<template>
  <div class="table-box">
    <ProTable ref="proTable" :columns="columns" row-key="id" :data="bizProcessList">
      <!-- 表格 header 按钮 -->
      <template #tableHeader="scope">
        <el-button type="primary" v-auth="['task:bizProcess:add']" icon="CirclePlus" @click="openDialog(1, '算法业务处理新增')"> 新增 </el-button>
        <el-button type="primary" v-auth="['task:bizProcess:import']" icon="Upload" plain @click="batchAdd"> 导入 </el-button>
        <el-button type="primary" v-auth="['task:bizProcess:export']" icon="Download" plain @click="downloadFile"> 导出 </el-button>
        <el-button
          type="danger"
          v-auth="['task:bizProcess:remove']"
          icon="Delete"
          plain
          :disabled="!scope.isSelected"
          @click="batchDelete(scope.selectedListIds)"
        >
          批量删除
        </el-button>
        <el-button type="primary" v-auth="['task:bizProcess:add']" icon="View" @click="contrastResults()"> 对比结果 </el-button>
      </template>
      <!-- 表格操作 -->
      <template #operation="scope">
        <el-button type="primary" link icon="View" v-auth="['task:bizProcess:query']" @click="openDialog(3, '算法业务处理查看', scope.row)">
          查看
        </el-button>
        <el-button type="primary" link icon="EditPen" v-auth="['task:bizProcess:edit']" @click="openDialog(2, '算法业务处理编辑', scope.row)">
          编辑
        </el-button>
        <el-button type="primary" link icon="Delete" v-auth="['task:bizProcess:remove']" @click="deleteBizProcess(scope.row)"> 删除 </el-button>
        <el-button type="primary" link icon="View" v-auth="['task:bizProcess:query']" @click="viewLog(scope.row)"> 查看日志 </el-button>
      </template>
    </ProTable>
    <FormDialog ref="formDialogRef" />
    <ImportExcel ref="dialogRef" />
    <el-dialog v-model="dialogVisible" title="日志" width="70%">
      <div class="log">
        <div class="p" v-for="(item, index) in logInfo" :key="index">{{ item }}</div>
      </div>
    </el-dialog>
    <el-dialog v-model="resultVisible" title="对比结果" width="70%">
      <div v-if="!resultsFlag" class="resultShow">
        <el-row class="headerRow">
          <el-col class="col" :span="4" v-for="(agloName, index) in resultsData['agNameList']" :key="index">
            <span>{{ agloName }}</span>
          </el-col>
        </el-row>
        <el-row class="row">
          <el-col class="col" :span="4" v-for="(RCurveUrl, index) in resultsData['rcureList']" :key="index">
            <div v-if="index !== 1" class="oneCol">{{ RCurveUrl }}</div>
            <ImagePreview
              class="img"
              v-else
              :width="100"
              :height="100"
              :src="'/api/profile' + RCurveUrl"
              :preview-src-list="['/api/profile' + RCurveUrl]"
            />
          </el-col>
        </el-row>
        <el-row class="row">
          <el-col class="col" :span="4" v-for="(PCurveUrl, index) in resultsData['pcureList']" :key="index">
            <div v-if="index !== 1" class="oneCol">{{ PCurveUrl }}</div>
            <ImagePreview
              class="img"
              v-else
              :width="100"
              :height="100"
              :src="'/api/profile' + PCurveUrl"
              :preview-src-list="['/api/profile' + PCurveUrl]"
            />
          </el-col>
        </el-row>
        <el-row class="row">
          <el-col class="col" :span="4" v-for="(F1CurveUrl, index) in resultsData['f1cureList']" :key="index">
            <div v-if="index !== 1" class="oneCol">{{ F1CurveUrl }}</div>
            <ImagePreview
              class="img"
              v-else
              :width="100"
              :height="100"
              :src="'/api/profile' + F1CurveUrl"
              :preview-src-list="['/api/profile' + F1CurveUrl]"
            />
          </el-col>
        </el-row>
      </div>
      <div v-if="resultsFlag" class="resultShow">
        <el-row class="row">
          <el-col class="col" :span="4" v-for="(agloName, index) in testResultsData['agNameList']" :key="index">
            <span>{{ agloName }}</span>
          </el-col>
        </el-row>
        <el-row v-for="(item, index) in testResultsData['resultList']" :key="index">
          <el-col class="col" :span="4" v-for="(url, index1) in item" :key="index1">
            <span>{{ url }}</span>
          </el-col>
        </el-row>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="tsx" name="BizProcess">
