<template>
  <Dialog :title="dialogTitle" v-model="dialogVisible" width="800px">
    <el-form
      ref="formRef"
      :model="formData"
      :rules="formRules"
      label-width="120px"
      v-loading="formLoading"
    >
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="项目名称" prop="name">
            <el-input v-model="formData.name" placeholder="请输入项目名称" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="识别类型" prop="type">
            <el-select v-model="formData.type" placeholder="请选择识别类型" style="width: 100%">
              <el-option
                v-for="dict in getIntDictOptions(DICT_TYPE.VISUAL_TYPE)"
                :key="dict.value"
                :label="dict.label"
                :value="dict.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>

      <el-form-item label="描述" prop="description">
        <el-input v-model="formData.description" placeholder="描述" />
      </el-form-item>

      <el-form-item label="数据集选择" prop="datasets">
        <el-select
          v-model="selectedDatasetIds"
          placeholder="请选择数据集"
          multiple
          style="width: 100%"
        >
          <el-option
            v-for="dataset in datasetList"
            :key="dataset.id"
            :label="dataset.name"
            :value="dataset.id"
          />
        </el-select>
        <div class="form-tip">已选择 {{ selectedDatasetIds.length }} 个数据集</div>
      </el-form-item>

      <el-divider content-position="left">训练参数配置</el-divider>

      <el-form-item label="数据集比例" prop="trainRatio">
        <div class="ratio-slider-container">
          <!-- 滑块 -->
          <div class="ratio-slider">
            <el-slider
              v-model="ratioRange"
              range
              :min="0"
              :max="100"
              :step="5"
              :show-tooltip="true"
              @input="handleRatiosChange"
            />
          </div>
          <!-- 比例显示 -->
          <div class="ratio-display">
            <span class="train-label">训练: <strong>{{ ratioRange[0] }}%</strong></span>
            <span class="val-label">验证: <strong>{{ ratioRange[1] - ratioRange[0] }}%</strong></span>
            <span class="test-label">测试: <strong>{{ 100 - ratioRange[1] }}%</strong></span>
          </div>
        </div>
      </el-form-item>

      <el-row :gutter="20">
        <el-col :span="8">
          <el-form-item label="训练次数" prop="epochs">
            <el-input-number
              v-model="formData.epochs"
              :min="1"
              :max="1000"
              style="width: 100%"
            />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="批次大小" prop="batch">
            <el-input-number
              v-model="formData.batch"
              :min="0"
              :max="128"
              :step="batchStep"
              :precision="batchPrecision"
              controls-position="right"
              style="width: 100%"
              @change="handleBatchChange"
            />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="图片大小" prop="imageSize">
            <el-input-number
              v-model="formData.imageSize"
              :min="32"
              :max="1280"
              :step="32"
              style="width: 100%"
            />
            <span class="pixel">px</span>
          </el-form-item>
        </el-col>
      </el-row>

      <el-form-item label="模型路径" prop="modelPath">
        <el-input v-model="formData.modelPath" placeholder="请输入模型路径（可选）" />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
      <el-button @click="dialogVisible = false">取 消</el-button>
    </template>
  </Dialog>
</template>
<script setup lang="ts">
import { DatasApi, DatasVO, DatasetDetail } from '@/api/annotation/datas'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { DatasetApi } from '@/api/annotation/dataset'

/** 数据集管理 表单 */
defineOptions({ name: 'DatasForm' })

const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗

const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中：1）修改时的数据加载；2）提交的按钮禁用
const formType = ref('') // 表单的类型：create - 新增；update - 修改
const datasetList = ref<DatasetDetail[]>([]) // 数据集列表
const selectedDatasetIds = ref<number[]>([]) // 选中的数据集ID列表

const formData = ref({
  id: undefined as number | undefined,
  name: undefined as string | undefined,
  description: undefined as string | undefined,
  status: undefined as string | undefined,
  count: undefined as number | undefined,
  type: undefined as number | string | undefined,
  progress: undefined as number | undefined,
  datasets: undefined as string | undefined,
  trainRatio: 70,
  valRatio: 20,
  testRatio: 10,
  epochs: 100,
  batch: 0.8,
  imageSize: 640,
  modelPath: undefined as string | undefined,
})

// 滑块值：[训练截止位置, 验证截止位置]
const ratioRange = ref<[number, number]>([70, 85])

// 处理滑块变化
const handleRatiosChange = () => {
  formData.value.trainRatio = ratioRange.value[0]
  formData.value.valRatio = ratioRange.value[1] - ratioRange.value[0]
  formData.value.testRatio = 100 - ratioRange.value[1]
}

