<template>
  <div id="algoCardWrapper" class="algoCardWrapper">
    <div class="algoCardTitle">
      <div>{{ selectedAlgoDetail?.algoInfo?.name }}</div>
      <div style="display: flex; align-items: center">
        <ElSwitch
          v-model="selectedAlgoDetail.enableCardBool"
          size="small"
          @change="handleAlgoEnable"
        />
        <el-tooltip class="box-item" effect="dark" placement="top">
          <template #content> 关闭后该算法对<br />此台相机不生效</template>
          <el-icon color="#d4d5d8" :size="16" class="tipIcon"><InfoCircleOutlined /></el-icon>
        </el-tooltip>
      </div>
    </div>
    <div class="algoCardMain">
      <div class="algoRow" style="display: flex; align-items: center">
        <div class="algoLabel">绘制电子围栏:</div>
        <div>
          <div style="display: flex; align-items: center">
            <ElSwitch v-model="selectedAlgoDetail.electronicFenceBool" size="small" />
            <el-tooltip class="box-item" effect="dark" placement="top">
              <template #content>
                默认检测全部范围，如需<br />指定范围，可打开开关，<br />在相机界面完成绘制
              </template>
              <el-icon color="#e2e2e2" :size="16" class="tipIcon"><InfoCircleOutlined /></el-icon>
            </el-tooltip>
            <!-- <span style="font-size: 10px; margin-left: 20px; color: #262626"
              >备注：请绘制电子围栏</span
            > -->
            <el-radio-group
              v-model="selectedAlgoDetail.regionJudge"
              :disabled="!selectedAlgoDetail.electronicFenceBool"
              class="ml-3"
            >
              <el-radio :label="0">内</el-radio>
              <el-radio :label="1">外</el-radio>
            </el-radio-group>
          </div>
          <div class="presetList"> 预置位1 预置位2 预置位3 </div>
        </div>
      </div>
      <div class="algoRow">
        <div class="algoLabel">检测时间段:</div>
        <div class="algoTimeContent">
          <div class="timeAdd" @click="handleAddTimePeriod">
            <el-icon color="#d0d0d0"><Plus /></el-icon>
          </div>
          <div class="timeList">
            <PeriodCard
              v-for="(x, index) in selectedAlgoDetail.timeRangeArr"
              :key="x.id"
              :ref="(el) => (periodCardRefs[index] = el)"
              :id="x.id"
            />
          </div>
        </div>
      </div>
      <div class="algoRow">
        <div class="algoLabel">检测元数据:</div>
        <div class="algoTimeContent">
          <div
            class="timeAdd"
            :class="{ addDisable: unEmptyLabels.length >= selectedAlgoDetail.metaValues.length }"
            @click="handleAddMetaObj"
          >
            <el-icon color="#d0d0d0"><Plus /></el-icon>
          </div>
          <div class="timeList">
            <ParamCard
              v-for="(v, index) in selectedAlgoDetail.metaValues"
              :key="v.id"
              :ref="(el) => (paramCardRefs[index] = el)"
              :id="v.id"
            />
          </div>
        </div>
      </div>
      <div class="algoRow" style="align-items: center">
        <div class="algoLabel">检测数量范围:</div>
        <el-radio-group v-model="selectedAlgoDetail.judge" class="ml-4">
          <el-radio :label="0">小于</el-radio>
          <el-radio :label="1">大于</el-radio>
          <el-radio :label="2">等于</el-radio>
        </el-radio-group>
      </div>
      <div class="algoRow" style="align-items: center">
        <div class="algoLabel">检测频率:</div>
        <ElInputNumber
          v-model="selectedAlgoDetail.detectionFrequency"
          controls-position="right"
          :min="1"
          :step="1"
          size="small"
          style="width: 186px"
          @blur="checkFrequencyValid"
        />
        <span style="font-size: 12px; margin-left: 5px">S/次</span>
      </div>
      <div
        v-if="selectedAlgoDetail.timeWindow !== undefined"
        class="algoRow"
        style="align-items: center"
      >
        <div class="algoLabel">检测窗口时长:</div>
        <ElInputNumber
          v-model="selectedAlgoDetail.timeWindow"
          controls-position="right"
          :min="1"
          size="small"
          style="width: 186px"
          placeholder="请输入允许的最长时间"
          @blur="checkTimeWindowValid"
        />
        <span style="font-size: 12px; margin-left: 5px">S</span>
      </div>
      <div style="display: flex; justify-content: flex-end">
        <ElButton size="small" :disabled="!selectedAlgoId" @click="handleRemoveAlgo">取消</ElButton>
        <ElButton size="small" type="primary" @click="handleSave" :disabled="!selectedAlgoId"
          >保存</ElButton
        >
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
  import {
    ElSelect,
    ElOption,
    ElSwitch,
    ElInputNumber,
    ElTimePicker,
    ElMessage,
    ElMessageBox,
  } from 'element-plus';
  import { CircleCloseFilled, Plus } from '@element-plus/icons-vue';
  import { storeToRefs } from 'pinia';
  import dayjs, { Dayjs } from 'dayjs';
  import addTimeIcon from '@/assets/icons/addTimeIcon.png';
  import useCameraAlgoStore, { AlgoParamMetaItem } from '../../store/useCameraAlgoStore';
  import { createDefaultTime, frequencyOptions, getTimeCompletion } from './utils';
  import { InfoCircleOutlined } from '@vicons/antd';
  import { ALGO_ENABLED_STATUS, FENCE_ENBALED_STATUS } from '@/api/camera/camera-preview';
  import PeriodCard from './AlgoPeriodCard.vue';
  import ParamCard from './AlgoParamsCard.vue';
  import { uid } from 'uid';
  import { computed, ref } from 'vue';

  // const { data: algoList, loading } = useAllAlgos();
  const cameraAlgoStore = useCameraAlgoStore();
  const {
    selectedAlgoId,
    selectedAlgoDetail,
    metaObjList,
    markedTimeRangeIds,
    markedParamCardIds,
  } = storeToRefs(cameraAlgoStore);

  interface Param {
    /** 算法id */
    algoId: number;
    /** 检测频率，单位是秒 */
    detectionFrequency: number;
    /** 检测时间段，可以有多个，转化为字符串，格式为 09:00-10:00;11:00-12:00 */
    detectionTime: string;
    /** 电子围栏是否开启 */
    electronicFence: FENCE_ENBALED_STATUS;
    /** 算法是否启用 */
    status: ALGO_ENABLED_STATUS;
  }

  const emits = defineEmits<{
    (e: 'onSubmit', param: Param): Promise<unknown>;
    (e: 'onCancel', algoId: number): Promise<unknown>;
  }>();

  const periodCardRefs = ref<any>([]);
  const paramCardRefs = ref<any>([]);

  const handleAddTimePeriod = () => {
    const emptyList = selectedAlgoDetail.value.timeRangeArr.filter(
      (item) => !getTimeCompletion(item),
    );
    if (emptyList && emptyList.length > 0) {
      emptyList.forEach((item) => markedTimeRangeIds.value.push(item.id));
      ElMessage.error('请先完善检测时间段数据');
      return;
    }
    selectedAlgoDetail.value.timeRangeArr.push(createDefaultTime());
  };

  const unEmptyLabels = computed(() => {
    return selectedAlgoDetail.value.metaValues.filter((item) => item.label);
  });

  const handleAddMetaObj = () => {
    if (unEmptyLabels.value.length < selectedAlgoDetail.value.metaValues.length) {
      selectedAlgoDetail.value.metaValues
        .filter((item) => !item.label)
        .forEach((val) => markedParamCardIds.value.push(val.id));
      ElMessage.error('存在未完善的检测元数据');
      return;
    }
    // if (unemptyList.length == metaObjList.value.length) {
    //   ElMessage.warning('暂无更多检测对象');
    //   return;
    // }
    selectedAlgoDetail.value.metaValues.push({ id: uid() } as AlgoParamMetaItem);
  };

  const removeTime = (id: string) => {
    const timeRangeArr = selectedAlgoDetail.value.timeRangeArr;
    selectedAlgoDetail.value.timeRangeArr = timeRangeArr.filter((x) => x.id !== id);
  };

  const getTimeStr = (d: Dayjs) => {
    return dayjs(d).format('HH:mm:ss');
  };
  const getTimeStrs = (d: [Dayjs, Dayjs]) => {
    return getTimeStr(d[0]) + '-' + getTimeStr(d[1]);
  };

  const handleAlgoEnable = () => {
    handleSave();
  };

  const checkFrequencyValid = () => {
    selectedAlgoDetail.value.detectionFrequency = Math.ceil(
      selectedAlgoDetail.value.detectionFrequency,
    );
  };

  const checkTimeWindowValid = () => {
    selectedAlgoDetail.value.timeWindow = Math.ceil(selectedAlgoDetail.value.timeWindow || 1);
  };

  const handleSave = async () => {
    //判断时间段是否合格
    if (markedTimeRangeIds.value.length > 0) {
      ElMessage.error('请正确填写检测时间段');
      return;
    }
    const emptyTimes = selectedAlgoDetail.value.timeRangeArr.filter(
      (item) => !item.startDay || !item.endDay,
    );
    if (emptyTimes && emptyTimes.length > 0) {
      emptyTimes.forEach((item) => {
        markedTimeRangeIds.value.push(item.id);
      });
      ElMessage.error('请完善检测时间段');
      return;
    }
    for (let i = 0; i < periodCardRefs.value.length; i++) {
      const item = periodCardRefs.value[i];
      switch (item.checkValid()) {
        case 0:
          ElMessage.error('请正确填写检测时间段');
          return;
        case 1:
          ElMessage.error('请完善检测时间段');
          return;
        case 2:
          ElMessage.error('至少有一个时间段');
          return;
        case 3:
          break;
      }
    }

    //判断元数据是否合格
    for (let i = 0; i < paramCardRefs.value.length; i++) {
      const item = paramCardRefs.value[i];
      const res = await item.checkValid();
      if (res) {
      } else {
        ElMessage.error('请正确填写检测元数据');
        return;
      }
    }

    //判断时间段和元数据都有值
    const detail = selectedAlgoDetail.value;
    if (!detail) return;
    const timeRanges = detail.timeRangeArr;
    // if (timeRanges.length == 0) {
    //   ElMessage.error('至少添加一个检测时间段');
    //   return;
    // }
    const metaValues = detail.metaValues;
    if (metaValues.length == 0) {
      ElMessage.error('至少添加一个检测元数据');
      return;
    }

    //数据处理
    const metaObjs = metaValues.map((meta) => {
      const obj = metaObjList.value.find((item) => item.label === meta.label);
      const val = {
        label: meta.label,
        confidence: meta.confidence / 100,
        'min_width': meta['min_width'],
        'min_height': meta['min_height'],
      } as any;
      const nextValues = [] as any[];
      obj.nextObjs.forEach((next) => {
        if (meta[`${next.label}.confidence`]) {
          nextValues.push({
            label: next.label,
            confidence: meta[`${next.label}.confidence`] / 100,
            'min_width': meta[next.label + '.' + 'min_width'],
            'min_height': meta[next.label + '.' + 'min_height'],
            nextObjs: [],
          });
        }
      });
      val.nextObjs = nextValues;
      return val;
    });
    const param = {
      id: detail.id,
      inferCode: detail.inferCode,
      algoId: detail.algoId,
      detectionFrequency: detail.detectionFrequency,
      regionJudge: detail.regionJudge,
      detectionTime: JSON.stringify(detail.timeRangeArr),
      metaObjs,
      criticalCounts: metaValues.map((item) => item.criticalCount),
      judge: detail.judge,
      electronicFence: detail.electronicFenceBool
        ? FENCE_ENBALED_STATUS.enabled
        : FENCE_ENBALED_STATUS.disabled,
      status: detail.enableCardBool ? ALGO_ENABLED_STATUS.enabled : ALGO_ENABLED_STATUS.disabled,
    } as any;
    if (detail.timeWindow) {
      param.timeWindow = detail.timeWindow;
    }
    emits('onSubmit', param);
    console.log('param', param);
  };

  const handleRemoveAlgo = () => {
    if (!selectedAlgoId.value) return;
    const el = document.getElementById('algoCardWrapper') as HTMLElement;
    ElMessageBox.confirm(
      '<strong>确认取消算法配置吗?</strong><br />取消后配置的参数将不会被保存。',
      '',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
        dangerouslyUseHTMLString: true,
        appendTo: el,
      },
    )
      .then(() => {
        emits('onCancel', selectedAlgoId.value!);
      })
      .catch(() => {});
  };