import { ref, reactive, onMounted, onUnmounted, nextTick, watch } from 'vue'
import { useHandleData } from '@/hooks/useHandleData'
import { useDownload } from '@/hooks/useDownload'
import { ElMessageBox, ElMessage } from 'element-plus'
import ProTable from '@/components/ProTable/index.vue'
import ImportExcel from '@/components/ImportExcel/index.vue'
import FormDialog from '@/components/FormDialog/index.vue'
import { ProTableInstance, ColumnProps } from '@/components/ProTable/interface'
import {
  listBizProcessApi,
  delBizProcessApi,
  addBizProcessApi,
  updateBizProcessApi,
  importTemplateApi,
  importBizProcessDataApi,
  exportBizProcessApi,
  getBizProcessApi,
  getTrainResultApi,
  getVerifyResultApi,
  getTestResultApi
} from '@/api/modules/task/bizProcess'
import { getSubtaskApi } from '@/api/modules/task/subtask'
import { getDictsApi } from '@/api/modules/system/dictData'
import { useRoute } from 'vue-router'
import ImagePreview from '@/components/ImagePreview/index.vue'
const route = useRoute()
const subTaskId = route.query.id as string
// ProTable 实例
const proTable = ref<ProTableInstance>()
const dialogVisible = ref(false)
const resultVisible = ref(false)
let resultsData = ref({})
let testResultsData = ref({})
let resultsFlag = ref(false)
let logList = ref()
let logInfo = ref([] as string[])
let taskType = ref()
let taskStatus = ref()

let bizProcessList = ref()
// 每隔10秒请求一下列表
const timer = ref() // 定时器
const refreshList = () => {
  setTimeout(() => {
    listBizProcessApi({
      pageNum: 1,
      pageSize: 100,
      subTaskId
    }).then(res => {
      bizProcessList.value = res.data['list']
    })
  }, 0)
}
onMounted(() => {
  getSubtaskApi(subTaskId).then(res => {
    taskType.value = res.data.type
    taskStatus.value = res.data.status
  })
  refreshList()
  timer.value = setInterval(() => {
    refreshList()
  }, 100000)
})
// 删除算法业务处理信息
const deleteBizProcess = async (params: any) => {
  await useHandleData(delBizProcessApi, params.id, '删除【' + params.id + '】算法业务处理')
  proTable.value?.getTableList()
}

// 批量删除算法业务处理信息
const batchDelete = async (ids: string[]) => {
  await useHandleData(delBizProcessApi, ids, '删除所选算法业务处理信息')
  proTable.value?.clearSelection()
  proTable.value?.getTableList()
}

// 导出算法业务处理列表
const downloadFile = async () => {
  ElMessageBox.confirm('确认导出算法业务处理数据?', '温馨提示', { type: 'warning' }).then(() =>
    useDownload(exportBizProcessApi, '算法业务处理列表', proTable.value?.searchParam)
  )
}

// 批量添加算法业务处理
const dialogRef = ref<InstanceType<typeof ImportExcel> | null>(null)
const batchAdd = () => {
  const params = {
    title: '算法业务处理',
    tempApi: importTemplateApi,
    importApi: importBizProcessDataApi,
    getTableList: proTable.value?.getTableList
  }
  dialogRef.value?.acceptParams(params)
}

