<template>
  <div class="table-box">
    <ProTable ref="proTable" :columns="columns" row-key="id" :request-api="listDataAugmentationApi">
      <!-- 表格 header 按钮 -->
      <template #tableHeader="scope">
        <el-button type="primary" v-auth="['demo:DataAugmentation:add']" icon="CirclePlus" @click="openDialog(1, '任务新增')"> 新增 </el-button>
        <!-- <el-button type="primary" v-auth="['demo:DataAugmentation:import']" icon="Upload" plain @click="batchAdd"> 导入</el-button> -->
        <!-- <el-button type="primary" v-auth="['demo:DataAugmentation:export']" icon="Download" plain @click="downloadFile"> 导出 </el-button> -->
        <el-button
          type="danger"
          v-auth="['demo:DataAugmentation:remove']"
          icon="Delete"
          plain
          :disabled="!scope.isSelected"
          @click="batchDelete(scope.selectedListIds)"
        >
          批量删除
        </el-button>
      </template>
      <!-- 表格操作 -->
      <template #operation="scope">
        <el-button
          type="primary"
          link
          icon="View"
          @click="startDataAugmentation(scope.row)"
          v-if="scope.row.status == '0' || scope.row.status == '3' || scope.row.status == '4'"
        >
          开始
        </el-button>
        <el-popconfirm title="确定终止此任务吗?" @confirm="stopDataAugmentation(scope.row)" v-if="scope.row.status == '1'">
          <template #reference>
            <el-button type="primary" link icon="View"> 终止 </el-button>
          </template>
        </el-popconfirm>
        <el-button type="primary" link icon="View" @click="compareDataAugmentation(scope.row)" v-if="scope.row.status == '2'"> 预览 </el-button>
        <el-button type="primary" link icon="View" @click="downloadFile(scope.row)" v-if="scope.row.status == '2'"> 导出 </el-button>
        <el-button type="primary" link icon="View" v-auth="['demo:DataAugmentation:query']" @click="openDialog(3, '任务查看', scope.row)">
          查看
        </el-button>
        <el-button
          type="primary"
          link
          icon="View"
          v-auth="['demo:DataAugmentation:query']"
          @click="openLogDialog(scope.row.id)"
          v-if="scope.row.status != '0'"
        >
          日志
        </el-button>
        <el-button type="primary" link icon="Delete" v-auth="['demo:DataAugmentation:remove']" @click="deleteDataAugmentation(scope.row)">
          删除
        </el-button>
      </template>
    </ProTable>
    <DataAugmentationFormDialog ref="formDialogRef" />
    <ImportExcel ref="dialogRef" />
    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="80%">
      <div class="image-dialog" v-if="imageIdx >= 0 && cacheImages[imageIdx]">
        <div style="width: 50%">
          <el-image v-for="(image, index) in cacheImages[imageIdx].origin" :key="index" :src="'data:image/png;base64,' + image"></el-image>
          <!-- <el-tag>结果：</el-tag> -->
        </div>
        <div v-if="task_type_view == '目标毁伤评估'" style="width: 50%">
          <ul v-infinite-scroll="load" class="list" :infinite-scroll-disabled="disabled">
            <li v-for="i in count" :key="i" style="list-style-type: none">
              <el-image :src="'data:image/png;base64,' + cacheImages[imageIdx].stable[i - 1]"></el-image>
            </li>
          </ul>
          <p v-if="loading">Loading...</p>
          <p v-if="noMore">No more</p>
        </div>
        <div v-else style="width: 50%">
          <el-image v-for="(image, index) in cacheImages[imageIdx].stable" :key="index" :src="'data:image/png;base64,' + image"></el-image>
        </div>
      </div>
      <div class="image-dialog-btn" v-if="imageFps == 0">
        <el-button type="primary" @click="pre_picture" :disabled="imageIdx <= 0">上一个</el-button>
        <el-button type="primary" @click="next_picture" :disabled="imageIdx >= fileCount - 1">下一个</el-button>
      </div>
    </el-dialog>
    <el-dialog v-model="logDialogVisible" title="日志" width="80%">
      <el-text class="mx-1">{{ logDialog }}</el-text>
    </el-dialog>
  </div>
</template>

