<template>
  <div>
    <!-- <filter-list class="mb-3" :option="option" :show-btn="false"></filter-list> -->
    <m-card :title="title || $t('upload.calculation')" class="pb-4" :minHeight="600">
      <div class="pt-3">
        <v-btn
          outlined
          color="indigo"
          @click="processHistory"
        >{{ $t('upload.processingHistory') }}</v-btn>
      </div>
      <v-container style="width: 840px; min-height: 600px">
        <v-row>
          <v-col v-if="formItems.options.length">
            <form-list ref="form" class="mt-5" :items="formTime"></form-list>
            <form-list ref="form" :items="formItems"></form-list>
            <div class="text-center">
              <v-btn
                color="primary"
                class="elevation-5 ml-3 buttons"
                rounded @click="handleUpload"
              >
                <v-icon left>mdi-cloud-upload</v-icon>{{ $t('upload.uploadBtn') }}
              </v-btn>
              <v-btn
                color="primary"
                class="elevation-5 ml-3 buttons"
                rounded
                @click="processTask"
              >
                <v-icon left>mdi-tools</v-icon>{{ $t('upload.processing') }}
              </v-btn>
            </div>
          </v-col>
          <v-col cols="6" offset="3" v-else>
            <empty-page></empty-page>
          </v-col>
        </v-row>
      </v-container>
      <v-navigation-drawer
        v-model="log.show"
        width="70%"
        right
        absolute
        hide-overlay
        temporary
      >
        <m-card title="加工历史记录" class="elevation-0">
          <table-list
            :elevation="0"
            :loading="false"
            :disable-sort="true"
            :is-tools="false"
            :show-page="true"
            :show-select="false"
            :page-info="log.page"
            :total="log.total"
            :items="log.items"
            :headers="log.headers"
            @pageHandleChange="drillPageHandleChange"
          >
            <template v-slot:runState="{ item }">
              <span text class="ma-2" :style="{ 'color': colorList.find(e => e.title === item.runState)?.color ?? '' }">{{ item.runState }}</span>
            </template>
            <template v-slot:actions="{ item }">
              <v-btn text color="primary" @click="handleDetail(item)">查看明细</v-btn>
            </template>
          </table-list>
        </m-card>

        <Dialog :visible.sync="drill.show" :footer="false" :title="drill.title" @close="close" widthType="1">
          <table-list
            :headers="drill.headers"
            :items="drill.items"
            :is-tools="false"
            :disable-sort="true"
            :show-page="false"
            :show-select="false"
            :elevation="0"
            :loading="false"
          >
          <template v-slot:runState="{ item }">
            <span text class="ma-2" :style="{ 'color': colorList.find(e => e.title === item.runState)?.color ?? '' }">{{ item.runState }}</span>
          </template>
          <template #actions="{ item }">
            <v-btn text color="primary" @click="handleLog(item)">查看日志</v-btn>
          </template>
          </table-list>
          <Dialog
            :visible.sync="detailsShow"
            :footer="false"
            :title="detailsInfo.name + '['+detailsInfo.runTime+']'"
            widthType="1"
          >
            <div v-for="v in detailsInfo.msg" :key="v.content" class="d-flex mb-3">
              <div style="width: 60px">
                <!-- <v-btn icon> -->
                  <v-icon :color="v.level.toLowerCase()">mdi-checkbox-blank-circle</v-icon>
                <!-- </v-btn> -->
              </div>
              <div :style="`width: 200px;${v.level === 'ERROR' ? 'color: red' : ''}`">{{ v.recordTime }}</div>
              <div :style="`flex: 1;${v.level === 'ERROR' ? 'color: red' : ''}`">{{ v.content }}</div>
            </div>
          </Dialog>
        </Dialog>
      </v-navigation-drawer>
    </m-card>
    <m-linear :visible="visible" :text="$t('upload.waitProcessing')"></m-linear>
  </div>
</template>

<script>
import Dialog from '@/components/Dialog'
import TableList from '@/components/List/table.vue'
import EmptyPage from '@/components/Common/empty.vue'
import MLinear from '@/components/Progress/linear.vue'
import MCard from '@/components/MCard'
import FormList from '@/components/Form/list'
import { getNow } from '@/utils/date'
import {
  fileUpload,
  taskGroupList,
  queryTaskProductIdMapByIdList,
  getCombinationPage,
  taskGroupRun,
  platformTaskGroupLogList,
  dataFactoryDictList,
  getFileDetail,
  getLogPage,
  checkFile,
  checkSettingFile,
  checkDistribution
} from '@/api/dataFactory'

