<script setup lang="ts">
import { reactive, onMounted, toRaw, watch, PropType } from 'vue';
import { ProModal } from 'antdv-pro-modal';
import { message, Form, Modal } from 'ant-design-vue/es';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { regExpIPv4, regExpIPv6 } from '@/utils/regular-utils';
import useDictStore from '@/store/modules/dict';
import useI18n from '@/hooks/useI18n';
import {
  addTraceTask,
  delTraceTask,
  getTraceTask,
  listTraceTask,
  updateTraceTask,
} from '@/api/trace/task';
import dayjs, { Dayjs } from 'dayjs';
const { getDict } = useDictStore();
const { t } = useI18n();
const emit = defineEmits(['ok', 'cancel', 'update:open']);
const props = defineProps({
  open: {
    type: Boolean,
    default: false,
  },
  id: {
    type: Number,
    default: 0,
    required: true,
  },
  options: {
    type: Array as PropType<any[]>,
    default: () => [],
  },
});

/**字典数据 */
let dict: {
  /**跟踪类型 */
  traceType: DictType[];
  /**跟踪接口 */
  traceInterfaces: DictType[];
} = reactive({
  traceType: [],
  traceInterfaces: [],
});

/**对话框对象信息状态类型 */
type ModalStateType = {
  /**新增框或修改框是否显示 */
  openByEdit: boolean;
  /**标题 */
  title: string;
  /**网元类型设备对象 */
  neType: any[] | undefined;
  /**网元类型设备对象接口 */
  neTypeInterface: string[];
  /**任务开始结束时间 */
  timeRangePicker: [Dayjs, Dayjs] | undefined;
  /**表单数据 */
  from: {
    id?: string;
    coreId: number; // 核心网元ID
    neIds: string; // 网元ID列表 例如 1,3
    startTime?: number;
    endTime?: number;
    title: string;
    remark?: string;
    /**1-Interface,2-Device,3-User */
    traceType: string;
    /**1接口跟踪 */
    interfaces?: string;
    /**2设备跟踪 */
    srcIp?: string;
    dstIp?: string;
    signalPort?: number;
    /**3用户跟踪 */
    imsi?: string;
    msisdn?: string;
  };
  /**确定按钮 loading */
  confirmLoading: boolean;
};

/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
  openByView: false,
  openByEdit: false,
  title: '',
  neType: [],
  neTypeInterface: [],
  timeRangePicker: undefined,
  from: {
    id: undefined,
    coreId: 0,
    neIds: '',
    traceId: undefined,
    startTime: undefined,
    endTime: undefined,
    title: '',
    remark: '',
    traceType: '3',
    /**1接口跟踪 */
    interfaces: '',
    /**2设备跟踪 */
    srcIp: '',
    dstIp: '',
    signalPort: undefined,
    /**3用户跟踪 */
    imsi: undefined,
    // msisdn: undefined,
  },
  confirmLoading: false,
});

/**对话框内表单属性和校验规则 */
const modalStateFrom = Form.useForm(
  modalState.from,
  reactive({
    traceType: [
      {
        required: true,
        message: t('views.traceManage.task.trackTypePlease'),
      },
    ],
    neList: [
      {
        required: true,
        message: t('views.ne.common.neTypePlease'),
      },
    ],
    endTime: [
      {
        required: true,
        message: t('views.traceManage.task.rangePickerPlease'),
      },
    ],
    title: [
      {
        required: true,
        message: t('common.inputPlease'),
      },
    ],
    // 用户跟踪
    imsi: [
      {
        required: true,
        message: t('views.traceManage.task.imsiPlease'),
      },
    ],
    msisdn: [
      {
        required: false,
        message: t('views.traceManage.task.msisdnPlease'),
      },
    ],
    // 接口跟踪
    interfaces: [
      {
        required: true,
        message: t('views.traceManage.task.interfacesPlease'),
      },
    ],
    // 数据跟踪
    srcIp: [
      {
        required: true,
        pattern: regExpIPv4,
        message: t('views.traceManage.task.srcIpPlease'),
      },
    ],
    dstIp: [
      {
        required: true,
        pattern: regExpIPv4,
        message: t('views.traceManage.task.dstIpPlease'),
      },
    ],
  })
);