// 对比结果
const contrastResults = () => {
  // if (taskStatus.value !== '3') {
  //   ElMessage.warning(`算法状态为${taskStatus.value}，暂无对比结果`)
  //   return
  // }
  switch (taskType.value) {
    case '1':
      getTrainResultApi(subTaskId).then(res => {
        resultsFlag.value = false
        handleResultData(res.data)
      })
      break
    case '2':
      getVerifyResultApi(subTaskId).then(res => {
        resultsFlag.value = false
        handleResultData(res.data)
      })
      break
    case '3':
      getTestResultApi(subTaskId).then(res => {
        console.log('333', res)
        resultsFlag.value = true
        testResultsData.value = res.data as any
      })
      break
    default:
      break
  }
  resultVisible.value = true
}
const handleResultData = data => {
  resultsData.value = data
  resultsData.value['agNameList'].unshift('')
  resultsData.value['rcureList'].unshift('R_curve')
  resultsData.value['pcureList'].unshift('P_curve')
  resultsData.value['f1cureList'].unshift('F1_curve')
}
// 查看日志
const viewLog = row => {
  // if (taskStatus.value !== '0') {
  //   ElMessage.warning('算法状态为待处理，暂无日志')
  //   return
  // }
  console.log(row.log)
  const url = '/api/profile/task/log.log'
  fetchLogFile(url)
    .then(text => {
      logList.value = text.split('\n')
      // console.log('logList.value', logList.value)
      // if (taskStatus.value === '1') {
      //   info(logList.value)
      //   dialogVisible.value = true
      // } else if (taskStatus.value === '2') {
      //   logInfo.value = logList.value
      //   dialogVisible.value = true
      // }
      info(logList.value)
      dialogVisible.value = true
    })
    .catch(error => {
      console.error('Failed to fetch the log file:', error)
      ElMessage.error('日志读取错误')
    })
}

