<template>
  <div class="createTask-bigBox">
    <dv-border-box1 ref="borderRef" style="width: 80%; height: calc(100% - 20px); margin: 0 auto">
      <el-container style="height: 30px"></el-container>
      <el-container>
        <span class="span_class">任务名称</span>
        <el-input style="width: 300px" type="text" placeholder="请输入任务名称" v-model="formData.taskName"> </el-input>
      </el-container>

      <el-container style="height: 10px"></el-container>
      <el-container>
        <span class="span_class">任务类型</span>
        <el-radio v-model="formData.taskType" label="1">单数据多算法任务</el-radio>
        <el-radio v-model="formData.taskType" label="2">多数据单算法任务</el-radio>
      </el-container>

      <el-container style="height: 10px"></el-container>
      <el-container>
        <span class="span_class">算法任务</span>
        <el-checkbox-group v-model="formData.tasks">
          <el-checkbox label="1">训练</el-checkbox>
          <el-checkbox label="2">测试</el-checkbox>
        </el-checkbox-group>
      </el-container>

      <el-container style="height: 10px"></el-container>
      <el-container>
        <span class="span_class">选择算法</span>
        <el-container style="display: flex; flex-direction: column">
          <el-container v-for="(item, index) in formData.algorithms" :key="index" style="margin-top: 5px">
            <el-select style="width: 200px" v-model="formData.algoIdx[index]" placeholder="请选择" @change="onAlgorithmModelSelect(index)">
              <el-option v-for="(item1, index) in algorithms" :key="item1.id" :label="item1.name" :value="index"> </el-option>
            </el-select>
            <el-button style="margin-left: 20px" @click="showSuperParameterConfig(item, index)"> 超参配置 </el-button>
            <span class="span_class1">选择模型</span>
            <el-select style="width: 200px" v-model="formData.algoModelId[index]" placeholder="未选择将使用默认模型">
              <el-option v-for="item1 in formData.algoModelList[index]" :key="item1.id" :label="item1.modelName" :value="item1.id"> </el-option>
            </el-select>
            <el-button @click="showAddModelDialog(item, index)"> 导入模型 </el-button>
            <el-button v-show="formData.algorithms.length > 1" @click="removeItem(index)"> 删除算法 </el-button>
            <el-button v-show="formData.taskType === '1' && index + 1 === formData.algorithms.length" @click="appendNewItem"> 添加算法 </el-button>
          </el-container>
        </el-container>
      </el-container>

      <el-container style="height: 10px"></el-container>
      <el-container>
        <span class="span_class">选择训练数据</span>
        <el-container style="display: flex; flex-direction: column">
          <el-container v-for="(item, index) in formData.data" :key="index" style="margin-top: 5px">
            <el-button v-show="formData.data" @click="showDataSelectionDialog(index, true)"> 选择批次 </el-button>
            <span v-if="!item || item.length === 0" class="span_class" style="font-size: 15px; color: red">未完成</span>
            <span v-else class="span_class" style="font-size: 15px; color: greenyellow">已选择</span>
            <el-button v-show="formData.data.length > 1" style="margin-left: 20px" @click="removeDataItem(index, true)"> 删除数据 </el-button>
            <el-button
              v-show="formData.taskType === '2' && index + 1 === formData.data.length"
              style="margin-left: 20px"
              @click="appendNewDataItem(true)"
            >
              添加数据
            </el-button>
          </el-container>
        </el-container>
      </el-container>

      <el-container style="height: 10px"></el-container>
      <el-container>
        <span class="span_class">选择测试数据</span>
        <el-container style="display: flex; flex-direction: column">
          <el-container v-for="(item, index) in formData.testData" :key="index" style="margin-top: 5px">
            <el-button v-show="formData.testData" @click="showDataSelectionDialog(index, false)"> 选择批次 </el-button>
            <span v-if="!item || item.length === 0" class="span_class" style="font-size: 15px; color: red">未完成</span>
            <span v-else class="span_class" style="font-size: 15px; color: greenyellow">已选择</span>
            <el-button v-show="formData.testData.length > 1" style="margin-left: 20px" @click="removeDataItem(index, false)"> 删除数据 </el-button>
            <el-button
              v-show="formData.taskType === '2' && index + 1 === formData.testData.length"
              style="margin-left: 20px"
              @click="appendNewDataItem(false)"
            >
              添加数据
            </el-button>
          </el-container>
        </el-container>
      </el-container>

      <el-container style="height: 10px"></el-container>
      <el-container>
        <span class="span_class">是否训练扩增</span>
        <el-checkbox v-model="formData.expandData">扩增</el-checkbox>
        <el-button v-show="formData.expandData" style="margin-left: 20px" @click="showExpandDataSuperParameterConfig"> 超参配置 </el-button>
      </el-container>

      <el-form-item style="margin-top: 20px; margin-left: 30px">
        <el-button type="primary" @click="submit"> 提交 </el-button>

        <el-button @click="cancel"> 取消 </el-button>
      </el-form-item>
    </dv-border-box1>

    <FormDialog ref="formDialogRef" @update="handleUpdateModelList" />

    <el-dialog v-model="expandDataDialogVisible" title="数据扩增超参配置">
      <!--      <span style="font-size: 16px; color: darkorange; font-weight: bold"> 数据扩增超参 </span>-->
      <!--      <el-container v-for="(item, index) in expandDataConfig" :key="index" style="margin-top: 5px">-->
      <!--        <span class="span_class"> {{ item.name }}</span>-->
      <!--        <el-input style="width: 300px" type="text" :placeholder="'请输入' + item.name" v-model="item.defaultValue"> </el-input>-->
      <!--      </el-container>-->
      <el-container style="margin-top: 5px">
        <AmplifyForm
          @update-data="updateBatchData"
          @update-model="updateModelData"
          @update-params="updateParamsList"
          :show-select-batch-button="true"
          :use-data="true"
          :data-list="selectedBatchDataList"
        />
      </el-container>
      <el-container style="height: 10px"></el-container>

      <span class="dialog-footer">
        <el-button type="primary" @click="submitExpandDataConfigDialog">确 定</el-button>
        <el-button @click="expandDataDialogVisible = false">取 消</el-button>
      </span>
    </el-dialog>

    <el-dialog v-model="dialogVisible" :title="superParameterFormData.title">
      <span style="font-size: 16px; font-weight: bold; color: darkorange"> 训练超参 </span>
      <el-container v-for="(item, index) in superParameterFormData.trainParams" :key="index">
        <span class="span_class"> {{ item.name }}</span>
        <el-tooltip effect="dark" :content="item?.prompt" placement="top">
          <i :class="'iconfont icon-yiwen'"></i>
        </el-tooltip>
        <el-input style="width: 300px" type="text" :placeholder="'请输入' + item.name" v-model="item.defaultValue"> </el-input>
      </el-container>
      <el-container style="height: 10px"></el-container>

      <span style="font-size: 16px; font-weight: bold; color: darkorange"> 验证超参 </span>
      <el-container v-for="(item, index) in superParameterFormData.verifyParams" :key="index">
        <span class="span_class"> {{ item.name }}</span>
        <el-tooltip effect="dark" :content="item?.prompt" placement="top">
          <i :class="'iconfont icon-yiwen'"></i>
        </el-tooltip>
        <el-input style="width: 300px" type="text" :placeholder="'请输入' + item.name" v-model="item.defaultValue"> </el-input>
      </el-container>
      <el-container style="height: 10px"></el-container>

      <span style="font-size: 16px; font-weight: bold; color: darkorange"> 测试超参 </span>
      <el-container v-for="(item, index) in superParameterFormData.testParams" :key="index">
        <span class="span_class"> {{ item.name }}</span>
        <el-tooltip effect="dark" :content="item?.prompt" placement="top">
          <i :class="'iconfont icon-yiwen'"></i>
        </el-tooltip>
        <el-input style="width: 300px" type="text" :placeholder="'请输入' + item.name" v-model="item.defaultValue"> </el-input>
      </el-container>
      <el-container style="height: 10px"></el-container>

      <span class="dialog-footer">
        <el-button type="primary" @click="submitConfigDialog">确 定</el-button>
        <el-button @click="dialogVisible = false">取 消</el-button>
      </span>
    </el-dialog>

    <el-dialog v-model="dataDialogVisible" title="选择数据批次" style="width: 70vw">
      <el-container>
        <el-table :data="batchDataList" tooltip-effect="dark" style="width: 100%" @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="55"> </el-table-column>
          <el-table-column prop="batchNum" label="所有批次" width="120"> </el-table-column>
          <el-table-column prop="batchSize" label="数量" width="80"> </el-table-column>
        </el-table>

        <el-container style="display: flex; flex-direction: column; justify-content: center; margin-right: 10px; margin-left: 10px">
          <el-button type="primary" :disabled="!canSelect" @click="clickSelectData"> {{ '=>' }} </el-button>
          <el-container style="height: 10px"></el-container>
          <el-button type="primary" :disabled="!canDeselect" @click="clickDeselectData"> {{ '<=' }} </el-button>
        </el-container>

        <el-table :data="selectedBatchDataList" tooltip-effect="dark" style="width: 100%" @selection-change="handleDeselectionChange">
          <el-table-column type="selection" width="55"> </el-table-column>
          <el-table-column prop="batchNum" label="已选批次" width="120"> </el-table-column>
          <el-table-column prop="batchSize" label="数量" width="80"> </el-table-column>
        </el-table>
      </el-container>

      <el-container style="height: 10px"></el-container>
      <span class="dialog-footer">
        <el-button type="primary" @click="submitDataDialog">确 定</el-button>
        <el-button @click="dataDialogVisible = false">取 消</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref, onMounted, computed } from 'vue'
