<template>
  <BasicDrawer
    :maskClosable="false"
    @close="handleClose"
    destroyOnClose
    v-bind="$attrs"
    @register="registerDrawer"
    showFooter
    :title="getTitle"
    width="30%"
    @ok="handleSubmit"
  >
    <BasicForm @register="registerForm">
      <template #devices="{ model, field }">
        <p style="display: none">{{ field }}</p>
        <p>{{ queryModeFunc(model['queryMode']) }}</p>
        <p>{{ orgFunc(model['organizationId']) }}</p>
        <p>{{ dataTypeFunc(model['dataType']) }}</p>
        <Select
          placeholder="请选择设备"
          v-model:value="selectDevice"
          style="width: 100%"
          :options="selectOptions"
          @change="handleDeviceChange"
          @deselect="handleDeselect"
          mode="multiple"
          labelInValue
          notFoundContent="请选择设备"
        />
        <div style="margin-top: 1.5vh"></div>
        <template v-for="(item, index) in deviceList" :key="item.value">
          <p style="display: none">{{ index }}</p>
          <DeviceAttrCpns
            :ref="bindDeviceRefObj.deviceAttrRef"
            :value="item"
            :orgId="organizationId || orgId"
          />
        </template>
      </template>
    </BasicForm>
  </BasicDrawer>