/**网元类型选择对应修改 */
function fnNeChange(p: any, c: any) {
  let neList: string[] = [];
  for (let i = 0; i < p.length; i++) {
    const v = p[i];
    if (v.length === 1) {
      c[i][0].children.forEach((item: any) => {
        neList.push(`${item.id}`);
      });
    } else if (v.length === 2) {
      neList.push(`${v[0]}_${v[1]}`);
    }
  }
  if (neList.length > 0) {
    modalState.from.neIds = neList.join(',');
  } else {
    modalState.from.neIds = '';
  }
}

/**开始结束时间选择对应修改 */
function fnRangePickerChange(item: any, _: any) {
  if (!item || item.length !== 2) {
    modalState.from.startTime = undefined;
    modalState.from.endTime = undefined;
    return;
  }
  // 获取当前时间
  const now = dayjs();
  // 如果开始时间小于当前时间，则设置为当前时间
  const startTime = item[0].isBefore(now) ? now : item[0];
  const endTime = item[1].isBefore(now) ? now : item[1];
  modalState.timeRangePicker = [startTime, endTime];

  modalState.from.startTime = startTime.valueOf();
  modalState.from.endTime = endTime.valueOf();
}
function fnRangePickerDisabledDate(current: Dayjs) {
  return current && current < dayjs().startOf('day');
}

/**信令接口选择对应修改 */
function fnSelectInterface(s: any, _: any) {
  modalState.from.interfaces = s.join(',');
}

/**
 * 对话框弹出显示为 新增或者修改
 * @param noticeId 网元id, 不传为新增
 */
function fnModalOpenByEdit() {
  if (!props.id) {
    fnModalCancel();
    modalState.title = t('views.traceManage.task.addTask');
    modalState.openByEdit = true;
  } else {
    if (modalState.confirmLoading) return;
    const hide = message.loading(t('common.loading'), 0);
    modalState.confirmLoading = true;
    getTraceTask(props.id).then(res => {
      modalState.confirmLoading = false;
      hide();
      if (res.code === RESULT_CODE_SUCCESS && res.data) {
        // 回显网元类型
        const neType: any[] = [];
        const neList = res.data.neList.split(',');
        const neListMap: any = {};
        for (const v of neList) {
          const item: string[] = v.split('_');
          if (!neListMap[item[0]]) {
            neListMap[item[0]] = [];
          }
          neListMap[item[0]].push(item[1]);
        }
        for (const op of props.options) {
          const arr = neListMap[op.value];
          if (!arr) {
            continue;
          }
          const all = op.children.every((c: any) => {
            return arr.includes(c.neUid);
          });
          if (all) {
            neType.push([op.value]);
          } else {
            arr.forEach((v: string) => {
              neType.push([op.value, v]);
            });
          }
        }
        modalState.neType = neType;
        // 回显时间
        modalState.timeRangePicker = [
          dayjs(res.data.startTime),
          dayjs(res.data.endTime),
        ];
        // 回显接口
        if (res.data.traceType === '1') {
          modalState.neTypeInterface = res.data.interfaces.split(',');
        }
        modalState.from = Object.assign(modalState.from, res.data);
        modalState.title = t('views.traceManage.task.viewTask');
        modalState.openByEdit = true;
      } else {
        message.error(t('views.traceManage.task.errorTaskInfo'), 3);
      }
    });
  }
}

/**
 * 对话框弹出确认执行函数
 * 进行表达规则校验
 */
