<template>
  <div class="wrap-box">
    <BasicTree
      v-bind="bindProps"
      search
      :switcher="getSwitcher"
      :clickRowToExpand="true"
      :treeData="treeData"
      :fieldNames="{
        key: 'key',
        title: 'label',
      }"
      @select="handleSelect"
    >
      <template #title="item">
        <template v-if="item.renderIcon === 'parentIcon' && options?.parentIcon">
          <Icon :icon="options?.parentIcon" />
        </template>
        <template v-if="item.renderIcon === 'childIcon' && options?.childIcon">
          <Icon :icon="options?.childIcon" />
        </template>
        {{ item.label }}
      </template>
    </BasicTree>
  </div>
</template>
<script lang="ts" setup>
  import { computed, inject, onMounted, ref, watch, watchEffect } from 'vue';
  import { BasicTree } from '/@/components/Tree';
  import { getInfo } from '/@/api/system/generator/treeStructure';
  import { TreeStructureType } from '/@/enums/treeStructure';
  import { apiConfigFunc } from '/@/utils/event/design';
  import Icon from '/@/components/Icon/index';

  import { getDicDetailList } from '/@/api/system/dic';
  import { ApiItem } from '../../types';
  const props = defineProps({
    options: {
      type: Object,
      defualt: () => {
        return {
          label: '',
          showLabel: true,
          treeConfig: {},
          datasourceType: 'static',
          apiConfig: {},
        };
      },
    },
    compkey: String,
  });
  const emit = defineEmits(['update:value', 'refreshComp', 'select', 'load', 'refresh']);
  const widgetFormModel = inject('widgetFormModel', ref<any>({}));
  const selectedKeys = ref<string[] | number[]>([]);
  const treeData = ref<ApiItem[]>([]);
  const bindProps = ref({});
  const level = ref(1);
  const getSwitcher = computed(() => {
    if (props.options?.datasourceType === 'dic') {
      return false;
    } else if (props.options?.datasourceType === 'api' && level.value === 1) {
      return false;
    } else if (props.options?.datasourceType === 'api' && level.value > 1) {
      return true;
    } else {
      return true;
    }
  });
  watchEffect(() => {
    fetch();
    emit('refresh');
  });
  watch(
    () => props.options?.showLabel,
    (val) => {
      if (val) {
        bindProps.value = { title: props.options?.label };
      } else {
        bindProps.value = {};
      }
    },
  );
  watch(
    () => props.options?.label,
    (val) => {
      if (props.options?.showLabel) {
        bindProps.value = { title: val };
      } else {
        bindProps.value = {};
      }
    },
  );
  onMounted(() => {
    if (props.options?.showLabel) {
      bindProps.value = { title: props.options?.label };
    } else {
      bindProps.value = {};
    }
    fetch();
    emit('load');
  });
  async function fetch() {
    treeData.value = [];
    if (props.options?.datasourceType === 'static') {
      await getTreeData();
    } else if (props.options?.datasourceType === 'api') {
      level.value = 1;
      treeData.value = await apiConfigFunc(props.options?.apiConfig, false, {});
      setIcon(treeData.value);
    } else if (props.options?.datasourceType === 'dic' && props.options?.dictionaryItemId) {
      let res = await getDicDetailList({ itemId: props.options.dictionaryItemId });
      res.forEach((o: any) => {
        treeData.value.push({ label: o.name, key: o.value, children: [], renderIcon: 'childIcon' });
      });
    }
  }
  function setIcon(list) {
    list.forEach((o) => {
      if (o.children?.length > 0) {
        level.value += 1;
        o.renderIcon = 'parentIcon';
        setIcon(o.children);
      } else {
        o.renderIcon = 'childIcon';
      }
    });
  }
  async function getTreeData() {
    if (!props.options?.treeConfig?.id) {
      return;
    }

    selectedKeys.value = [];

    let formState = await getInfo(props.options?.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> = [];
      let apiData = await apiConfigFunc(config.apiData.apiConfig, false, {});
      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));
  }
  function getApiItem(item, labelKey, valueKey, value): ApiItem {
    let childrenArr: Array<ApiItem> = [];
    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;
    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 = 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 handleSelect(selectIds, info) {
    let label = info.node.label.el.textContent.trim();
    if (props.compkey) widgetFormModel.value[props.compkey] = { value: selectIds, label };
    emit('refreshComp', selectIds);
    emit('select', selectIds);
  }
</script>
<style lang="less" scoped>
  .wrap-box {
    background-color: #fff;
    border-radius: 16px;
    height: 100%;
  }
</style>