import { addModelApi, queryModelList } from '@/api/modules/ag/model'
import { createTaskApi } from '@/api/modules/task/task'
import FormDialog from '@/components/FormDialog/index.vue'
import { useRouter } from 'vue-router'
import { listTaskConfigurationApi } from '@/api/modules/task/taskConfiguration'
import { amplifyApi, batchListDataApi } from '@/api/modules/demo/data'
import { getDictsApi, listDataApi } from '@/api/modules/system/dictData'
import { ElMessage } from 'element-plus'
import AmplifyForm from '@/views/demo/data/AmplifyForm.vue'

let selectedBatchDataList1 = ref([] as any[])
let model = ref({})
let parameList = ref([] as any[])

// 监听 AmplifyForm 组件传递的数据
const updateBatchData = data => {
  selectedBatchDataList1.value = data
}

const updateModelData = data => {
  model.value = data
  console.log('model', model.value)
}

// 监听 parameList 更新
const updateParamsList = data => {
  parameList.value = data
  console.log('params', parameList.value)
}

// 提交逻辑
const getTrainAugmentationParams = () => {
  let batchNum = selectedBatchDataList1.value.map(batch => batch.batchNum).join()

  // 将 parameList 中的值也传递到接口
  parameList.value.forEach(item => {
    item.value = model.value[`${item.agName}`]
  })

  return {
    batchNum: batchNum,
    taskName: model.value.taskName,
    augmentationType: model.value.augmentationType,
    otherParams: parameList.value
  }
}
const valid = data => {
  let ret = {
    code: 400,
    message: 'OK'
  }
  if (!data.taskName || data.taskName.length === 0) {
    ret.message = '任务名称不能为空'
    return ret
  }
  if (!data.taskItemList || data.taskItemList.length === 0) {
    ret.message = '请选择算法任务'
    return ret
  }
  data.algTaskList.forEach(obj => {
    if (!obj || !obj.id) {
      ret.message = '请选择算法模型'
    }
  })
  if (ret.message !== 'OK') {
    return ret
  }
  if (data.taskItemList.includes('1')) {
    data.trainBatchNumList.forEach(obj => {
      if (!obj) {
        ret.message = '请选择训练数据集'
      }
    })
    if (ret.message !== 'OK') {
      return ret
    }
  }
  if (data.taskItemList.includes('2')) {
    data.testBatchNumList.forEach(obj => {
      if (!obj) {
        ret.message = '请选择测试数据集'
      }
    })
    if (ret.message !== 'OK') {
      return ret
    }
  }
  if (data.hasTrainAugmentation) {
    if (!data.trainAugmentationParams || data.trainAugmentationParams.length === 0) {
      ret.message = '请配置扩增参数'
      return ret
    }
  }
  ret.code = 200
  return ret
}