function fnModalOk() {
  const from = toRaw(modalState.from);
  let valids = ['title', 'traceType', 'neList', 'endTime'];
  if (from.traceType === '1') {
    valids = valids.concat(['interfaces']);
  }
  if (from.traceType === '2') {
    valids = valids.concat(['srcIp', 'dstIp']);
  }
  if (from.traceType === '3') {
    valids = valids.concat(['imsi']);
  }

  modalStateFrom
    .validate(valids)
    .then(e => {
      modalState.confirmLoading = true;
      const traceTask = from.id ? updateTraceTask(from) : addTraceTask(from);
      const hide = message.loading(t('common.loading'), 0);
      traceTask
        .then(res => {
          if (res.code === RESULT_CODE_SUCCESS) {
            message.success({
              content: t('common.msgSuccess', { msg: modalState.title }),
              duration: 3,
            });
            // 返回无引用信息
            emit('ok', JSON.parse(JSON.stringify(from)));
            fnModalCancel();
          } else {
            message.error({
              content: `${res.msg}`,
              duration: 3,
            });
          }
        })
        .finally(() => {
          hide();
          modalState.confirmLoading = false;
        });
    })
    .catch(e => {
      message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
    });
}

/**
 * 对话框弹出关闭执行函数
 * 进行表达规则校验
 */
function fnModalCancel() {
  modalState.openByEdit = false;
  modalState.confirmLoading = false;
  modalState.timeRangePicker = undefined;
  modalState.neType = undefined;
  modalState.neTypeInterface = [];
  modalStateFrom.resetFields();
  emit('cancel');
  emit('update:open', false);
}

/**监听是否显示，初始数据 */
watch(
  () => props.open,
  val => {
    if (val) fnModalOpenByEdit();
  }
);

onMounted(() => {
  // 初始字典数据
  Promise.allSettled([getDict('trace_type'), getDict('trace_interfaces')]).then(
    resArr => {
      if (resArr[0].status === 'fulfilled') {
        dict.traceType = resArr[0].value;
      }
      if (resArr[1].status === 'fulfilled') {
        dict.traceInterfaces = resArr[1].value;
      }
    }
  );
});
</script>

