<template>
  <div class="wrap-box" :style="{ ...getBoxStyle, ...style }">
    <template v-if="props.treeConfig.isMultiple">
      <a-directory-tree
        v-model:checkedKeys="checkedKeys"
        :selectable="false"
        :checkable="true"
        :tree-data="treeData"
        default-expand-all
        :show-icon="false"
        :height="treeState.height - 20"
        @check="checkItem"
        :disabled="disabled"
      >
        <template #title="item"> &nbsp;&nbsp;{{ item.label }} </template>
      </a-directory-tree>
    </template>
    <template v-else>
      <a-directory-tree
        v-model:selectedKeys="selectedKeys"
        :tree-data="treeData"
        default-expand-all
        :show-icon="false"
        :height="treeState.height - 20"
        :disabled="disabled"
        @select="selectItem"
      >
        <template #title="item"> &nbsp;&nbsp;{{ item.label }} </template>
      </a-directory-tree>
    </template>
  </div>
</template>
<script lang="ts" setup>
  import { onMounted, watch, ref, reactive, inject } from 'vue';
  import { getInfo } from '/@/api/system/generator/treeStructure';
  import { TreeStructureType } from '/@/enums/treeStructure';
  import { apiConfigFunc, isValidJSON } from '/@/utils/event/design';
  import { cloneDeep } from 'lodash-es';
  import { ApiItem } from '/@/model/generator/treeStructure';
  import { TreeProps } from 'ant-design-vue';

  const props = defineProps({
    value: String,
    defaultValue: String,
    disabled: Boolean,
    codeType: String,
    treeConfig: {
      type: Object,
      default: () => {},
    },
    style: Object,
  });
  const formModel = inject<any>('formModel', null);
  const emit = defineEmits(['update:value', 'change']);
  const checkedKeys = ref<string[] | number[]>([]);
  const selectedKeys = ref<string[] | number[]>([]);
  const getBoxStyle = ref();
  const treeData = ref<TreeProps['treeData']>([
    // {
    //   title: '0-0',
    //   key: '0-0',
    //   value: '0-0',
    //   label: '0-0',
    // },
  ]);
  const treeState = reactive({
    height: 600,
    treeDataMap: new Map(),
    loading: true,
  });

  watch(
    () => props.treeConfig.id,
    async (_val) => {
      initHeight(props.treeConfig.height);
      await getTreeData();
    },
  );
  watch(
    () => props.treeConfig.height,
    (val) => {
      initHeight(val);
    },
  );
  // watch(
  //   () => props.value,
  //   (_val) => {
  //     initData();
  //   },
  // );
  watch(
    () => props.treeConfig.isMultiple,
    async (_val) => {
      resetData();
    },
  );
  onMounted(async () => {
    initHeight(props.treeConfig.height);
    await getTreeData();
    initData();
  });
  function resetData() {
    let val = '';
    checkedKeys.value = [];
    selectedKeys.value = [];
    emit('update:value', val);
    emit('change', val);
  }
  function initHeight(height) {
    treeState.height = Number(height);
    let maxH = treeState.height;
    getBoxStyle.value = {
      maxHeight: height === '' ? 'none' : maxH + 'px',
      height:
        height === '0'
          ? 0
          : props.treeConfig.id && treeData.value && treeData.value.length > 0
          ? 'auto'
          : '32px',
      padding: height === '0' ? 0 : '10px',
    };
  }
  function initData() {
    if (props.value) {
      if (props.treeConfig.isMultiple) {
        let val = props.value.includes(',')
          ? props.value.split(',')
          : Array.isArray(props.value)
          ? props.value[0]
          : [];
        checkedKeys.value = val;
      } else {
        selectedKeys.value = Array.isArray(props.value) ? props.value[0] : [];
      }
    } else if (props.defaultValue) {
      if (props.treeConfig.isMultiple) {
        let val = props.defaultValue.split(',');
        checkedKeys.value = val;
      } else {
        selectedKeys.value = Array.isArray(props.defaultValue) ? props.defaultValue[0] : [];
      }
    }
  }
  async function getTreeData() {
    if (!props.treeConfig?.id) {
      return;
    }
    checkedKeys.value = [];
    selectedKeys.value = [];
    let formState = await getInfo(props.treeConfig?.id);
    let config = JSON.parse(formState.config);
    if (formState.type == TreeStructureType.STATIC) {
      // treeState.treeData = config.staticData;
      let data: Array<ApiItem> = [];
      config.staticData.forEach((element, index) => {
        let res = getItem(element, index, element.value);
        data.push(res);
      });
      treeData.value = data;
    } else {
      let data: Array<ApiItem> = [];

      config.apiData.apiConfig.apiParams = [
        { key: '1', title: 'Query Params', tableInfo: [] },
        { key: '2', title: 'Header', tableInfo: [] },
        { key: '3', title: 'Body', tableInfo: [] },
      ];
      if (config.apiData.apiConfig.requestParamsConfigs) {
        let temp: any = [];
        config.apiData.apiConfig.requestParamsConfigs.forEach((o) => {
          transferData(temp, o, 'requestParamsConfigs');
        });
        config.apiData.apiConfig.apiParams[0].tableInfo = temp;
      }
      if (config.apiData.apiConfig.requestHeaderConfigs) {
        let temp: any = [];
        config.apiData.apiConfig.requestHeaderConfigs.forEach((o) => {
          transferData(temp, o, 'requestHeaderConfigs');
        });
        config.apiData.apiConfig.apiParams[1].tableInfo = temp;
      }
      if (config.apiData.apiConfig.requestBodyConfigs) {
        let temp: any = [];
        config.apiData.apiConfig.requestBodyConfigs.forEach((o) => {
          transferData(temp, o, 'requestBodyConfigs');
        });
        config.apiData.apiConfig.apiParams[2].tableInfo = temp;
      }
      let apiData = await apiConfigFunc(config.apiData.apiConfig, false, formModel);
      let labelKey = config.apiData.apiColumns[0].dataIndex;
      let valueKey = config.apiData.apiColumns[1].dataIndex;
      apiData.data?.forEach((element) => {
        let res = getApiItem(element, labelKey, valueKey, element[valueKey]);
        data.push(res);
      });
      treeData.value = data;
    }
    setTreeDataMap(cloneDeep(treeData.value));
    initHeight(props.treeConfig.height);
    treeState.loading = false;
  }
  function transferData(temp, o, key) {
    if (o.assignmentType == 'value') {
      let obj = props.treeConfig?.innerParams.find((k) => k.key == key && k.name == o.name);
      let val = '';
      if (obj) {
        let value = isValidJSON(obj.bindComp);
        val = JSON.stringify({ bindField: value.field, fieldKey: value.key });
      }
      temp.push({
        bindType: 'data',
        dataType: o.dataType,
        name: o.name,
        type: null,
        value: val,
      });
    } else if (o.assignmentType == 'currentInfo') {
      temp.push({
        bindType: 'data',
        dataType: o.dataType,
        name: o.name,
        type: null,
        value: o.config,
      });
    }
  }
  function getApiItem(item, labelKey, valueKey, value): ApiItem {
    let childrenArr: Array<ApiItem> = [];
    if (item.children?.length > 0) {
      item.children.forEach((element) => {
        let value2 = props.treeConfig?.isSaveLast
          ? element[valueKey]
          : 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;
    return {
      ...otherParams,
      label: item[labelKey],
      key: value,
      children: childrenArr,
    };
  }
  function getItem(item, index, rowKey): ApiItem {
    let childrenArr: Array<ApiItem> = [];
    if (item.children?.length > 0) {
      item.children.forEach((element, index2) => {
        let key = index + '---' + index2;
        let rowKey2 = props.treeConfig?.isSaveLast ? element.value : rowKey + '---' + element.value;
        childrenArr.push(getItem(element, key, rowKey2));
      });
    }
    // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
    let { children, ...otherParams } = item;
    return {
      ...otherParams,
      label: item.label,
      index: index,
      key: rowKey,
      children: childrenArr,
    };
  }
  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 changeSelectIds(ids) {
    let val = '';
    if (ids.length > 0) {
      if (props.treeConfig.isMultiple) {
        val = Array.isArray(ids) ? ids.join(',') : ids;
      } else {
        val = Array.isArray(ids) ? ids[0] : ids;
      }
    }
    emit('update:value', val);
    emit('change', val);
  }
  function checkItem() {
    changeSelectIds(checkedKeys.value);
  }
  function selectItem() {
    changeSelectIds(selectedKeys.value);
  }
</script>
<style lang="less" scoped>
  .wrap-box {
    border: 1px solid #d9d9d9;
    border-radius: 4px;
    padding: 10px;
  }
</style>
