<template>
  <BasicDrawer
    v-bind="$attrs"
    @register="registerDrawer"
    showFooter
    :title="getTitle"
    width="500px"
    @ok="handleSubmit"
  >
    <BasicForm @register="registerForm">
      <template #menu>
        <Spin :spinning="spinning">
          <a-tabs v-model:activeKey="activeKey">
            <a-tab-pane key="1" tab="菜单分配" :force-render="true">
              <BasicTree
                v-if="treeData.length"
                checkable
                toolbar
                ref="treeRef"
                title="工具栏"
                :treeData="treeData"
                :replace-fields="{ title: 'name', key: 'id' }"
                :checkedKeys="roleMenus"
                @check="handleCheckClick"
              />
            </a-tab-pane>
            <!-- <a-tab-pane key="2" tab="权限分配" :force-render="true">
              <Spin :spinning="spinningT">
                <a-form
                  :model="formState"
                  :label-col="{ span: 4 }"
                  :wrapper-col="{ span: 18 }"
                  size="default"
                >
                  <a-form-item label="河段">
                    <a-select
                      v-model:value="formState.segments"
                      placeholder="请选择河段"
                      mode="multiple"
                      :showArrow="true"
                      :maxTagTextLength="4"
                      :maxTagCount="3"
                      allowClear
                      :options="segmentsOptions"
                      @change="segmentsChange"
                    />
                  </a-form-item>
                  <a-form-item label="工程">
                    <a-select
                      v-model:value="formState.projects"
                      placeholder="请选择工程"
                      mode="multiple"
                      :showArrow="true"
                      :maxTagTextLength="4"
                      :maxTagCount="3"
                      allowClear
                      :options="projectsOptions"
                      @change="projectsChange"
                    />
                  </a-form-item>
                  <a-form-item label="地灾点">
                    <a-select
                      v-model:value="formState.monitors"
                      placeholder="请选择地灾点"
                      mode="multiple"
                      :showArrow="true"
                      :maxTagTextLength="4"
                      :maxTagCount="3"
                      allowClear
                      :options="monitorsOptions"
                      @change="monitorsChange"
                    />
                  </a-form-item>
                  <a-form-item label="设备">
                    <a-tree-select
                      v-model:value="formState.devices"
                      style="width: 100%"
                      :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
                      :tree-data="TreeSelectData"
                      placeholder="请选择设备"
                      tree-checkable
                      :checkable="true"
                      :maxTagTextLength="4"
                      :maxTagCount="3"
                      allow-clear
                      showCheckedStrategy="SHOW_ALL"
                      tree-default-expand-all
                      @change="TreeSelectChange"
                    />
                  </a-form-item>
                  <a-form-item label="传感器">
                    <a-select
                      v-model:value="formState.sensors"
                      placeholder="请选择传感器"
                      mode="multiple"
                      :showArrow="true"
                      :maxTagTextLength="4"
                      :maxTagCount="3"
                      allowClear
                      :options="sensorsOptions"
                      @change="sensorsChange"
                    />
                  </a-form-item>
                  <a-form-item label="接入数据">
                    <a-select
                      v-model:value="formState.multiDatas"
                      placeholder="请选择接入数据"
                      mode="multiple"
                      :showArrow="true"
                      :maxTagTextLength="4"
                      allowClear
                      :maxTagCount="3"
                      :options="multiDatasOptions"
                    />
                  </a-form-item>
                </a-form>
              </Spin>
            </a-tab-pane> -->
          </a-tabs>
        </Spin>
      </template>
    </BasicForm>
  </BasicDrawer>