<template>
  <ProModal
    :drag="true"
    :width="800"
    :destroyOnClose="true"
    :keyboard="false"
    :mask-closable="false"
    :open="modalState.openByEdit"
    :title="modalState.title"
    :confirm-loading="modalState.confirmLoading"
    @ok="fnModalOk"
    @cancel="fnModalCancel"
    :footer="modalState.from.id ? null : undefined"
  >
    <a-form
      name="modalStateFrom"
      layout="horizontal"
      :label-col="{ span: 4 }"
      :label-wrap="true"
      :disabled="!!modalState.from.id"
    >
      <a-form-item
        :label="t('views.traceManage.task.title')"
        name="title"
        v-bind="modalStateFrom.validateInfos.title"
      >
        <a-input
          v-model:value="modalState.from.title"
          allow-clear
          :placeholder="t('common.inputPlease')"
        >
        </a-input>
      </a-form-item>
      <a-form-item :label="t('views.traceManage.task.remark')" name="remark">
        <a-textarea
          v-model:value="modalState.from.remark"
          :auto-size="{ minRows: 1, maxRows: 6 }"
          :maxlength="450"
          :show-count="true"
          :placeholder="t('views.traceManage.task.remarkPlease')"
        />
      </a-form-item>

      <a-row>
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item
            :label="t('views.ne.common.neType')"
            :label-col="{ span: 8 }"
            name="neType"
            v-bind="modalStateFrom.validateInfos.neList"
          >
            <a-cascader
              v-model:value="modalState.neType"
              :options="props.options"
              @change="fnNeChange"
              multiple
              :allow-clear="false"
              :placeholder="t('views.ne.common.neTypePlease')"
            />
          </a-form-item>
        </a-col>
        <a-col :lg="12" :md="12" :xs="24">
          <a-form-item
            :label="t('views.traceManage.task.trackType')"
            :label-col="{ span: 8 }"
            name="traceType"
            v-bind="modalStateFrom.validateInfos.traceType"
          >
            <a-select
              v-model:value="modalState.from.traceType"
              :options="dict.traceType"
              :allow-clear="false"
              :placeholder="t('views.traceManage.task.trackTypePlease')"
            >
            </a-select>
          </a-form-item>
        </a-col>
      </a-row>

      <a-form-item
        :label="t('views.traceManage.task.rangePicker')"
        name="endTime"
        v-bind="modalStateFrom.validateInfos.endTime"
      >
        <a-range-picker
          v-model:value="modalState.timeRangePicker"
          @change="fnRangePickerChange"
          bordered
          :show-time="{ format: 'HH:mm:ss' }"
          format="YYYY-MM-DD HH:mm:ss"
          style="width: 100%"
          :disabled-date="fnRangePickerDisabledDate"
        ></a-range-picker>
      </a-form-item>

      <!-- 接口跟踪 -->
      <template v-if="modalState.from.traceType === '1'">
        <a-form-item
          :label="t('views.traceManage.task.interfaces')"
          name="interfaces"
          v-bind="modalStateFrom.validateInfos.interfaces"
        >
          <a-select
            mode="multiple"
            :placeholder="t('views.traceManage.task.interfacesPlease')"
            v-model:value="modalState.neTypeInterface"
            :options="dict.traceInterfaces"
            @change="fnSelectInterface"
          >
          </a-select>
        </a-form-item>
      </template>

      <!-- 设备跟踪 -->
      <template v-if="modalState.from.traceType === '2'">
        <a-row>
          <a-col :lg="12" :md="12" :xs="24">
            <a-form-item
              :label="t('views.traceManage.task.srcIp')"
              :label-col="{ span: 8 }"
              name="srcIp"
              v-bind="modalStateFrom.validateInfos.srcIp"
            >
              <a-input
                v-model:value="modalState.from.srcIp"
                allow-clear
                :placeholder="t('views.traceManage.task.srcIpPlease')"
              >
                <template #prefix>
                  <a-tooltip placement="topLeft">
                    <template #title>
                      <div>{{ t('views.traceManage.task.srcIpTip') }}</div>
                    </template>
                    <InfoCircleOutlined style="opacity: 0.45; color: inherit" />
                  </a-tooltip>
                </template>
              </a-input>
            </a-form-item>
          </a-col>
          <a-col :lg="12" :md="12" :xs="24">
            <a-form-item
              :label="t('views.traceManage.task.dstIp')"
              :label-col="{ span: 8 }"
              name="dstIp"
              v-bind="modalStateFrom.validateInfos.dstIp"
            >
              <a-input
                v-model:value="modalState.from.dstIp"
                allow-clear
                :placeholder="t('views.traceManage.task.dstIpPlease')"
              >
                <template #prefix>
                  <a-tooltip placement="topLeft">
                    <template #title>
                      <div>{{ t('views.traceManage.task.dstIpTip') }}</div>
                    </template>
                    <InfoCircleOutlined style="opacity: 0.45; color: inherit" />
                  </a-tooltip>
                </template>
              </a-input>
            </a-form-item>
          </a-col>
        </a-row>
      </template>

      <!-- 用户跟踪 -->
      <template v-if="modalState.from.traceType === '3'">
        <a-form-item
          :label="t('views.traceManage.task.imsi')"
          name="imsi"
          v-bind="modalStateFrom.validateInfos.imsi"
        >
          <a-input
            v-model:value="modalState.from.imsi"
            allow-clear
            :placeholder="t('views.traceManage.task.imsiPlease')"
          >
            <template #prefix>
              <a-tooltip placement="topLeft">
                <template #title>
                  <div>{{ t('views.traceManage.task.imsiTip') }}</div>
                </template>
                <InfoCircleOutlined style="opacity: 0.45; color: inherit" />
              </a-tooltip>
            </template>
          </a-input>
        </a-form-item>
        <!-- <a-form-item
            :label="t('views.traceManage.task.msisdn')"
            name="msisdn"
            v-bind="modalStateFrom.validateInfos.msisdn"
          >
            <a-input
              v-model:value="modalState.from.msisdn"
              allow-clear
              :placeholder="t('views.traceManage.task.msisdnPlease')"
            >
              <template #prefix>
                <a-tooltip placement="topLeft">
                  <template #title>
                    <div>{{ t('views.traceManage.task.msisdnTip') }}</div>
                  </template>
                  <InfoCircleOutlined style="opacity: 0.45; color: inherit" />
                </a-tooltip>
              </template>
            </a-input>
          </a-form-item> -->
      </template>
    </a-form>
  </ProModal>
</template>

<style lang="less" scoped></style>