</script>
<style scoped>
  .algoCardWrapper {
    border: 1px solid #ccc;
    border-radius: 4px;
    /* padding: 10px; */
    width: 780px;
  }

  .algoRow {
    display: flex;
    margin: 10px 0;
  }

  .algoLabel {
    margin-right: 10px;
    width: 90px;
    text-align: right;
  }
  .algoTimeContent {
    display: flex;
  }
  .presetList {
    font-size: 12px;
    display: none;
  }
  .removeIcon {
    margin-left: 10px;
    color: #8c8c8c;
    cursor: pointer;
  }

  .addTimeIcon {
    cursor: pointer;
  }

  .algoCardTitle {
    background: #f0f2f5;
    display: flex;
    justify-content: space-between;
    padding: 4px 20px;
    align-items: center;
  }

  .algoCardMain {
    padding: 10px 15px;
  }

  .timeAdd {
    width: 28px;
    height: 90px;
    background: #ebebeb;
    border-radius: 4px;
    border: 1px dashed #00000026;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-right: 5px;
    cursor: pointer;
  }
  .addDisable {
    opacity: 0.5;
    cursor: not-allowed;
  }

  .timeList {
    width: 610px;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
  }
  .tipIcon {
    margin-left: 10px;
  }

  :deep(.ml-4) {
    margin-left: 0 !important;
  }
  :deep(.el-message-box__status.el-icon) {
    top: 0 !important;
    transform: none !important;
  }
</style>