// 批次大小：根据值动态调整 step 和 precision
const batchPrecision = computed(() => formData.value.batch && formData.value.batch > 1 ? 0 : 1)
const batchStep = computed(() => formData.value.batch && formData.value.batch > 1 ? 1 : 0.1)

const handleBatchChange = (val: number | undefined) => {
  if (val && val > 1) {
    // 大于1时四舍五入到整数
    formData.value.batch = Math.round(val)
  }
}

// 禁止使用的数据集名称列表
const forbiddenNames = ['test', 'dev']

/** 验证数据集名称 */
const validateName = (_rule: any, value: string, callback: any) => {
  if (!value) {
    return callback(new Error('项目名称不能为空'))
  }

  // 检查是否包含禁用的名称
  if (forbiddenNames.includes(value.toLowerCase())) {
    return callback(new Error(`项目名称不能为: ${forbiddenNames.join(', ')}`))
  }

  callback()
}

const formRules = reactive({
  name: [
    { required: true, message: '项目名称不能为空', trigger: 'blur' },
    { validator: validateName, trigger: 'blur' }
  ],
  type: [
    { required: true, message: '请选择识别类型', trigger: 'change' }
  ],
})

const formRef = ref() // 表单 Ref

/** 获取数据集列表 */
const getDatasetList = async () => {
  try {
    const data = await DatasetApi.getDatasetPage({ pageNo: 1, pageSize: 99 })
    datasetList.value = data.list.map((item: any) => ({
      id: item.id,
      name: item.name,
      path: item.path
    }))
  } catch (error) {
    message.error('获取数据集列表失败')
  }
}

/** 打开弹窗 */
const open = async (type: string, id?: number) => {
  dialogVisible.value = true
  dialogTitle.value = t('action.' + type)
  formType.value = type
  resetForm()

  // 获取数据集列表
  await getDatasetList()

  // 修改时，设置数据
  if (id) {
    formLoading.value = true
    try {
      formData.value = await DatasApi.getDatas(id)
      // 确保 type 是数字类型
      formData.value.type = formData.value.type ? Number(formData.value.type) : undefined

      // 处理数据集ID列表
      if (formData.value.datasets) {
        selectedDatasetIds.value = formData.value.datasets.split(',').map(Number)
      }

      // 同步滑块值
      if (formData.value.trainRatio !== undefined) {
        ratioRange.value = [
          formData.value.trainRatio,
          formData.value.trainRatio + (formData.value.valRatio || 0)
        ]
      }
    } finally {
      formLoading.value = false
    }
  }
}
defineExpose({ open }) // 提供 open 方法，用于打开弹窗

/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件，用于操作成功后的回调
const submitForm = async () => {
  // 校验表单
  await formRef.value.validate()

  // 校验数据集选择
  if (selectedDatasetIds.value.length === 0) {
    message.warning('请至少选择一个数据集')
    return
  }

  // 提交请求
  formLoading.value = true
  try {
    // 将选中的数据集ID转换为逗号分隔的字符串
    formData.value.datasets = selectedDatasetIds.value.join(',')

    const data = formData.value as unknown as DatasVO
    if (formType.value === 'create') {
      await DatasApi.createDatas(data)
      message.success(t('common.createSuccess'))
    } else {
      await DatasApi.updateDatas(data)
      message.success(t('common.updateSuccess'))
    }
    dialogVisible.value = false
    // 发送操作成功的事件
    emit('success')
  } finally {
    formLoading.value = false
  }
}

/** 重置表单 */
const resetForm = () => {
  formData.value = {
    id: undefined,
    name: undefined,
    description: undefined,
    status: undefined,
    count: undefined,
    type: undefined,
    progress: undefined,
    datasets: undefined,
    trainRatio: 70,
    valRatio: 15,
    testRatio: 15,
    epochs: 100,
    batch: 0.8,
    imageSize: 640,
    modelPath: undefined,
  }
  // 同步滑块值
  ratioRange.value = [70, 85]
  selectedDatasetIds.value = []
  formRef.value?.resetFields()
}
</script>

<style scoped>
.percentage, .pixel {
  margin-left: 8px;
  color: #909399;
  font-size: 14px;
}

.form-tip {
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
}

.ratio-slider-container {
  width: 100%;
  padding: 10px 0;
}

.ratio-slider {
  padding: 10px 5px;
}

/* 比例显示 */
.ratio-display {
  display: flex;
  justify-content: space-around;
  padding: 12px 15px;
  background: #f5f7fa;
  border-radius: 8px;
  margin-top: 10px;
}

.ratio-display span {
  font-size: 14px;
  color: #606266;
}

.ratio-display strong {
  font-size: 18px;
  margin-left: 4px;
}

.train-label strong {
  color: #67c23a;
}

.val-label strong {
  color: #409eff;
}

.test-label strong {
  color: #e6a23c;
}
</style>