const submit = () => {
  const params = {
    taskName: formData.taskName,
    taskType: formData.taskType,
    taskItemList: formData.tasks,
    algTaskList: formData.algorithms,
    trainBatchNumList: formData.data,
    testBatchNumList: formData.testData,
    hasTrainAugmentation: formData.expandData,
    trainAugmentationParams: getTrainAugmentationParams()
  }
  console.log('submit data', params)
  let result = valid(params)
  // console.log(result)
  if (result.code !== 200) {
    ElMessage.error(result.message)
    return
  }

  let __idx = 0
  params.algTaskList.forEach(obj => {
    obj.algorithmId = obj.id
    // if (!obj.trainParams) {
    //   return
    // }
    let o1 = JSON.parse(obj.trainParams)
    let o2 = JSON.parse(obj.verifyParams)
    let o3 = JSON.parse(obj.testParams)
    if (formData.algoModelId[__idx] && formData.algoModelId[__idx].length > 0) {
      const __trained = {
        agName: 'pretrained_model',
        defaultValue: true,
        modelId: formData.algoModelId[__idx]
      }
      o1.push(__trained)
      o2.push(__trained)
      o3.push(__trained)
    }

    obj.params = JSON.stringify(o1) + ';;;' + JSON.stringify(o2) + ';;;' + JSON.stringify(o3)
    __idx++
  })
  // console.log('submit', params)

  createTaskApi(params)
    .then(res => {
      // console.log(res)
      if (res.code !== 200) {
        ElMessage.error(res.msg)
      } else {
        router.push(`/index`)
      }
    })
    .catch(err => {
      console.log(err)
    })
}

