<template>
  <div class="tree-content">
    <div class="tree-header">
      <div>数据源</div>
      <Checkbox v-model:checked="isSelected">隐藏已有节点</Checkbox>
    </div>
    <Spin :spinning="spinning">
      <Tree
        v-if="!!treeData"
        :load-data="onLoadData"
        :tree-data="treeData"
        v-model:checkedKeys="checkedKeys"
        :selectedKeys="selectedKeys"
        :selectable="false"
        checkable
        @check="onCheck"
        :height="600"
        :showLine="{ showLeafIcon: false }"
        :show-icon="true"
      >
        <template #title="{ name, key }">
          <span :class="[selectKeys.includes(key) ? 'tree-selected' : 'tree-title']">
            {{ name }}
          </span>
        </template>
      </Tree>
      <Empty v-else style="margin-top: 22%" />
    </Spin>
  </div>
</template>

<script lang="ts" setup>
  import { ref, watch, onMounted } from 'vue';
  import type { TreeProps } from 'ant-design-vue';
  import { scanOpcUAList, queryPointNoPaging } from '../../../../../api/data-collect/collector';
  import { cloneDeep } from 'lodash-es';
  // @ts-ignore
  import { Checkbox, Tree, Spin, Empty } from 'linker-ui-components';

  const props = defineProps({
    data: {
      type: Array,
      default: () => []
    },
    unSelectKeys: {
      type: String,
      default: ''
    }
  });
  const emits = defineEmits(['change']);

  const channelId = props.data?.channelId;
  const checkedKeys = ref<string[]>([]);
  const selectKeys = ref<string[]>([]);
  const spinning = ref(false);

  const isSelected = ref(false);
  const treeData = ref<TreeProps['treeData']>();
  const treeAllData = ref<TreeProps['treeData']>();

  const onLoadData = (node: any) =>
    new Promise<void>(async (resolve) => {
      if ((node?.children && node.children?.length) || !node?.folder) {
        resolve();
        return;
      }
      const resp: any = await scanOpcUAList({
        id: channelId,
        nodeId: node.key
      });
      if (resp.code === 200) {
        const list: any = resp.result.map((item: any) => {
          return {
            ...item,
            key: item.id,
            title: item.name,
            disabled: item?.folder,
            isLeaf: !item?.folder
          };
        });

        treeAllData.value = updateTreeData(cloneDeep(treeAllData.value), node.key, [...list]);
      }
      resolve();
    });

  const handleData = (arr: any): any[] => {
    const data = arr.filter((item: any) => {
      return (isSelected.value && !selectKeys.value.includes(item.id)) || !isSelected.value;
    });
    return data.map((item: any) => {
      if (item.children && item.children?.length) {
        return {
          ...item,
          children: handleData(item.children)
        };
      } else {
        return item;
      }
    });
  };

  const onCheck = (checkedKeys: any, info: any) => {
    const one: any = { ...info.node };
    const list: any = [];
    const last: any = list.length ? list[list.length - 1] : undefined;
    if (list.map((i: any) => i?.id).includes(one.id)) {
      return;
    }
    const item = {
      features: {
        value: last ? last?.features?.value : (one?.features || []).includes('changedOnly'),
        check: true
      },
      id: one?.id || '',
      name: one?.name || '',
      accessModes: {
        value: last ? last?.accessModes?.value : one?.accessModes || [],
        check: true
      },
      type: one?.type,
      configuration: {
        ...one?.configuration,
        interval: {
          value: last ? last?.configuration?.interval?.value : one?.configuration?.interval || 3000,
          check: true
        },
        nodeId: one?.id
      }
    };
    emits('change', item, info.checked);
  };

  const updateTreeData = (list: any, key: string, children: any[]): any[] => {
    const arr = list.map((node: any) => {
      if (node.key === key) {
        return {
          ...node,
          children
        };
      }
      if (node?.children && node?.children?.length) {
        return {
          ...node,
          children: updateTreeData(node.children, key, children)
        };
      }
      return node;
    });
    return arr;
  };

  const getPoint = async () => {
    spinning.value = true;
    const res: any = await queryPointNoPaging({
      paging: false,
      terms: [
        {
          terms: [
            {
              column: 'collectorId',
              value: props.data?.id
            }
          ]
        }
      ]
    });
    if (res.status === 200) {
      selectKeys.value = res.result.map((item: any) => item.pointKey);
    }
    getScanOpcUAList();
    spinning.value = false;
  };

  onMounted(() => {
    getPoint();
  });

  const getScanOpcUAList = async () => {
    spinning.value = true;
    const res: any = await scanOpcUAList({ id: channelId });
    treeAllData.value = res.result.map((item: any) => ({
      ...item,
      key: item.id,
      title: item.name,
      disabled: item?.folder || false
    }));
    spinning.value = false;
  };
  // getScanOpcUAList();

  watch(
    () => isSelected.value,
    (value) => {
      treeData.value = value ? handleData(treeAllData.value) : treeAllData.value;
    },
    { deep: true }
  );
  watch(
    () => treeAllData.value,
    (value) => {
      treeData.value = isSelected.value ? handleData(value) : value;
    },
    { deep: true }
  );

  watch(
    () => props.unSelectKeys,
    (value) => {
      checkedKeys.value = checkedKeys.value.filter((i) => i !== value);
    },
    { deep: true }
  );
</script>

<style lang="less" scoped>
  .tree-content {
    padding: 16px;
    padding-left: 0;
    min-width: 180px;
    .tree-header {
      margin-bottom: 16px;
      display: flex;
      justify-content: space-between;
    }
    .tree-selected {
      padding: 2px 5px;
      background-color: #d6e4ff;
      border-radius: 2px;
    }
    .tree-title {
      color: black;
    }
  }
</style>
