<!-- eslint-disable @typescript-eslint/no-unused-vars -->
<template>
  <div class="bg-color">
    <div class="vben-tree-header flex px-2 py-2 items-center justify-between header pd">
      <span class="vben-basic-title">{{ formState.name }}</span>
      <div class="cursor-pointer">
        <Preview
          :formState="formState"
          v-model:checkedKeys="checkedKeys"
          :type="props.treeConfig?.isMultiple ? 'checkbox' : 'radio'"
          >展开</Preview
        >
      </div>
    </div>
    <div class="tree-box" v-if="treeState.treeData && treeState.treeData?.length > 0">
      <template v-if="props.treeConfig.isMultiple">
        <a-directory-tree
          v-model:checkedKeys="checkedKeys"
          :selectable="false"
          :checkable="true"
          :tree-data="treeState.treeData"
          show-icon
          default-expand-all
          @check="checkItem"
        >
          <template #icon="{ key }">
            <template v-if="key && (key + '').includes('-')">
              <Icon v-if="formState.childIcon" :icon="formState.childIcon" />
              <Icon v-else icon="ant-design:file-outlined" />
            </template>
            <template v-else>
              <Icon v-if="formState.parentIcon" :icon="formState.parentIcon" />
              <Icon v-else icon="ant-design:folder-open-twotone" />
            </template>
          </template>
          <template #title="item"> &nbsp;&nbsp;{{ item.label }} </template>
        </a-directory-tree>
      </template>
      <template v-else>
        <a-directory-tree
          v-model:selectedKeys="selectedKeys"
          :tree-data="treeState.treeData"
          show-icon
          default-expand-all
        >
          <template #icon="{ key }">
            <template v-if="key && (key + '').includes('-')">
              <Icon v-if="formState.childIcon" :icon="formState.childIcon" />
              <Icon v-else icon="ant-design:file-outlined" />
            </template>
            <template v-else>
              <Icon v-if="formState.parentIcon" :icon="formState.parentIcon" />
              <Icon v-else icon="ant-design:folder-open-twotone" />
            </template>
          </template>
          <template #title="item"> &nbsp;&nbsp;{{ item.label }} </template>
        </a-directory-tree>
      </template>
    </div>
  </div>
</template>