</template>
<script lang="ts">
  import { defineComponent, ref, computed, unref, nextTick, reactive, toRaw, watch } from 'vue';
  import { BasicForm, useForm } from '/@/components/Form/index';
  import { formSchema, KeysTypeEnum, RoleMenuDictEnum } from './role.data';
  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
  import { BasicTree, TreeItem } from '/@/components/Tree';
  import { useMessage } from '/@/hooks/web/useMessage';
  const { t } = useI18n(); //加载国际化
  // 加载菜单数据
  import {
    getMenuList,
    getMenusIdsByRoleId,
    getRolePermissionByUserId,
    getRolePermissionByRoleId,
    updateRolePermission,
  } from '/@/api/sys/menu';
  import {
    getSegmentsList,
    getProjectsList,
    getMonitorsList,
    getDevicesList,
    getRutList,
    getSensorsList,
    getMultiDatasList,
  } from '/@/api/system/role';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { MenuRecord } from '/@/api/sys/model/menuModel';
  import { saveOrUpdateRoleInfoWithMenu } from '/@/api/system/system';
  import { findDictItemByCode } from '/@/api/system/dict';
  import { RoleEnum } from '/@/enums/roleEnum';
  import { Spin, message } from 'ant-design-vue';
  import { useUserStore } from '/@/store/modules/user';

  type TreeData = MenuRecord & TreeItem;

  export default defineComponent({
    name: 'RoleDrawer',
    components: { BasicDrawer, BasicForm, BasicTree, Spin },
    emits: ['success', 'register'],
    setup(_, { emit }) {
      const formState = reactive({
        segments: [],
        projects: [],
        monitors: [],
        devices: [],
        ruts: [],
        sensors: [],
        multiDatas: [],
      });
      watch(
        () => formState.monitors,
        (count, prevCount) => {
          console.log(count);

          monitorsChange(count);
        }
      );
      const activeKey = ref('1');
      const segmentsOptions = ref([]);
      const projectsOptions = ref([]);
      const monitorsOptions = ref([]);
      const devicesOptions = ref([]);
      const rutOptions = ref([]);
      const sensorsOptions = ref([]);
      const multiDatasOptions = ref([]);
      const isUpdate = ref<boolean>(true);
      const treeData = ref<TreeData[]>([]);
      const roleMenus = ref<string[]>([]);
      const allCheckedKeys = ref<string[]>([]);
      const TreeSelectData: any = ref([]);
      const roleId = ref<string>('');
      const treeRef = ref();
      const checked = ref<string[]>([]); //需要选中的节点
      const spinning = ref(false);
      const spinningT = ref(false);
      async function getDataList() {
        spinningT.value = true;
        try {
          // const values1 = await getSegmentsList();
          // const values2 = await getProjectsList();
          // const values3 = await getMonitorsList();
          // const values4 = await getDevicesList();
          // const values5 = await getSensorsList();
          // const values6 = await getMultiDatasList();
          // const values7 = await getRutList();
          // if (values1 && values2 && values3 && values5 && values6 && values7) {
          //   segmentsOptions.value = values1.result.map((e) => {
          //     return {
          //       id: e.id,
          //       value: e.id,
          //       label: e.lymc,
          //     };
          //   });
          //   projectsOptions.value = values2.result.map((e) => {
          //     return {
          //       id: e.id,
          //       value: e.id,
          //       label: e.gcmc,
          //       sshdid: e.sshdid,
          //     };
          //   });
          //   monitorsOptions.value = values3.result.map((e) => {
          //     return {
          //       id: e.id,
          //       value: e.id,
          //       label: e.dzmc,
          //       ssgcid: e.ssgcid,
          //       ssgcmc: e.ssgcmc,
          //       sshdid: e.sshdid,
          //       sshdmc: e.sshdmc,
          //     };
          //   });
          //   devicesOptions.value = values4.result.map((e) => {
          //     return {
          //       id: e.id,
          //       value: e.id,
          //       label: e.deviceName,
          //       deviceRtu: e.deviceRtu,
          //       monitorPointId: e.monitorPointId, //地灾点ID
          //     };
          //   });
          //   rutOptions.value = values7.result.map((e) => {
          //     return {
          //       id: e.id,
          //       value: e.id,
          //       label: e.rtuName,
          //       rtuCode: e.rtuCode,
          //       monitorPointId: e.monitorPointId, //地灾点ID
          //     };
          //   });
          //   sensorsOptions.value = values5.result.map((e) => {
          //     return {
          //       id: e.sensorInnerCode,
          //       value: e.sensorInnerCode,
          //       label: e.sensorType_dictText,
          //       deviceId: e.deviceId, //设备ID
          //     };
          //   });
          //   multiDatasOptions.value = values6.result.map((e) => {
          //     return {
          //       id: e.id,
          //       value: e.id,
          //       label: e.zymc,
          //       sshdid: e.sshdid,
          //       sshdmc: e.sshdid,
          //       ssgcid: e.deviceId,
          //       ssgcmc: e.deviceId,
          //       ssdzdid: e.deviceId,
          //       ssdzdmc: e.deviceId,
          //     };
          //   });

          //   // console.log(segmentsOptions.value);
          //   // console.log(projectsOptions.value);
          //   // console.log(monitorsOptions.value);
          //   // console.log(devicesOptions.value);
          //   // console.log(rutOptions.value);
          //   // console.log(sensorsOptions.value);
          //   // console.log(multiDatasOptions.value);
          //   TreeSelectData.value = processData(rutOptions.value, devicesOptions.value);
          //   console.log('TreeSelectData.value', TreeSelectData.value);
          // } else {
          //   message.error('接口请求超时,请刷新页面重试!');
          // }
        } finally {
          spinningT.value = false;
        }
      }
      function processData(data1, data2) {
        let result = [
          { title: '与RTU关联', value: -1, key: -1, children: [] },
          { title: '未与RTU关联', value: -2, key: -2, children: [] },
        ];

        // 处理与RTU关联的数据
        data1.forEach((d1) => {
          let node1: any = {
            title: d1.label,
            value: d1.value,
            key: d1.value,
            rtuCode: d1.rtuCode,
            monitorPointId: d1.monitorPointId,
            children: [],
          };
          data2.forEach((d2) => {
            if (d2.deviceRtu === d1.rtuCode && d2.monitorPointId === d1.monitorPointId) {
              let node2: any = {
                title: d2.label,
                value: d2.value,
                key: d2.value,
                monitorPointId: d2.monitorPointId,
              };
              node1.children.push(node2);
            }
          });
          if (node1.children.length > 0) {
            result[0].children.push(node1);
          } else {
            node1.children = null;
            result[0].children.push(node1);
          }
        });

        // 处理未与RTU关联的数据
        data2.forEach((d2) => {
          if (d2.deviceRtu === '') {
            let node: any = { title: d2.label, value: d2.value, key: d2.value };
            result[1].children.push(node);
          }
        });

        return result;
      }
      // getDataList();
      const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
        labelWidth: 100,
        schemas: formSchema,
        showActionButtonGroup: false,
      });

      const transformName = (data: TreeData[]) => {
        return data.map((item) => {
          item.name = t(item.name);
          if (item.children && item.children.length) {
            item.children = transformName(item.children as unknown as TreeData[]);
          }
          return item;
        });
      };

      const userStore = useUserStore();
      const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
        activeKey.value = '1';
        allCheckedKeys.value = [];

        resetFields();
        roleId.value = '';
        // 在打开弹窗时清除所有选择的菜单
        treeRef.value && treeRef.value?.setCheckedKeys([]);
        isUpdate.value = data.isUpdate;
        const roleType = data?.record?.roleType || userStore.getRoleList.at(0);

        try {
          spinning.value = true;
          // 需要在setFieldsValue之前先填充treeData，否则Tree组件可能会报key not exist警告

          if (!unref(treeData).length) {
            // 获取全部的菜单
            const menuListModel = await getMenuList({});
            console.log('获取全部的菜单:', menuListModel);
            treeData.value = transformName(menuListModel as unknown as TreeData[]);
          }

          const keys = await getPermissionByRole(roleType);
          const { keyType } = RoleMenuDictEnum[roleType];
          treeData.value = getPermissionTreeData(
            unref(treeData) as unknown as TreeData[],
            keys,
            keyType
          );
          for (const key in formState) {
            if (Array.isArray(formState[key])) {
              formState[key] = [];
            }
          }
          // 更新
          if (unref(isUpdate)) {
            checked.value = [];
            roleId.value = data.record.id;

            //通过角色id去获取角色对应的菜单的ids
            allCheckedKeys.value = roleMenus.value = await getMenusIdsByRoleId(data.record.id);
            const backendData = await getRolePermissionByRoleId(data.record.id);

            // 遍历后台返回数据，并存储到对应的 formState 属性中
            backendData.forEach((item: any) => {
              const { permission_type, data_id } = item;
              if (formState.hasOwnProperty(permission_type)) {
                let sortedDataIds = [];

                if (permission_type === 'devices' || permission_type === 'sensors') {
                  sortedDataIds = data_id ? data_id.split(',') : [];
                } else {
                  sortedDataIds = data_id
                    ? data_id
                        .split(',')
                        .map(Number)
                        .sort((a, b) => a - b)
                    : [];
                }

                formState[permission_type] = sortedDataIds;
              }
            });
            console.log(formState);

            formState.devices = formState.devices.concat(formState.ruts);
            console.log(formState.devices);
            excludeHalfCheckedKeys(unref(treeData));
            await nextTick();
            treeRef.value.setCheckedKeys(roleMenus.value);
            setFieldsValue(data.record);
          } else {
          }
        } catch (error) {
          throw error;
        } finally {
          spinning.value = false;
        }
      });

      const getTitle = computed(() => (!unref(isUpdate) ? '新增角色' : '编辑角色'));

      async function handleSubmit() {
        const rtudevice = splitArrayByType(toRaw(formState).devices);

        const data = {
          segments: toRaw(formState).segments.toString(),
          projects: toRaw(formState).projects.toString(),
          monitors: toRaw(formState).monitors.toString(),
          devices: rtudevice[1].toString(),
          rtus: rtudevice[0].toString(),
          sensors: toRaw(formState).sensors.toString(),
          multiDatas: toRaw(formState).multiDatas.toString(),
          roleId: roleId.value,
        };
        setDrawerProps({ confirmLoading: true });
        const { createMessage } = useMessage();
        // allCheckedKeys.value = treeRef.value?.getCheckedKeys();//这个去掉了半选的父节点，所以注释掉了
        try {
          const values = await validate();
          const req = {
            id: roleId.value,
            name: values.name,
            remark: values.remark,
            status: values.status,
            menu: unref(allCheckedKeys) || [],
          };
          if (req.menu == undefined) return createMessage.error('请勾选权限菜单');

          if (unref(isUpdate)) {
            updateRole(data);
          }
          saveOrUpdateRoleInfoWithMenu(req).then((res) => {
            closeDrawer();
            emit('success');
            createMessage.success(`${unref(isUpdate) ? '编辑' : '新增'}成功`);
            if (!unref(isUpdate)) {
              data.roleId = res.data.id;
              updateRole(data);
            }
          });
        } finally {
          setTimeout(() => {
            setDrawerProps({ confirmLoading: false });
          }, 300);
        }
      }
      function updateRole(data) {
        updateRolePermission(data).then((res) => {
          if (res.code == 200) {
            message.success('权限分配成功！');
          }
        });
      }
      function splitArrayByType(elements) {
        const numberArray = [];
        const stringArray = [];

        for (const element of elements) {
          if (typeof element === 'number') {
            numberArray.push(element);
          } else if (typeof element === 'string') {
            stringArray.push(element);
          } else {
            throw new Error(`Unsupported data type: ${typeof element}`);
          }
        }

        return [numberArray, stringArray];
      }
      // Tree check事件
      const handleCheckClick = (checkedNodes, { halfCheckedKeys }) => {
        allCheckedKeys.value = [...checkedNodes, ...halfCheckedKeys];
        console.log('1111:', allCheckedKeys.value);
      };

      const getPermissionByRole = async (roleType: RoleEnum) => {
        try {
          const { key } = RoleMenuDictEnum[roleType];
          const res = await findDictItemByCode({ dictCode: key });
          return res.map((item) => item.itemValue);
        } catch (error) {}
        return [];
      };

      const getPermissionTreeData = (
        data: MenuRecord[],
        permissionKeys: string[],
        keysType: KeysTypeEnum
      ) => {
        const setDisabled = (data: MenuRecord[], flag: boolean) => {
          return data.map((item) => {
            item.name = t(item.name);
            if (item.children && item.children.length) {
              item.children = setDisabled(item.children, flag);
            }
            return {
              ...item,
              disabled: flag,
              icon: item.meta.icon,
            } as TreeData;
          });
        };

        const permissionCompare = (
          data: MenuRecord[],
          permissionKeys: string[],
          keysType: KeysTypeEnum
        ) => {
          return data.map((item) => {
            item.name = t(item.name);
            const findFlag = permissionKeys.includes(item.permission);
            if (findFlag) item.isDictCompareDisabled = true;
            const disabledFlag = keysType === KeysTypeEnum.DISABLED ? findFlag : !findFlag;
            item.disabled = disabledFlag;

            if (item.isDictCompareDisabled && item.children && item.children.length) {
              setDisabled(item.children, disabledFlag);
            } else {
              if (item.children && item.children.length) {
                item.children = permissionCompare(item.children, permissionKeys, keysType);
                item.disabled = item.children.every((temp) => temp.disabled);
              }
            }
            return {
              ...item,
              icon: item.meta.icon,
            } as TreeData;
          });
        };

        const result = permissionCompare(data, permissionKeys, keysType).map((item) => {
          if (item.children && item.children.length) {
            const rootDisabledFlag = item.children.every((temp) => temp.disabled);
            item.disabled = rootDisabledFlag;
          }
          return item;
        });

        return result;
      };
      const excludeHalfCheckedKeys = (treeData: MenuRecord[]) => {
        const needExcludeKeys: string[] = [];
        const query = (data: MenuRecord[]) => {
          data.forEach((item) => {
            item.checked = roleMenus.value.includes(item.id);
            if (item.children && item.children.length) {
              query(item.children);
              item.checked = item.children.every((item) => item.checked);
            }
            if (!item.checked) {
              needExcludeKeys.push(item.id);
            }
          });
        };
        query(treeData);
        roleMenus.value = unref(roleMenus).filter((key) => !needExcludeKeys.includes(key));
        return needExcludeKeys;
      };
      function filterOption(input, option) {
        return (
          option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
        );
      }

      function segmentsChange(val) {
        projectsOptions.value.map((e: any) => {
          if (val.includes(e.sshdid) && !formState.projects.includes(e.id)) {
            formState.projects.push(e.id);
          }
        });
        monitorsOptions.value.map((e: any) => {
          if (val.includes(e.sshdid) && !formState.monitors.includes(e.id)) {
            formState.monitors.push(e.id);
          }
        });

        multiDatasOptions.value.map((e: any) => {
          if (val.includes(e.sshdid) && !formState.multiDatas.includes(e.id)) {
            formState.multiDatas.push(e.id);
          }
        });
        monitorsChange(toRaw(formState).monitors);
      }
      function projectsChange(val) {
        monitorsOptions.value.map((e: any) => {
          if (val.includes(e.ssgcid) && !formState.monitors.includes(e.id)) {
            formState.monitors.push(e.id);
          }
        });
        multiDatasOptions.value.map((e: any) => {
          if (val.includes(e.ssgcid) && !formState.multiDatas.includes(e.id)) {
            formState.multiDatas.push(e.id);
          }
        });
        monitorsChange(toRaw(formState).monitors);
      }
      function monitorsChange(val) {
        console.log('monitorsChange', val);

        const data = findValuesByMonitorPointIds(TreeSelectData.value, val);
        const arr = formState.devices;
        arr.push(...data);

        formState.devices = Array.from(new Set(arr));
        console.log(formState.devices);
        TreeSelectChange(toRaw(formState).devices);
      }
      function findValuesByMonitorPointIds(data, monitorPointIds) {
        let values = [];

        function traverseNodes(node) {
          if (node.children && node.children.length > 0) {
            node.children.forEach((child) => traverseNodes(child));
          }

          if (node.monitorPointId && monitorPointIds.includes(parseInt(node.monitorPointId))) {
            values.push(node.value);
          }
        }

        traverseNodes({ children: data });

        return values;
      }
      function TreeSelectChange(val) {
        console.log(val);

        sensorsOptions.value.map((e: any) => {
          if (val.includes(e.deviceId) && !formState.sensors.includes(e.id)) {
            formState.sensors.push(e.id);
          }
        });
      }
      function sensorsChange(val) {}

      return {
        spinning,
        spinningT,
        registerDrawer,
        registerForm,
        getTitle,
        handleSubmit,
        treeData,
        roleMenus,
        treeRef,
        handleCheckClick,
        allCheckedKeys,
        activeKey,
        formState,
        filterOption,
        segmentsOptions,
        projectsOptions,
        monitorsOptions,
        devicesOptions,
        sensorsOptions,
        multiDatasOptions,
        isUpdate,
        TreeSelectData,
        segmentsChange,
        projectsChange,
        monitorsChange,
        TreeSelectChange,
        sensorsChange,
      };
    },
  });
</script>

<style scoped lang="less">
  :deep(.vben-basic-tree) {
    width: 100% !important;
  }

  :deep(.is-unflod) {
    display: none !important;
  }

  :deep(.is-flod) {
    display: none !important;
  }

  :deep(.ant-tabs-content-animated) {
    height: 500px;
  }
</style>
