<template>
  <div
    class="algo-params-card"
    :class="{ 'algo-params-card-active': markedParamCardIds.includes(props.id) }"
  >
    <el-form
      ref="ruleFormRef"
      :model="algoParams"
      :inline="true"
      :rules="rules"
      label-width="120px"
    >
      <div v-for="item in paramItems">
        <el-form-item v-if="item.type === 'label'" label="检测对象：" prop="label">
          <el-select v-model="algoParams.label" style="width: 186px" @change="handleLabelChange">
            <el-option
              v-for="item in getLabelList()"
              :key="item.value"
              :label="item.label"
              :value="item.value"
              :disabled="item.disabled"
            />
          </el-select>
        </el-form-item>
        <el-form-item
          v-if="item.type === 'criticalCount'"
          :label="labelNameMap[item.label] + '检测数量：'"
          :prop="item.prop"
          required
        >
          <ElInputNumber
            v-model="algoParams[item.prop]"
            controls-position="right"
            :min="0"
            :step="1"
            style="width: 186px; margin-right: 5px"
            :disabled="!algoParams.label"
          />
          <span>s</span>
        </el-form-item>
        <el-form-item
          v-if="item.type === 'confidence'"
          :label="labelNameMap[item.label] + '置信度：'"
          :prop="item.prop"
          required
        >
          <div style="display: flex">
            <el-slider
              v-model="algoParams[item.prop]"
              :min="25"
              :max="98"
              :step="1"
              style="width: 128px; margin-right: 6px"
              :disabled="!algoParams.label"
            />

            <ElInputNumber
              v-model="algoParams[item.prop]"
              controls-position="right"
              :min="0"
              :step="1"
              style="width: 88px; margin-right: 5px"
              :disabled="!algoParams.label"
            />
            <span>%</span>
          </div>
        </el-form-item>
        <el-form-item
          v-if="item.type === 'minArea'"
          :label="labelNameMap[item.label] + '最小检测面积：'"
          required
        >
          <el-form-item :prop="item.label ? item.label + '.' + 'min-width' : 'min-width'">
            <ElInputNumber
              v-model="algoParams[item.label ? item.label + '.' + 'min-width' : 'min-width']"
              controls-position="right"
              :min="32"
              :step="1"
              style="width: 88px; margin-right: 5px"
              :disabled="!algoParams.label"
            />
            <span>px</span>
          </el-form-item>
          <el-form-item
            :prop="item.label ? item.label + '.' + 'min-height' : 'min-height'"
            style="margin-left: 17px"
          >
            <ElInputNumber
              v-model="algoParams[item.label ? item.label + '.' + 'min-height' : 'min-height']"
              controls-position="right"
              :min="32"
              :step="1"
              style="width: 88px; margin-right: 5px"
              :disabled="!algoParams.label"
            />
            <span>px</span>
          </el-form-item>
        </el-form-item>
      </div>
    </el-form>
    <div class="paramOptIcons">
      <!-- <el-icon v-if="isEdit" size="16px" @click="handleSaveParam(ruleFormRef)">
        <SaveOutline />
      </el-icon>
      <el-icon v-else size="16px" @click="isEdit = true"><Edit /></el-icon> -->
      <el-icon size="16px" @click="deleteParam(props.id)"><Delete /></el-icon>
    </div>
  </div>
</template>