const fetchLogFile = async url => {
  try {
    const response = await fetch(url, { method: 'GET' })
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }
    return await response.text()
  } catch (error) {
    throw error
  }
}
let timer2 = ref()
const info = logText => {
  let index = 0
  const logContainer = document.querySelector('.log')
  timer2.value = setInterval(() => {
    if (index < logText.length) {
      logInfo.value.push(logText[index])
      index++
      nextTick(() => {
        if (logContainer) {
          logContainer.scrollTop = logContainer.scrollHeight
        }
      })
    } else {
      clearInterval(timer2.value)
    }
  }, 300)
}
const formDialogRef = ref<InstanceType<typeof FormDialog> | null>(null)
// 打开弹框的功能
const openDialog = async (type: number, title: string, row?: any) => {
  let res = { data: {} }
  if (row?.id) {
    res = await getBizProcessApi(row?.id || null)
  }
  // 重置表单
  setItemsOptions()
  const params = {
    title,
    width: 580,
    isEdit: type !== 3,
    itemsOptions: itemsOptions,
    model: type == 1 ? {} : res.data,
    api: type == 1 ? addBizProcessApi : updateBizProcessApi,
    getTableList: proTable.value?.getTableList
  }
  formDialogRef.value?.openDialog(params)
}
onUnmounted(() => {
  clearInterval(timer.value)
  timer.value = null
})
watch(
  () => dialogVisible.value,
  val => {
    if (!val) {
      clearInterval(timer2.value)
      timer2.value = null
    }
  }
)
// 表格配置项
const columns = reactive<ColumnProps<any>[]>([
  { type: 'selection', fixed: 'left', width: 70 },
  { prop: 'id', label: '主键ID' },
  {
    prop: 'subTaskId',
    label: '子任务id',
    search: {
      el: 'input'
    },
    width: 120
  },
  {
    prop: 'name',
    label: '任务名称',
    search: {
      el: 'input'
    },
    width: 120
  },
  {
    prop: 'type',
    label: '任务类型',
    search: {
      el: 'input'
    },
    width: 120
  },
  {
    prop: 'status',
    label: '任务状态',
    tag: true,
    enum: () => getDictsApi('biz_task_status'),
    search: {
      el: 'tree-select'
    },
    width: 100,
    fieldNames: { label: 'dictLabel', value: 'dictValue' }
  },
  {
    prop: 'algorithmId',
    label: '算法',
    width: 120
  },
  {
    prop: 'modelId',
    label: '模型',
    width: 120
  },
  {
    prop: 'parameters',
    label: '调用算法时所用的参数',
    width: 120
  },
  {
    prop: 'preprocessPath',
    label: '预处理数据路径',
    width: 120
  },
  {
    prop: 'resultPath',
    label: '结果数据路径',
    width: 120
  },
  {
    prop: 'index',
    label: '序号',
    width: 120
  },
  {
    prop: 'startTime',
    label: '开始时间',
    width: 120
  },
  {
    prop: 'endTime',
    label: '结束时间',
    width: 120
  },
  {
    prop: 'costSecond',
    label: '耗时',
    width: 120
  },
  {
    prop: 'log',
    label: '日志',
    width: 120
  },
  { prop: 'operation', label: '操作', width: 230, fixed: 'right' }
])
// 结果表格配置项
// const resultColumns = reactive<ColumnProps<any>[]>([])
// 表单配置项
let itemsOptions: ProForm.ItemsOptions[] = []
const setItemsOptions = () => {
  itemsOptions = [
    {
      label: '子任务id',
      prop: 'subTaskId',
      compOptions: {
        placeholder: '请输入子任务id'
      }
    },
    {
      label: '任务名称',
      prop: 'name',
      compOptions: {
        placeholder: '请输入任务名称'
      }
    },
    {
      label: '任务类型',
      prop: 'type',
      compOptions: {
        placeholder: '请输入任务类型'
      }
    },
    {
      label: '任务状态',
      prop: 'status',
      compOptions: {
        elTagName: 'select',
        labelKey: 'dictLabel',
        valueKey: 'dictValue',
        enum: () => getDictsApi('biz_task_status'),
        placeholder: '请选择任务状态'
      }
    },
    {
      label: '算法',
      prop: 'algorithmId',
      compOptions: {
        placeholder: '请输入算法'
      }
    },
    {
      label: '模型',
      prop: 'modelId',
      compOptions: {
        placeholder: '请输入模型'
      }
    },
    {
      label: '调用算法时所用的参数',
      prop: 'parameters',
      compOptions: {
        type: 'textarea',
        clearable: true,
        placeholder: '请输入内容'
      }
    },
    {
      label: '预处理数据路径',
      prop: 'preprocessPath',
      compOptions: {
        placeholder: '请输入预处理数据路径'
      }
    },
    {
      label: '结果数据路径',
      prop: 'resultPath',
      compOptions: {
        placeholder: '请输入结果数据路径'
      }
    },
    {
      label: '序号',
      prop: 'index',
      compOptions: {
        placeholder: '请输入序号'
      }
    },
    {
      label: '开始时间',
      prop: 'startTime',
      compOptions: {
        elTagName: 'date-picker',
        type: 'date',
        placeholder: '请选择开始时间'
      }
    },
    {
      label: '结束时间',
      prop: 'endTime',
      compOptions: {
        elTagName: 'date-picker',
        type: 'date',
        placeholder: '请选择结束时间'
      }
    },
    {
      label: '耗时',
      prop: 'costSecond',
      compOptions: {
        placeholder: '请输入耗时'
      }
    },
    {
      label: '日志',
      prop: 'log',
      compOptions: {
        type: 'textarea',
        clearable: true,
        placeholder: '请输入内容'
      }
    }
  ]
}
</script>
<style scoped lang="scss">
.log {
  width: 90%;
  height: 60vh; /* 根据需要调整 */
  padding: 10px;

  // padding-bottom: 80px;
  margin-left: 50px;
  overflow-y: auto;
  font-family: 'Courier New', monospace;
  color: #4aff84;
  background-color: #1e1e1e;
}
.p {
  padding-left: 10px;
  margin-bottom: 5px;
  border-left: 3px solid #4aff84;
}
.resultShow {
  width: 100%;
  height: 60vh;
  overflow: hidden;
  overflow: scroll scroll;
  .headerRow {
    height: 50px;
    font-size: 1.5rem;
    line-height: 50px;
    text-align: center;
  }
  .row {
    .col {
      text-align: center;
      .oneCol {
        margin-top: 45px;
        font-size: 1.2rem;
      }
      .img {
        margin: 10px 0;
      }
    }
  }
}
</style>