const loadExpandDataParams = () => {
  listDataApi({
    dictType: 'expand_data_params',
    pageNum: 1,
    pageSize: 10000
  })
    .then(res => {
      // console.log(res)
      expandDataConfig.value = reactive([])
      res.data.list.forEach(obj => {
        expandDataConfig.value.push({
          name: obj.dictLabel,
          defaultValue: obj.dictValue
        })
      })
      expandDataDialogVisible.value = true
    })
    .catch(err => {
      console.log(err)
    })
}

const showExpandDataSuperParameterConfig = () => {
  loadExpandDataParams()
}
// 数据扩增超参修改保存
const submitExpandDataConfigDialog = () => {
  expandDataDialogVisible.value = false
}

const expandDataDialogVisible = ref(false)

let expandDataConfig = ref(
  reactive([
    // {
    //   name: 'config1',
    //   defaultValue: 'a'
    // }
  ])
)

const submitConfigDialog = () => {
  dialogVisible.value = false
  formData.algorithms[superParameterFormData.index].trainParams = JSON.stringify(superParameterFormData.trainParams)
  formData.algorithms[superParameterFormData.index].verifyParams = JSON.stringify(superParameterFormData.verifyParams)
  formData.algorithms[superParameterFormData.index].testParams = JSON.stringify(superParameterFormData.testParams)
}
// 选择批次的数据结果
const submitDataDialog = () => {
  // console.log(selectedBatchDataList.value)
  let val = ''
  for (let i = 0; i < selectedBatchDataList.value.length; i++) {
    val += selectedBatchDataList.value[i].batchNum + ','
  }
  if (bIsTrainData.value) {
    formData.data[selectDataIndex] = val.substring(0, val.length - 1)
  } else {
    formData.testData[selectDataIndex] = val.substring(0, val.length - 1)
  }
  dataDialogVisible.value = false
}
const canSelect = computed(() => {
  // console.log(tempSelectedBatchDataList)
  return tempSelectedBatchDataList.value.length > 0
})
const canDeselect = computed(() => {
  return tempDeselectedBatchDataList.value.length > 0
})

