import { computed, ref } from 'vue';
import { fetchGetDeptSimpleList } from '@/service/api';
import { buildMenuTree } from '@/views/system/shared/menu-tree';

export type TreeCheckState = 'none' | 'partial' | 'all';

export function useDeptSource(
  userOptions: () => Api.SystemManage.UserSimple[],
  selectedIds: () => Set<string>,
  disabledUserIdSet: () => Set<string>
) {
  const tree = ref<Api.SystemManage.DeptSimple[]>([]);
  const loading = ref(false);
  let loaded = false;

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

  function collectDeptIds(node: Api.SystemManage.DeptSimple): string[] {
    const ids: string[] = [String(node.id)];
    if (node.children) {
      for (const c of node.children) ids.push(...collectDeptIds(c));
    }
    return ids;
  }

  function getNodeUserIds(node: Api.SystemManage.DeptSimple): string[] {
    const deptIds = new Set(collectDeptIds(node));
    return userOptions()
      .filter(u => u.deptId !== null && u.deptId !== undefined && deptIds.has(String(u.deptId)))
      .map(u => String(u.id));
  }

  function getNodeCheckState(node: Api.SystemManage.DeptSimple): 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: Api.SystemManage.DeptSimple[], key: string): Api.SystemManage.DeptSimple | null {
    for (const n of list) {
      if (String(n.id) === key) return n;
      if (n.children) {
        const r = findNode(n.children, key);
        if (r) return r;
      }
    }
    return null;
  }

  function matchKeyword(node: Api.SystemManage.DeptSimple, kw: string): boolean {
    if (!kw) return true;
    if (node.name.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: Api.SystemManage.DeptSimple): string {
    const total = getNodeUserIds(node).length;
    return total > 0 ? `${total} 人` : '';
  }

  function nodeKey(node: Api.SystemManage.DeptSimple): string {
    return String(node.id);
  }

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

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