<script setup lang="ts">
  import { ref, watch, onMounted, reactive } from 'vue';
  import type { TreeProps } from 'ant-design-vue';
  import { TreeStructureType } from '/@/enums/treeStructure';
  import { apiConfigFunc } from '/@/utils/event/design';
  import { getInfo } from '/@/api/system/generator/treeStructure';
  import Preview from './Preview.vue';
  import Icon from '/@/components/Icon/index';
  import {
    ApiItem,
    TreeConfigColumn,
    TreeStructureFormState,
  } from '/@/model/generator/treeStructure';
  const props = defineProps({
    treeConfig: Object as () => TreeConfigColumn,
  });
  const treeState = reactive({
    checkable: false as Boolean,
    treeData: [] as TreeProps['treeData'],
    treeDataMap: new Map(),
  });
  const emits = defineEmits(['select']);
  const formState: TreeStructureFormState = reactive({
    key: '',
    code: '',
    name: '',
    remark: '',
    parentIcon: '',
    childIcon: '',
    type: TreeStructureType.STATIC,
    columns: [],
    config: {
      staticData: [],
      apiData: {
        apiConfig: {
          id: '',
          name: '',
          method: '',
          requestParamsConfigs: [], //Query Params
          requestHeaderConfigs: [], //Header
          requestBodyConfigs: [], //Body
        },
        apiColumns: [],
        data: [],
      },
    },
  });
  onMounted(async () => {
    treeState.checkable =
      props.treeConfig?.isMultiple != undefined ? props.treeConfig?.isMultiple : false;
    await setTreeInfo();
  });
  async function setTreeInfo() {
    if (props.treeConfig?.isMultiple == undefined) {
      return;
    }
    let res = await getInfo(props.treeConfig?.id);
    formState.key = props.treeConfig.id;
    if (res.code) formState.code = res.code;
    if (res.name) formState.name = res.name;
    if (res.remark) formState.remark = res.remark;
    if (res.parentIcon) formState.parentIcon = res.parentIcon;
    if (res.childIcon) formState.childIcon = res.childIcon;
    formState.type = res.type;
    if (formState.type == TreeStructureType.STATIC) {
      if (res.config) {
        let configObj = JSON.parse(res.config);
        formState.config.staticData = configObj.staticData;
      }
      if (res.columns) {
        let columnsObj = JSON.parse(res.columns);
        formState.columns = columnsObj;
      }
    } else {
      if (res.config) {
        let configObj = JSON.parse(res.config);
        formState.config.apiData.apiConfig = configObj.apiData.apiConfig;
        formState.config.apiData.apiColumns = configObj.apiData.apiColumns;
      }
    }
    getTreeData();
  }
  async function getTreeData() {
    if (formState.type == TreeStructureType.STATIC) {
      treeState.treeData = formState.config.staticData;
      setTreeDataMap(formState.config.staticData);
    } else {
      let data: Array<ApiItem> = [];
      let apiData = await apiConfigFunc(formState.config.apiData.apiConfig, false, {});
      let labelKey = formState.config.apiData.apiColumns[0].dataIndex;
      let valueKey: string = formState.config.apiData.apiColumns[1].dataIndex
        ? formState.config.apiData.apiColumns[1].dataIndex
        : '';
      apiData.data.forEach((element) => {
        let res = getApiItem(element, labelKey, valueKey, element[valueKey]);
        data.push(res);
      });
      treeState.treeData = data;
      formState.config.apiData.data = data;
      setTreeDataMap(data);
    }
  }
  function setTreeDataMap(treeData) {
    if (treeData) {
      treeData.forEach((element) => {
        setTreeMapItem(element);
      });
    }
  }
  function setTreeMapItem(item) {
    if (item.children.length > 0) {
      item.children.forEach((element) => {
        setTreeMapItem(element);
      });
    }
    // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
    let { children, ...otherParams } = item;
    treeState.treeDataMap.set(item.key, otherParams);
  }
  function getApiItem(item, labelKey, valueKey, value): ApiItem {
    let childrenArr: Array<ApiItem> = [];
    let myValue = {};
    if (item.children.length > 0) {
      item.children.forEach((element) => {
        let value2 = value + '---' + element[valueKey];
        childrenArr.push(getApiItem(element, labelKey, valueKey, value2));
      });
    }
    // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
    let { children, ...otherParams } = item;
    myValue[valueKey] = value;
    return {
      ...otherParams,
      label: item[labelKey],
      ...myValue,
      key: value,
      children: childrenArr,
    };
  }
  function changeSelectIds(ids) {
    let returnData: Array<{ [x: string]: string }> = [];
    ids.forEach((id) => {
      let selectObj: { [x: string]: string } = {};
      let item = treeState.treeDataMap.get(id);
      props.treeConfig?.config.forEach((element) => {
        selectObj[element.bindFiled] = item[element.value];
      });
      returnData.push(selectObj);
    });
    emits('select', returnData);
  }
  const checkedKeys = ref<string[] | number[]>([]);
  const selectedKeys = ref<string[] | number[]>([]);
  watch(checkedKeys, () => {
    changeSelectIds(checkedKeys.value);
  });
  watch(selectedKeys, () => {
    changeSelectIds(selectedKeys.value);
  });
  function checkItem(item) {
    checkedKeys.value = item;
  }
</script>

<style lang="less" scoped>
  .bg-color {
    background-color: #fff;
    height: 100%;
    border-radius: 16px;
  }

  .pd {
    padding: 16px 8px;
  }

  .app-iconify {
    margin-top: 10px;
  }

  .tree-box {
    height: calc(100% - 55px);
    border-radius: 0 0 16px 16px;
    overflow: auto;
  }
</style>
