import { computed, ref } from 'vue';
import { fetchGetUserManagementRelationTree } from '@/service/api';
import type { TreeCheckState } from './use-dept-source';

type ChainNode = Api.SystemManage.UserManagementRelationTreeRespVO;

export function useChainSource(selectedIds: () => Set<string>, disabledUserIdSet: () => Set<string>) {
  const tree = ref<ChainNode[]>([]);
  const loading = ref(false);
  let loaded = false;

  async function ensureLoaded() {
    if (loaded) return;
    loading.value = true;
    try {
      const { data } = await fetchGetUserManagementRelationTree({ fromUserIndex: false });
      tree.value = data ?? [];
      loaded = true;
    } finally {
      loading.value = false;
    }
  }

  function nodeKey(node: ChainNode): string {
    return node.id ?? `chain_${node.userId}`;
  }

  function getNodeUserIds(node: ChainNode): string[] {
    const ids = new Set<string>([String(node.userId)]);
    if (node.children) {
      for (const c of node.children) {
        for (const id of getNodeUserIds(c)) ids.add(id);
      }
    }
    return [...ids];
  }

  function getNodeCheckState(node: ChainNode): TreeCheckState {
    const ids = getNodeUserIds(node).filter(id => !disabledUserIdSet().has(id));
    if (!ids.length) return 'none';
    const sel = ids.filter(id => selectedIds().has(id)).length;
    if (sel === 0) return 'none';
    if (sel === ids.length) return 'all';
    return 'partial';
  }

  function findNode(list: ChainNode[], key: string): ChainNode | null {
    for (const n of list) {
      if (nodeKey(n) === key) return n;
      if (n.children) {
        const r = findNode(n.children, key);
        if (r) return r;
      }
    }
    return null;
  }

  function matchKeyword(node: ChainNode, kw: string): boolean {
    if (!kw) return true;
    if (node.userNickname.toLowerCase().includes(kw)) return true;
    if (node.children) return node.children.some(c => matchKeyword(c, kw));
    return false;
  }

  function filterByKeyword(kw: string) {
    const lower = kw.trim().toLowerCase();
    if (!lower) return tree.value;
    return tree.value.filter(n => matchKeyword(n, lower));
  }

  function getMetaText(node: ChainNode): string {
    const total = getNodeUserIds(node).length;
    return total > 1 ? `${total} 人` : '';
  }

  const treeProps = computed(() => ({ children: 'children', label: 'userNickname' }) as const);

  return {
    tree,
    loading,
    treeProps,
    ensureLoaded,
    getNodeUserIds,
    getNodeCheckState,
    findNode,
    filterByKeyword,
    getMetaText,
    nodeKey
  };
}