<script setup lang="tsx" name="DataAugmentation">
import { ref, reactive, onMounted, computed } 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 DataAugmentationFormDialog from '@/components/DataAugmentationFormDialog/index.vue'
import { ProTableInstance, ColumnProps, EnumProps } from '@/components/ProTable/interface'
import {
  listDataAugmentationApi,
  delDataAugmentationApi,
  addDataAugmentationApi,
  updateDataAugmentationApi,
  importTemplateApi,
  importDataAugmentationDataApi,
  exportDataAugmentationApi,
  getDataAugmentationApi,
  startDataAugmentationApi,
  stopDataAugmentationApi,
  getCompareImageApi,
  getCompareImageCountApi,
  getDialogApi
} from '@/api/modules/demo/dataAugmentation'
import { listDataApi } from '@/api/modules/system/dictData'
import { S } from 'vite/dist/node/types.d-aGj9QkWt'
import { servicesVersion } from 'typescript'
const dialogVisible = ref(false)
const taskId = ref('')
const imageIdx = ref(0)
const imageBase64List = ref({
  origin: '',
  stable: ''
})
const inFileCount = ref(0)
const outFileCount = ref(0)
// 直接缓存所有图片
const cacheImages = ref({})
const dialogTitle = ref('')
const fileCount = ref(0)
const imageFps = ref(0)
const intervalChangeFps: any = ref()
const taskType = ref([])
const taskTypeEnums: EnumProps[] = []

const hyperparameterConfiguration = []

const logDialogVisible = ref(false)
const logDialog = ref('')
const count = ref(4)
const loading = ref(false)
const noMore = computed(() => count.value >= cacheImages.value[imageIdx.value].stable.length)
const disabled = computed(() => loading.value || noMore.value)
const load = () => {
  loading.value = true
  setTimeout(() => {
    count.value += 1
    loading.value = false
  }, 2000)
}
const openLogDialog = async (id: string | number) => {
  const res: any = await getDialogApi(id)
  logDialog.value = res.data
  logDialogVisible.value = true
}
const getTaskType = async () => {
  const res: any = await listDataApi({
    dictName: '',
    dictType: 'biz_data_augmentation',
    dictLabel: '任务类型',
    pageNum: 0,
    pageSize: 1000
  })
  if (res.data.list.length != 0) {
    taskType.value = res.data.list.map(item => ({
      label: item.dictValue,
      value: item.dictValue
    }))
    res.data.list.forEach(item => {
      taskTypeEnums.push({
        label: item.dictValue,
        value: item.dictValue,
        disabled: false,
        tagType: 'default'
      })
    })
    console.log(taskTypeEnums)
    for (let i = 0; i < taskType.value.length; i++) {
      let dictValue = taskType.value[i].value
      const res: any = await listDataApi({
        dictName: '',
        dictType: 'biz_data_augmentation',
        dictLabel: dictValue + '超参配置',
        pageNum: 0,
        pageSize: 1000
      })
      if (res.data.list.length != 0) {
        //console.log(res.data.list[0].dictValue)
        let obj = {}
        obj[dictValue] = res.data.list[0].dictValue
        hyperparameterConfiguration.push(obj)
      } else {
        ElMessage.error('${dictValue}未在数据字典中设置超参！')
      }
    }
  } else {
    ElMessage.error('task_type为空，请在数据字典中设置具体的任务类型！')
  }

  // console.log(taskType.value)
}
onMounted(() => {
  getTaskType()
})

const startDataAugmentation = async (params: any) => {
  const res = await startDataAugmentationApi(params.id)
  if (res.code === 200) {
    ElMessage.success('任务已经开始，请等待')
  } else {
    ElMessage.error('任务开始失败，请检查！')
  }
  proTable.value?.getTableList()
}

const stopDataAugmentation = async (params: any) => {
  const res = await stopDataAugmentationApi(params.id)
  if (res.code === 200) {
    ElMessage.success('任务终止成功')
  } else {
    ElMessage.error('任务终止失败！')
  }
  proTable.value?.getTableList()
}