export default {
  name: 'task-process',
  components: { MCard, FormList, MLinear, EmptyPage, TableList, Dialog },
  props: {
    // performanceSettingType 绩效类型 绩效类型, 0.对公绩效、1.对私绩效、2.全产品计价、3.拓面提质
    type: {
      type: Number,
      default: 0
    },
    title: {
      type: String,
      default: ''
    },
    mark: {
      type: String,
      default: ''
    },
    // 额外的上传列表 补充
    additional: {
      type: Array,
      default: () => []
    }
  },
  data () {
    return {
      detailsShow: false,
      detailsInfo: {},
      formTime: {
        options: [
          {
            type: 'date',
            key: 'month',
            value: getNow().slice(0, 2).join('-'),
            label: '选择月份',
            style: 'width: 300px',
            option: { type: 'month', placeholder: '请选择', clearable: true },
            change: this.getFileDetail
          }
        ]
      },
      visible: false,
      formItems: {
        options: []
      },
      // 明细
      drill: {
        show: false,
        title: '',
        headers: [
          { text: '任务名称', value: 'taskName' },
          { text: '任务类型', value: 'type' },
          { text: '开始时间', value: 'startTime' },
          { text: '结束时间', value: 'endTime' },
          { text: '执行耗时', value: 'duration' },
          { text: '执行结果', value: 'runState' },
          { text: '操作', value: 'actions', align: 'center' }
        ],
        items: []
      },
      // 历史记录
      log: {
        show: false,
        total: 0,
        page: {
          size: 10,
          current: 1
        },
        items: [],
        headers: [
          { text: '任务组名称', value: 'taskGroupName' },
          { text: '执行时间', value: 'runTime' },
          { text: '执行结果', value: 'runState' },
          { text: '操作', value: 'actions', align: 'center' }
        ]
      },
      statusList: [], // 任务状态
      typeList: [], // 任务类型
      colorList: [
        { title: '成功', color: 'green' },
        { title: '失败', color: 'red' },
        { title: '退出执行', color: '#fb8c00' }
      ],
      isDistribution: false
    }
  },
  async created () {
    this.formItems.options.push(...this.additional.map(e => this.finishParams(e)))
    await this.getTaskGroup()
    this.checkSettingFile()
    this.getFileDetail()
  },
  methods: {
    async handleLog (item) {
      const { startTime, endTime, taskId } = item
      try {
        const { data } = await getLogPage({ taskId, runTimes: [startTime, endTime] })
        if (!data.records.length) {
          return
        }
        this.detailsInfo = data.records.pop()
        this.detailsShow = true
      } catch (error) {
        this.$snackbar.error(error)
      }
    },
    finishParams (param) {
      return {
        ...param,
        type: 'upload',
        showSize: true,
        outlined: true,
        dense: true,
        value: null,
        error: false,
        success: false,
        loading: false,
        rules: [v => true],
        accept: '.xlsx, .xls'
      }
    },
    // 查看必传文件
    async checkSettingFile () {
      try {
        const { data } = await checkSettingFile({ performanceSettingType: this.type })
        if (!data) return
        this.formItems.options.forEach(ele => {
          const item = data.find(e => e.name === ele.en)
          if (item && item.checkType === 1) {
            ele.label += ' *'
            ele.placeholder += ' *'
          }
        })
        // console.log(data)
      } catch (error) {
        this.$snackbar.error(error)
      }
    },
    // 获取文件清单
    async getFileDetail () {
      const month = this.formTime.options.find(e => e.key === 'month').value
      try {
        const { data } = await getFileDetail({ month, performanceSettingType: this.type })
        this.formItems.options.forEach(item => {
          if (!data) {
            item.success = false
            return
          }
          const oData = data.filter(e => e.metaDataCombinationEngName === item.en)
          // if (!oData.length) return
          // item.color = 'success'
          // item.appendIcon = 'mdi-check'
          item.success = !!oData.length
        })
      } catch (error) {
        this.$snackbar.error(error)
      }
    },
    // 获取任务列表
    async getTaskGroup () {
      try {
        const { data } = await taskGroupList({ mark: this.mark })
        if (!data || !data.length || !data[0].detailRespVOList) return
        const idList = data[0].detailRespVOList.filter(e => e.uploadEnable).map(e => e.taskId)
        if (!idList.length) return
        await this.getProductIds(idList.toString())
      } catch (error) {
        this.$snackbar.error(error)
      }
    },
    // 根据任务列表id获取数据域id
    async getProductIds (ids) {
      try {
        const { data } = await queryTaskProductIdMapByIdList({ ids })
        if (!data) return
        const arr = Object.values(data).filter(e => e)
        if (!arr.length) return
        await this.getProducts(arr)
      } catch (error) {
        this.$snackbar.error(error)
      }
    },
    // 根据数据域id获取数据域信息
    async getProducts (item) {
      const metaDataCombinationIds = item.map(e => e.productId)
      try {
        const { data } = await getCombinationPage({ metaDataCombinationIds, size: 999 })
        const oData = data.records.map(e => {
          const obj = {
            label: e.name,
            placeholder: `点击上传${e.name}`,
            // rules: [v => v !== null || `请点击上传${e.name}`],
            en: e.engName,
            taskType: item.find(k => k.productId === e.metaDataCombinationId)?.type ?? '1',
            multiple: e.engName === 'information_management_loan_formal' // 多文件上传
          }
          return this.finishParams(obj)
        })
        this.formItems.options.push(...oData)
        this.formItems.options.map(e => {
          e.change = this.handleChange
          return e
        })
      } catch (error) {
        this.$snackbar.error(error)
      }
    },
    handleChange (value, item) {
      const check = Array.isArray(value) ? value.length : value
      if (check) {
        item.success = true
        item.error = false
        return
      }
      item.success = false
      item.error = true
    },
    // 上传
    handleUpload () {
      if (!this.$refs.form.validate()) return
      this.$confirm('系统提示', '是否确定上传').then(res => {
        const fileList = this.formItems.options.map(e => {
          return {
            file: e.value,
            metaDataCombinationEngName: e.en,
            taskType: e.taskType,
            performanceSettingType: this.type,
            month: this.formTime.options.find(e => e.key === 'month').value
          }
        }).filter(e => e.file)
        if (!fileList.length) {
          this.$snackbar.error('请选择要上传的文件')
          return
        }
        this.uploadList(fileList)
      })
    },
    uploadList (fileList, index = 0) {
      if (index >= fileList.length) {
        this.$snackbar.success('全部上传成功')
        return
      }
      const fileItem = fileList[index]
      const itemData = this.formItems.options.find(e => e.en === fileItem.metaDataCombinationEngName)
      itemData.loading = true
      this.upload(fileItem).then(res => {
        // itemData.appendIcon = 'mdi-check'
        itemData.success = true
        itemData.error = false
        index++
        this.uploadList(fileList, index)
      }).catch((error) => {
        this.$snackbar.error(error)
        itemData.success = false
        itemData.error = true
      }).finally(() => {
        itemData.loading = false
      })
    },
    // 文件上传
    upload (item) {
      return new Promise((resolve, reject) => {
        const oData = new FormData()
        Object.keys(item).forEach(key => {
          if (key === 'file' && Array.isArray(item[key])) {
            item[key].forEach(e => {
              oData.append('file', e)
            })
            return
          }
          oData.append(key, item[key])
        })
        fileUpload(oData).then(res => resolve(res)).catch(error => reject(error))
      })
    },
    // 后端检验
    async checkFile () {
      return new Promise((resolve, reject) => {
        checkFile({
          performanceSettingType: this.type,
          month: this.formTime.options.find(e => e.key === 'month').value
        }).then(({ data }) => {
          if (!data) return resolve()
          this.formItems.options.forEach(ele => {
            const item = data.find(e => e.name === ele.en)
            if (!item) return
            ele.error = !!item.checkType
          })
          resolve()
        }).catch(error => {
          reject(error)
        })
      })
    },
    // 全产品计价-检查是否可加工
    async checkDistribution (month) {
      try {
        const { data } = await checkDistribution({ month })
        this.isDistribution = data
      } catch (error) {
        this.$snackbar.error(error)
      }
    },
    // 加工
    async processTask () {
      const month = this.formTime.options.find(e => e.key === 'month')?.value
      if (this.type === 2) {
        await this.checkDistribution(month)
        if (!this.isDistribution) return this.$snackbar.warning('存在未发放的绩效，请先发放后再操作！')
      }
      // 设置全产品计价二次确认文字
      const text = this.type === 2 ? `此操作会重新计算${month}月的全产品绩效数据，操作约需要30分钟内完成` : '是否确定加工'
      this.$confirm('系统提示', text).then(async res => {
        this.visible = true
        try {
          // 校验文件是否齐全
          await this.checkFile()
          await taskGroupRun({ mark: this.mark })
          this.$snackbar.success('加工已启动')
        } catch (error) {
          this.$snackbar.error(error)
        } finally {
          this.visible = false
        }
      })
    },
    // 历史记录记录
    async processHistory () {
      this.log.show = true
      try {
        const statusRes = await dataFactoryDictList({ type: 'task_log_run_status' }) // 字典接口：任务状态
        this.statusList = statusRes.data[0].itemList
        const typeRes = await dataFactoryDictList({ type: 'task_type' }) // 任务类型
        this.typeList = typeRes.data[0].itemList

        const { data } = await platformTaskGroupLogList({ taskGroupMark: this.mark, size: this.log.page.size, current: this.log.page.current }) // 调试mark：23423
        this.log.total = data.total
        this.log.items = data.records.map(item => {
          item.runState = this.statusList.find(e => e.value === item.runResult)?.label
          return item
        })
      } catch (error) {
        this.$snackbar.error(error)
      }
    },
    drillPageHandleChange (val) {
      this.log.page.current = val
      this.processHistory()
    },
    // 列表展开项
    // handleExpanded (item) {
    //   this.drill.items = []
    //   if (!item.item.msg.length) return
    //   this.drill.items = item.item.msg.map(item => {
    //     item.runState = this.statusList.find(e => e.value === item.runResult)?.label
    //     return item
    //   })
    // },
    // 明细
    async handleDetail (item) {
      this.drill.title = `[${item.taskGroupName}]`
      if (!item.msg.length) return this.$snackbar.warning('无明细数据')
      this.drill.show = true
      this.drill.items = item.msg.map(item => {
        item.runState = this.statusList.find(e => e.value === item.runResult)?.label // 任务结果
        item.type = this.typeList.find(e => e.value === item.taskType)?.label // 任务类型
        return item
      })
    },
    close () {
      this.drill.show = false
    }
  }
}
</script>

<style lang="scss" scoped>

</style>