const handleUpdateModelList = () => {
  updateModelList(UPDATE_INDEX.value.id, UPDATE_INDEX.value.idx)
}

onMounted(() => {
  listTaskConfigurationApi({ pageNum: 1, pageSize: 10000 }).then(res => {
    // console.log(res)
    algorithms = reactive(res.data.list)
  })
  batchListDataApi().then(res => {
    // console.log(res)
    queryBatchData.value = reactive(res.data)
  })
})
let queryBatchData = ref(reactive([]))
const handleSelectionChange = data => {
  tempSelectedBatchDataList.value = reactive(data)
  // console.log(data)
}
const handleDeselectionChange = data => {
  tempDeselectedBatchDataList.value = reactive(data)
  // console.log(data)
}
const clickSelectData = () => {
  let set = new Set()
  for (let i = 0; i < tempSelectedBatchDataList.value.length; i++) {
    set.add(tempSelectedBatchDataList.value[i].batchNum)
    selectedBatchDataList.value.push(tempSelectedBatchDataList.value[i])
  }
  let newArray = []
  for (let i = 0; i < batchDataList.value.length; i++) {
    if (!set.has(batchDataList.value[i].batchNum)) {
      newArray.push(batchDataList.value[i])
    }
  }
  batchDataList.value = reactive(newArray)
  // console.log(batchDataList)
}
const clickDeselectData = () => {
  let set = new Set()
  for (let i = 0; i < tempDeselectedBatchDataList.value.length; i++) {
    set.add(tempDeselectedBatchDataList.value[i].batchNum)
    batchDataList.value.push(tempDeselectedBatchDataList.value[i])
  }
  let newArray = []
  for (let i = 0; i < selectedBatchDataList.value.length; i++) {
    if (!set.has(selectedBatchDataList.value[i].batchNum)) {
      newArray.push(selectedBatchDataList.value[i])
    }
  }
  selectedBatchDataList.value = reactive(newArray)
}
const router = useRouter()
let bIsTrainData = ref(false)
let dialogVisible = ref(false)
let batchDataList = ref(reactive([]))
let selectedBatchDataList = ref(reactive([]))
let tempSelectedBatchDataList = ref(reactive([]))
let tempDeselectedBatchDataList = ref(reactive([]))

const formData = reactive({
  taskName: null,
  taskType: '1',
  tasks: [],
  algorithms: [{}],
  algoIdx: [null],
  algoModelId: [null],
  algoModelList: [[]],
  // 训练数据
  data: [null],
  // 测试数据
  testData: [null],
  expandData: false,
  expandConfig: null
})
let selectDataIndex = null
const dataDialogVisible = ref(false)
const showDataSelectionDialog = (index, isTrainData) => {
  bIsTrainData.value = isTrainData
  batchDataList.value = queryBatchData.value
  selectedBatchDataList.value = reactive([])
  tempSelectedBatchDataList.value = reactive([])
  tempDeselectedBatchDataList.value = reactive([])
  selectDataIndex = index
  fillCurrentDataDialogList(index, isTrainData)
  dataDialogVisible.value = true
}

const fillCurrentDataDialogList = (index, isTrainData) => {
  let list = []
  try {
    list = bIsTrainData.value ? formData.data[index]?.split(',') : formData.testData[index]?.split(',')
  } catch (e) {
    console.log(e)
  }
  let selected = new Set(list)
  batchDataList.value = []
  selectedBatchDataList.value = []

  batchListDataApi().then(res => {
    // console.log(res)
    for (let i = 0; i < res.data.length; i++) {
      if (selected.has(res.data[i].batchNum)) {
        selectedBatchDataList.value.push(res.data[i])
      } else {
        batchDataList.value.push(res.data[i])
      }
    }
  })
}

let superParameterFormData = reactive({})