const loadImageData = async (taskId: string, imageIdx: number) => {
  const res: any = await getCompareImageApi(taskId, imageIdx)
  // imageBase64List.value.origin = res.origin
  // imageBase64List.value.stable = res.stable
  cacheImages.value[imageIdx].origin = res.origin
  cacheImages.value[imageIdx].stable = res.stable
}
const task_type_view = ref('')
const compareDataAugmentation = async (params: any) => {
  if (taskId.value !== '' && taskId.value !== null && taskId.value !== undefined && taskId.value == params.id) {
    dialogVisible.value = true
    return
  }
  task_type_view.value = params.taskType
  taskId.value = params.id
  imageIdx.value = 0
  cacheImages.value = {}
  const resCount: any = await getCompareImageCountApi(params.id)
  if (resCount.code === 200) {
    inFileCount.value = resCount.data.inFileCount
    outFileCount.value = resCount.data.outFileCount
  } else {
    ElMessage.error('获取图片对比数量失败')
    return
  }
  dialogVisible.value = true

  dialogTitle.value = '缓存图片中'
  fileCount.value = Math.min(inFileCount.value, outFileCount.value)
  for (let idx = 1; idx <= fileCount.value; idx++) {
    dialogTitle.value = '缓存图片中： 第' + idx + '个样本 共' + fileCount.value + '个样本'
    if (cacheImages.value[idx - 1]) {
      continue
    }
    const res: any = await getCompareImageApi(taskId.value, idx - 1)
    // console.log(res)

    cacheImages.value[idx - 1] = {
      origin: res.origin,
      stable: res.stable
    }
  }
  // console.log(cacheImages.value[0])
  dialogTitle.value = '预览: 第1个样本 共' + fileCount.value + '个样本'
  // next_picture()
}
const next_picture = async () => {
  if (imageIdx.value < fileCount.value - 1) {
    if (!cacheImages.value[imageIdx.value + 1]) {
      await loadImageData(taskId.value, imageIdx.value + 1)
    }
    imageIdx.value = imageIdx.value + 1
  }
  dialogTitle.value = '预览: 第' + (imageIdx.value + 1) + '个样本 共' + fileCount.value + '个样本'
}
const pre_picture = async () => {
  if (imageIdx.value > 0) {
    if (!cacheImages.value[imageIdx.value - 1]) {
      await loadImageData(taskId.value, imageIdx.value - 1)
    }
    imageIdx.value = imageIdx.value - 1
  }
  dialogTitle.value = '预览: 第' + (imageIdx.value + 1) + '个样本 共' + fileCount.value + '个样本'
}

// ProTable 实例
const proTable = ref<ProTableInstance>()

// 删除视频去抖动信息
const deleteDataAugmentation = async (params: any) => {
  await useHandleData(delDataAugmentationApi, params.id, '删除任务【' + params.name + '】？')
  proTable.value?.getTableList()
}

// 批量删除视频去抖动信息
const batchDelete = async (ids: string[]) => {
  await useHandleData(delDataAugmentationApi, ids, '删除所选任务？')
  proTable.value?.clearSelection()
  proTable.value?.getTableList()
}

// 导出视频去抖动列表
const downloadFile = async task => {
  ElMessageBox.confirm('确认导出任务数据?', '温馨提示', { type: 'warning' }).then(() =>
    useDownload(exportDataAugmentationApi, 'export', task.outputPath)
  )
}

// 批量添加视频去抖动
const dialogRef = ref<InstanceType<typeof ImportExcel> | null>(null)
const batchAdd = () => {
  const params = {
    title: '视频去抖动',
    tempApi: importTemplateApi,
    importApi: importDataAugmentationDataApi,
    getTableList: proTable.value?.getTableList
  }
  dialogRef.value?.acceptParams(params)
}

const formDialogRef = ref<InstanceType<typeof DataAugmentationFormDialog> | null>(null)
// 打开弹框的功能
const openDialog = async (type: number, title: string, row?: any) => {
  // hyperparameter.value = ''
  let res = { data: {} }
  if (row?.id) {
    res = await getDataAugmentationApi(row?.id || null)
    // hyperparameter.value = res.data?.hyperparameterConfiguration
  }
  // console.log(itemsOptions[1].compOptions?.value)
  // 重置表单
  // setItemsOptions()
  const params = {
    title,
    width: 580,
    isEdit: type !== 3,
    itemsOptions: itemsOptions,
    model: type == 1 ? model : res.data,
    api: type == 1 ? addDataAugmentationApi : updateDataAugmentationApi,
    getTableList: proTable.value?.getTableList
  }
  formDialogRef.value?.openDialog(params)
}

const statusEnums: EnumProps[] = [
  {
    label: '未开始',
    value: '0',
    disabled: false,
    tagType: 'default'
  },
  {
    label: '进行中',
    value: '1',
    disabled: false,
    tagType: 'primary'
  },
  {
    label: '完成',
    value: '2',
    disabled: false,
    tagType: 'success'
  },
  {
    label: '失败',
    value: '3',
    disabled: false,
    tagType: 'danger'
  },
  {
    label: '已中断',
    value: '4',
    disabled: false,
    tagType: 'default'
  }
]

