import { MyResponseType } from '@/common';
import { Tree, TreeProps } from 'antd';
import { DataNode } from 'antd/es/tree';
import { Key, useEffect, useState } from 'react';

interface PermissionTreeProps
  extends Omit<TreeProps, 'treeData' | 'onCheck' | 'checkedKeys'> {
  api: () => Promise<MyResponseType>;
  value?: Key[];
  onChange?: (value: Key[]) => void;
}

export default function PermissionTree({
  api,
  value,
  onChange,
  ...rest
}: PermissionTreeProps) {
  const [treeData, setTreeData] = useState<DataNode[]>([]);
  const [expandedKeys, setExpandedKeys] = useState<Key[]>([]);

  const processTree = (item: any): DataNode => {
    return {
      key: item.id,
      title: item.name,
      children: item.children?.map(processTree),
    };
  };

  const collectLeafKeys = (nodes: DataNode[]): Key[] => {
    const keys: Key[] = [];
    nodes.forEach((node) => {
      if (!node.children || node.children.length === 0) {
        keys.push(node.key);
      } else {
        keys.push(...collectLeafKeys(node.children));
      }
    });
    return keys;
  };

  useEffect(() => {
    api().then((res: any) => {
      const data = res.data?.map(processTree) || [];
      setTreeData(data);
      setExpandedKeys(data.map((node: DataNode) => node.key));
    });
  }, [api]);

  const leafKeys = collectLeafKeys(treeData);

  const onCheck: TreeProps['onCheck'] = (_, info) => {
    const ids: Key[] = [];
    info.checkedNodes?.forEach((item: any) => {
      if (!item.children || item.children.length === 0) {
        ids.push(item.key);
      }
    });
    onChange?.(ids);
  };

  const checkedKeys = (value ?? []).filter((v) => leafKeys.includes(v));

  return (
    <Tree
      checkable
      showLine
      treeData={treeData}
      expandedKeys={expandedKeys}
      onExpand={(keys) => setExpandedKeys(keys)}
      checkedKeys={checkedKeys}
      onCheck={onCheck}
      {...rest}
    />
  );
}