const showSuperParameterConfig = (item, index) => {
  superParameterFormData = reactive({
    index: index,
    trainParams: JSON.parse(item.trainParams),
    testParams: JSON.parse(item.testParams),
    verifyParams: JSON.parse(item.verifyParams),
    title: '超参配置'
  })
  // console.log(superParameterFormData)
  dialogVisible.value = true
}

let algorithms = reactive([])

const onAlgorithmModelSelect = index => {
  formData.algorithms[index] = algorithms[formData.algoIdx[index]]
  updateModelList(formData.algorithms[index].id, index)
}

const formDialogRef = ref<InstanceType<typeof FormDialog> | null>(null)

let UPDATE_INDEX = ref({ id: null, idx: null })
const fileDescription = ref('')
const showAddModelDialog = async (item, index) => {
  let _id = null
  try {
    _id = item.id
  } catch (e) {
    ElMessage.error('请先选择算法模型')
    return
  }
  if (!_id || _id.length === 0) {
    ElMessage.error('请先选择算法模型')
    return
  }
  UPDATE_INDEX.value = {
    id: _id,
    idx: index
  }
  let _res = await getDictsApi('zip_file_format_description')

  _res.data.forEach(item => {
    // 检查item对象是否包含dict和des属性
    if (item.dictLabel === '多目标检测导入模型') {
      fileDescription.value = item.remark
    }
  })
  const params = {
    title: '算法模型配置',
    width: 580,
    isEdit: true,
    itemsOptions: [
      {
        label: '模型名称',
        prop: 'modelName',
        rules: [{ required: true, message: '模型名称不能为空', trigger: 'blur' }],
        compOptions: {
          placeholder: '请输入模型名称'
        }
      },
      {
        label: '模型',
        tooltip: fileDescription,
        prop: 'modelAddress',
        rules: [], //{ required: true, message: '模型不能为空', trigger: 'blur' }
        compOptions: {
          elTagName: 'slot'
        }
      },
      {
        label: '训练样本数',
        prop: 'sampleNumber',
        compOptions: {
          placeholder: '请输入训练样本数'
        }
      },
      {
        label: '训练循环次数',
        prop: 'cycleEpoch',
        compOptions: {
          placeholder: '请输入训练循环次数'
        }
      }
    ],
    model: {},
    api: addModelApi
  }
  console.log('check item:', item)
  formDialogRef.value?.openDialog(params, item.id)
}

// 获取算法模型绑定列表
const updateModelList = (id, index) => {
  // 获取算法列表？
  queryModelList({ id: id }).then(res => {
    console.log('algorithm task model get: ', res)
    if (res.code === 200) {
      formData.algoModelList[index] = [{ id: null, modelName: '未选择' }, ...res.data]
    }
  })
}

const appendNewItem = () => {
  formData.algorithms.push({})
  formData.algoIdx.push(null)
  formData.algoModelId.push(null)
  formData.algoModelList.push([])
}
const appendNewDataItem = isTrainData => {
  if (isTrainData) {
    formData.data.push([])
  } else {
    formData.testData.push([])
  }
}
const removeItem = idx => {
  formData.algorithms.splice(idx, 1)
  formData.algoIdx.splice(idx, 1)
  formData.algoModelId.splice(idx, 1)
  formData.algoModelList.splice(idx, 1)
}
const removeDataItem = (idx, isTrainData) => {
  if (isTrainData) {
    formData.data.splice(idx, 1)
  } else {
    formData.testData.splice(idx, 1)
  }
}
const cancel = () => {
  // console.log('cancel')
  router.push(`/index`)
}
</script>

<style scoped>
.createTask-bigBox {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-image: url('../../../assets/taaisImg/53bg.png');
  background-repeat: no-repeat;
  background-size: 100% 100%;
}
.span_class {
  display: flex;
  align-self: center;
  justify-content: center;
  width: 120px;
  font-size: 13px;
}
.span_class1 {
  display: flex;
  align-self: center;
  justify-content: center;
  width: 65px;
  font-size: 13px;
}
</style>