<script setup lang="ts">
  import { computed, ref, watch } from 'vue';
  import useCameraAlgoStore, { AlgoParamMetaItem } from '../../store/useCameraAlgoStore';
  import { storeToRefs } from 'pinia';
  import { ElInputNumber, ElMessage, FormInstance } from 'element-plus';
  import { Delete, Edit } from '@element-plus/icons-vue';
  import { SaveOutline } from '@vicons/ionicons5';
  import { labelNameMap } from './types';

  const props = defineProps<{
    id: string;
  }>();

  const cameraAlgoStore = useCameraAlgoStore();
  const { selectedAlgoDetail, metaObjList, markedParamCardIds } = storeToRefs(cameraAlgoStore);
  const { deleteParam } = cameraAlgoStore;

  const ruleFormRef = ref<FormInstance>();
  //是否在编辑
  const isEdit = ref(false);

  const getLabelList = () => {
    return metaObjList.value.map((item) => {
      const entry = selectedAlgoDetail.value.metaValues.find(
        (val) => val.label === item.label && item.label !== algoParams.value.label,
      );
      return {
        label: labelNameMap[item.label],
        value: item.label,
        disabled: entry ? true : false,
      };
    });
  };

  const handleLabelChange = () => {
    markedParamCardIds.value = selectedAlgoDetail.value.metaValues
      .filter((item) => !item.label)
      .map((item) => item.id);
  };

  const algoParams = computed(
    () =>
      selectedAlgoDetail.value.metaValues.find((item) => item.id === props.id) ||
      ({} as AlgoParamMetaItem),
  );

  const paramItems = ref([
    { label: '', type: 'label', prop: 'label' },
    { label: '', type: 'criticalCount', prop: 'criticalCount' },
    { label: '', type: 'confidence', prop: 'confidence' },
    { label: '', type: 'minArea', prop: '' },
  ]);

  watch(
    () => algoParams.value.label,
    (val) => {
      if (!val) return;
      const meta = metaObjList.value.find((item) => item.label === val);
      algoParams.value.criticalCount = 0;
      algoParams.value.confidence = meta.confidence * 100;
      algoParams.value['min-width'] = meta['min-width'];
      algoParams.value['min-height'] = meta['min-height'];

      const nexts = meta.nextObjs;
      if (nexts) {
        for (let i = 0; i < nexts.length; i++) {
          const item = nexts[i];
          paramItems.value.push({
            label: item.label,
            type: 'confidence',
            prop: `${item.label}.confidence`,
          });
          algoParams.value[`${item.label}.confidence`] = item.confidence * 100;
          paramItems.value.push({
            label: item.label,
            type: 'minArea',
            prop: '',
          });
          algoParams.value[item.label + '.' + 'min-width'] = item['min-width'];
          algoParams.value[item.label + '.' + 'min-height'] = item['min-height'];
        }
      }
    },
    {
      immediate: true,
    },
  );

  const rules = computed(() => {
    const rule = {} as any;
    paramItems.value.forEach((param) => {
      if (param.type === 'label') {
        rule.label = [
          {
            required: true,
            message: '请选择检测对象',
            trigger: 'blur',
          },
        ];
      }
      if (param.type === 'criticalCount') {
        rule[`${param.label}.criticalCount`] = [
          {
            required: true,
            message: '请输入检测数量',
            trigger: 'blur',
          },
          { validator: integerJudge, trigger: 'blur' },
        ];
      }
      if (param.type === 'confidence') {
        rule[`${param.label}.confidence`] = [
          {
            required: true,
            message: '请输入检测置信度',
            trigger: 'blur',
          },
          { validator: integerJudge, trigger: 'blur' },
        ];
      }
      if (param.type === 'minArea') {
        rule[param.label ? param.label + '.' + 'min-width' : 'min-width'] = [
          {
            required: true,
            message: '请输入最小宽度',
            trigger: 'blur',
          },
          { validator: integerJudge, trigger: 'blur' },
        ];
        rule[param.label ? param.label + '.' + 'min-height' : 'min-height'] = [
          {
            required: true,
            message: '请输入最小高度',
            trigger: 'blur',
          },
          { validator: integerJudge, trigger: 'blur' },
        ];
      }
    });
    return rule;
  });

  const integerJudge = (rule, value, callback) => {
    // 整数校验逻辑
    const pattern = /^-?\d+$/;
    if (pattern.test(value)) {
      callback(); // 校验通过
    } else {
      callback(new Error('请输入一个整数'));
    }
  };

  const handleSaveParam = async (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    await formEl.validate((valid, fields) => {
      if (valid) {
        isEdit.value = false;
      } else {
        ElMessage.error('保存失败，请检查填写');
      }
    });
  };

  const checkValid = async () => {
    if (!ruleFormRef.value) return false;
    let isValid = true;
    await ruleFormRef.value.validate((valid, fields) => {
      if (valid) {
      } else {
        isValid = false;
      }
    });
    return isValid;
  };

  const setEditable = (value: boolean) => {
    isEdit.value = value;
  };

  defineExpose({
    checkValid,
  });
</script>

<style scoped lang="scss">
  .algo-params-card {
    position: relative;
    width: 400px;
    background: #0000000a;
    border-radius: 5px;
    border: 1px solid #e8ecf2;
    padding: 10px 0 0 10px;
    margin: 0 5px 5px 5px;

    &-active {
      border: 1px solid #ff0000ab;
    }
  }

  .input-box {
    width: 80px;
  }

  .paramOptIcons {
    position: absolute;
    top: 6px;
    right: 6px;
    display: flex;
    justify-content: space-between;
    color: #00000026;
    cursor: pointer;
  }

  :deep(.el-form--inline .el-form-item) {
    margin-bottom: 10px;
    margin-right: 10px;
  }

  :deep(.el-form-item__label) {
    line-height: 16px;
    font-size: 14px;
  }
</style>