</template>
<script lang="ts" setup>
  import { ref, computed, unref, reactive, watch, Ref } from 'vue';
  import { BasicForm, useForm } from '/@/components/Form';
  import { formSchema, organizationId } from './config.data';
  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
  import {
    createOrEditReportManage,
    putReportConfigManage,
    reportEditDetailPage,
  } from '/@/api/report/reportManager';
  import { useMessage } from '/@/hooks/web/useMessage';
  import moment from 'moment';
  import { screenLinkPageByDeptIdGetDevice } from '/@/api/ruleengine/ruleengineApi';
  import { Select } from 'ant-design-vue';
  import DeviceAttrCpns from './cpns/DeviceAttrCpns.vue';
  import { SchemaFiled } from './config.data';
  import { QueryWay } from '../../device/localtion/cpns/TimePeriodForm/config';
  import { AggregateDataEnum } from '../../device/localtion/cpns/TimePeriodForm/config';

  type TDeviceList = {
    key?: string;
    value?: string;
    label?: string;
    attribute?: string;
    device?: string;
    name?: string;
    attributes?: string | undefined;
    deviceProfileId?: string;
    id?: string;
  };
  type TSelectOption = {
    value?: string;
    label?: string;
    deviceProfileId?: string;
    id?: string;
  };
  const emit = defineEmits(['success', 'register']);
  const bindDeviceRefObj = {
    deviceAttrRef: ref([]),
  };
  const isUpdate = ref(true);
  const editId = ref('');
  const orgId = ref('');
  const selectOptions: Ref<TSelectOption[]> = ref([]);
  const selectDevice = ref([]);
  const deviceList: Ref<TDeviceList[]> = ref([]);
  const editDeviceList: Ref<TDeviceList[]> = ref([]);
  let editResData: any = reactive({});
  const editDeviceAttr: any = ref([]);
  const orgFuncId = ref('');
  const queryModeStr = ref('');
  const dataTypeStr = ref(0);
  const orgFunc = (e) => {
    orgFuncId.value = e;
  };
  const queryModeFunc = (e) => {
    queryModeStr.value = e;
  };
  const dataTypeFunc = (e) => {
    dataTypeStr.value = e;
  };
  watch(
    () => dataTypeStr.value,
    (newValue) => {
      if (newValue == 0) {
        setFieldsValue({ limit: 100 });
      } else {
      }
    }
  );
  watch(
    () => queryModeStr.value,
    (newValue: string) => {
      if (newValue == 'latest') {
        setFieldsValue({ startTs: 1000 });
        setFieldsValue({ interval: 1000 });
      } else {
      }
    }
  );
  watch(
    () => orgFuncId.value,
    async (newValue: string) => {
      if (newValue) {
        //获取设备
        const { items } = await screenLinkPageByDeptIdGetDevice({
          organizationId: newValue,
        });
        selectOptions.value = items.map((item) => {
          if (item.deviceType !== 'GATEWAY')
            return {
              label: item.alias ? item.alias : item.name,
              value: item.tbDeviceId,
              id: item.id,
              deviceProfileId: item.deviceProfileId,
            };
        });
      }
    }
  );
  //设备Select选中
  const handleDeviceChange = (_, o) => {
    if (unref(isUpdate)) {
      //编辑
      let temp: any = [];
      editDeviceAttr.value.forEach((f) => {
        temp = [f, ...o];
      });
      let deWeightThree = () => {
        let map = new Map();
        for (let item of deviceList.value) {
          if (!map.has(item.value)) {
            map.set(item.value, item);
          }
        }
        return [...map.values()];
      };
      temp = deWeightThree();
      deviceList.value = temp;
      if (o.length !== 0) {
        deviceList.value = o;
      }
    } else {
      deviceList.value = o;
    }
  };
  //设备取消删除
  const handleDeselect = (e) => {
    if (unref(isUpdate)) {
      //编辑
      let deWeightThree = () => {
        let map = new Map();
        for (let item of deviceList.value) {
          if (!map.has(item.value)) {
            map.set(item.value, item);
          }
        }
        return [...map.values()];
      };
      deviceList.value = deWeightThree();
      const findEditValue = deviceList.value.findIndex((f) => f.value == e.value);
      if (findEditValue !== -1) deviceList.value.splice(findEditValue, 1);
    } else {
      const eDevice = e.key || e.value;
      const findValue = deviceList.value.findIndex((f) => f.value == eDevice);
      if (findValue !== -1) deviceList.value.splice(findValue, 1);
    }
  };
  const [registerForm, { validate, setFieldsValue, resetFields, updateSchema, getFieldsValue }] =
    useForm({
      labelWidth: 120,
      schemas: formSchema,
      showActionButtonGroup: false,
      fieldMapToTime: [[SchemaFiled.DATE_RANGE, [SchemaFiled.START_TS, SchemaFiled.END_TS]]],
    });
  const isViewDetail = ref(false);

  const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
    await resetFields();
    setDrawerProps({ confirmLoading: false });
    isUpdate.value = !!data?.isUpdate;
    isViewDetail.value = !!data?.isView;
    if (unref(isViewDetail)) {
      setDrawerProps({ showFooter: true });
      if (unref(isUpdate)) {
        setDrawerProps({ title: '编辑报表配置' });
      } else {
        setDrawerProps({ title: '新增报表配置' });
      }
    } else {
      setDrawerProps({ showFooter: false });
      setDrawerProps({ title: '查看报表配置' });
    }
    if (unref(isUpdate)) {
      //编辑回显数据
      editResData = await reportEditDetailPage(data.record.id);
      //回显基础数据
      editId.value = editResData.data.id;
      await setFieldsValue(editResData.data);
      //回显嵌套数据
      await setFieldsValue({
        agg: editResData.data.queryCondition?.agg,
        interval: editResData.data.queryCondition?.interval,
        limit: editResData.data.queryCondition?.limit,
        orderBy: editResData.data.queryCondition?.orderBy,
        useStrictDataTypes: editResData.data.queryCondition?.useStrictDataTypes,
        startTs: editResData.data.queryCondition?.startTs,
        endTs: editResData.data.queryCondition?.endTs,
        way: editResData.data?.way,
        queryMode: editResData.data.queryCondition?.queryMode === 0 ? 'latest' : 'timePeriod',
        cronTime: editResData.data?.executeContent,
        currentCycle: editResData.data?.cycle?.currentCycle,
        cycleTime: editResData.data?.cycle?.cycleTime,
        cycleType: editResData.data?.cycle?.cycleType,
      });
      const endTsTime = editResData.data.queryCondition?.endTs;
      const startTsTime = editResData.data.queryCondition?.startTs;
      const mathFloor = (endTsTime - startTsTime) / 10;
      const multTen = Math.floor(mathFloor) * 10;
      await setFieldsValue({
        startTs: multTen,
      });
      if (editResData.data.queryCondition?.queryMode == 1) {
        await setFieldsValue({
          dataRange: [
            editResData.data.queryCondition?.startTs,
            editResData.data.queryCondition?.endTs,
          ],
        });
      }
      //回显聚合条件
      const dataCompareOpions = [
        { label: '最小值', value: AggregateDataEnum.MIN },
        { label: '最大值', value: AggregateDataEnum.MAX },
        { label: '平均值', value: AggregateDataEnum.AVG },
        { label: '求和', value: AggregateDataEnum.SUM },
        { label: '空', value: AggregateDataEnum.NONE },
      ];
      const updateSchemaAgg = (options: {}) => {
        updateSchema({
          field: SchemaFiled.AGG,
          componentProps: {
            options,
          },
        });
      };
      if (editResData.data.dataType == 1) updateSchemaAgg(dataCompareOpions.slice(0, 4));
      else updateSchemaAgg(dataCompareOpions.slice(4, 5));
      //回显执行方式和查询周期
      const dataQueryOpions = [
        { label: '固定周期', value: QueryWay.LATEST },
        { label: '自定义周期', value: QueryWay.TIME_PERIOD },
      ];
      const updateSchemaQuery = (options: {}) => {
        updateSchema({
          field: SchemaFiled.WAY,
          componentProps: {
            options,
          },
        });
      };
      if (editResData.data.executeWay == 0) updateSchemaQuery(dataQueryOpions);
      else updateSchemaQuery(dataQueryOpions.slice(0, 1));
      //回显设备
      orgId.value = editResData.data.organizationId;
      const { items } = await screenLinkPageByDeptIdGetDevice({
        organizationId: editResData.data.organizationId,
      });
      selectOptions.value = items.map((item) => {
        if (item.deviceType !== 'GATEWAY')
          return {
            label: item.alias ? item.alias : item.name,
            value: item.tbDeviceId,
            id: item.id,
            deviceProfileId: item.deviceProfileId,
          };
      });
      const deviceIds = editResData.data.executeAttributes.map((m) => {
        return {
          label: m.name,
          key: m.device,
        };
      });
      selectDevice.value = deviceIds;
      //回显设备属性
      editDeviceAttr.value = editResData.data.executeAttributes?.map((item) => {
        const T = selectOptions.value.find((o) => {
          if (item.device === o.value) {
            return {
              id: o.id,
              deviceProfileId: o.deviceProfileId,
            };
          }
        });
        return {
          ...T,
          label: item.alias ? item.alias : item.name,
          value: item.device,
          attributes: item.attributes,
        };
      });
      deviceList.value = editDeviceAttr.value;
      editDeviceList.value = editResData.data.executeAttributes;
    } else {
      setFieldsValue({
        startTs: 1000,
        interval: 1000,
      });
      editId.value = '';
      orgId.value = '';
      selectDevice.value = [];
      selectOptions.value = [];
      deviceList.value = [];
      getAttrDevice.value = [];
      editDeviceList.value = [];
      editDeviceAttr.value = [];
      updateSchema({
        field: SchemaFiled.AGG,
        componentProps: {
          options: [],
        },
      });
      //新增显示执行方式和查询周期
      const dataQueryOpions = [
        { label: '固定周期', value: QueryWay.LATEST },
        { label: '自定义周期', value: QueryWay.TIME_PERIOD },
      ];
      const updateSchemaQuery = (options: {}) => {
        updateSchema({
          field: SchemaFiled.WAY,
          componentProps: {
            options,
          },
        });
      };
      if (getFieldsValue().executeWay == 0) updateSchemaQuery(dataQueryOpions);
    }
  });
  const handleClose = () => {
    deviceList.value = [];
    editId.value = '';
    orgId.value = '';
    selectDevice.value = [];
    selectOptions.value = [];
    getAttrDevice.value = [];
    editDeviceList.value = [];
    editDeviceAttr.value = [];
  };
  const getAttrDevice: Ref<TDeviceList[]> = ref([]);
  const getTitle = computed(() => (!unref(isUpdate) ? '新增报表配置' : '编辑报表配置'));
  let postObj: any = reactive({});
  let queryCondition: any = reactive({});
  let executeContent: any = reactive({});
  const startTs = ref(0);
  const endTs = ref(0);

  const getFormValueFunc = () => {
    const item: any = unref(bindDeviceRefObj.deviceAttrRef)?.map((item: any) => item.emitChange());
    getAttrDevice.value = item;
  };

  async function handleSubmit() {
    setDrawerProps({ confirmLoading: true });
    try {
      const { createMessage } = useMessage();
      const values = await validate();
      if (!values) return;
      getFormValueFunc();
      let hasAttr = false;
      if (!unref(isUpdate)) {
        if (getAttrDevice.value.length === 0) {
          return createMessage.error('请选择设备及其属性');
        } else {
          getAttrDevice.value.forEach((f: any) => {
            if (f.attributes == undefined || f.attributes.length == 0) hasAttr = true;
          });
        }
      } else {
        if (getAttrDevice.value.length === 0) {
          return createMessage.error('请选择设备及其属性');
        } else {
          getAttrDevice.value.forEach((f: any) => {
            if (f.attributes == undefined || f.attributes.length == 0) hasAttr = true;
          });
        }
      }
      if (hasAttr) return createMessage.error('请选择设备属性');
      if (values.executeWay == 0) {
        executeContent = null;
      } else {
        executeContent = values.cronTime;
      }
      if (values.queryMode === QueryWay.LATEST) {
        startTs.value = moment().subtract(values.startTs, 'ms').valueOf();
        endTs.value = Date.now();
      } else {
        const fT = JSON.parse(JSON.stringify(values.dataRange));
        startTs.value = moment(fT[0]).valueOf();
        endTs.value = moment(fT[1]).valueOf();
      }
      queryCondition = {
        agg: values.agg,
        interval: values.interval,
        limit: values.limit,
        ...{
          startTs: startTs.value,
        },
        ...{
          endTs: endTs.value,
        },
        queryMode: values?.queryMode === 'latest' ? 0 : 1,
      };
      const cycle = {
        currentCycle: values.currentCycle,
        cycleTime: values.cycleTime,
        cycleType: values.cycleType,
      };
      delete values.devices;
      delete values.agg;
      delete values.interval;
      delete values.timeZone;
      delete values.cronTime;
      delete values.currentCycle;
      delete values.cycleTime;
      delete values.limit1;
      delete values.startTs;
      delete values.queryMode;
      delete values.cycleType;
      postObj = {
        ...values,
        ...{
          executeAttributes:
            getAttrDevice.value.length == 0 ? editDeviceList.value : getAttrDevice.value,
        },
        ...{ queryCondition },
        ...{ cycle },
        ...{ executeContent },
        ...{ id: editId.value !== '' ? editId.value : '' },
      };
      let saveMessage = '添加成功';
      let updateMessage = '修改成功';
      editId.value !== ''
        ? await putReportConfigManage(postObj)
        : await createOrEditReportManage(postObj);

      closeDrawer();
      emit('success');
      createMessage.success(unref(isUpdate) ? updateMessage : saveMessage);
      handleClose();
    } finally {
      setTimeout(() => {
        setDrawerProps({ confirmLoading: false });
      }, 300);
    }
  }
</script>