// 表格配置项
const columns = reactive<ColumnProps<any>[]>([
  { type: 'selection', fixed: 'left', width: 70 },
  { prop: 'id', label: '主键ID', width: 180 },
  {
    prop: 'name',
    label: '任务名称',
    search: {
      el: 'input'
    },
    width: 150
  },
  {
    prop: 'taskType',
    label: '任务类型',
    search: {
      el: 'select'
    },
    width: 100,
    tag: true,
    enum: taskTypeEnums
  },
  {
    prop: 'status',
    label: '任务状态',
    search: {
      el: 'select'
    },
    width: 100,
    tag: true,
    enum: statusEnums
  },
  {
    prop: 'startTime',
    label: '开始时间',
    width: 180
  },
  {
    prop: 'endTime',
    label: '结束时间',
    width: 180
  },
  {
    prop: 'costSecond',
    label: '耗时',
    search: {
      el: 'input'
    },
    width: 80
  },
  {
    prop: 'log',
    label: '日志',
    width: 120
  },

  {
    prop: 'algorithmPath',
    label: '日志路径',
    width: 120
  },
  {
    prop: 'hyperparameterConfiguration',
    label: '超参配置',
    width: 120
  },
  {
    prop: 'remarks',
    label: '备注',
    search: {
      el: 'input'
    },
    width: 120
  },
  {
    prop: 'operation',
    label: '操作',
    width: 230,
    fixed: 'right'
  }
])
// 表单配置项
let itemsOptions: ProForm.ItemsOptions[] = [
  {
    label: '任务名称',
    prop: 'name',
    rules: [{ required: true, message: '任务名称不能为空', trigger: 'blur' }],
    compOptions: {
      placeholder: '请输入任务名称'
    }
  },
  {
    label: '任务类型',
    prop: 'taskType',
    rules: [{ required: true, message: '任务类型不能为空', trigger: 'change' }],
    compOptions: {
      elTagName: 'select', // 指定使用 el-select 组件
      placeholder: '请选择任务类型',
      enum: taskType,
      onChange: (value: string) => {
        model.value['taskType'] = value
        hyperparameterConfiguration.forEach(obj => {
          if (value in obj) {
            // console.log(obj[value])
            addParams(obj[value])
            openDialog(1, '任务新增')
          }
        })
      }
    }
  },
  {
    label: '图片集压缩包',
    prop: 'inputOssId',
    rules: [{ required: true, message: '数据压缩包不能为空', trigger: 'change' }],
    compOptions: {
      elTagName: 'file-upload',
      fileSize: 4096,
      fileType: ['zip'],
      placeholder: '请上传图片集压缩包'
    }
  },
  {
    label: '备注',
    prop: 'remarks',
    rules: [
      {
        required: false,
        trigger: 'blur'
      }
    ],
    compOptions: {
      placeholder: '请输入备注'
    }
  }
]
const model = ref({})
const setItemsOptions = () => {
  if (itemsOptions.length > 4) {
    itemsOptions.splice(4) // 如果里面有新增参数，删除，重新添加
  }
}
const hyperparameter = ref({})
const addParams = params => {
  setItemsOptions()
  if (params == 'null') {
    return
  }
  let validJsonString = params.replace(/'/g, '"')
  try {
    const obj: { [key: string]: number } = JSON.parse(validJsonString)
    // hyperparameter.value = { ...obj };
    Object.keys(obj).forEach(key => {
      model.value[key] = obj[key]
      // hyperparameter[key] = obj[key]
      itemsOptions.push({
        label: key,
        prop: key,
        rules: [{ trigger: 'blur' }],
        compOptions: {
          type: 'input',
          clearable: true,
          placeholder: '默认值为' + obj[key]
          // value: hyperparameter.value[key],
          // onChange: (value) => {
          //   hyperparameter.value[key] = value
          //   console.log(hyperparameter)
          //   // model.value[key] = value
          // }
        }
      })
    })
  } catch (error) {
    console.error('解析 JSON 字符串时出错:', error)
  }
}
</script>

<style lang="scss" scoped>
.image-dialog {
  display: flex;
  align-items: center;
  justify-content: center;
  .el-image {
    margin-right: 20px;
    margin-bottom: 20px;
  }
}
.image-dialog-btn {
  display: flex;
  justify-content: center;
  margin-top: 20px;
}
</style>
