import type { TreeDataNode } from 'antd';
import lodash from 'lodash';

/**
 * 生成树结构
 * @param list 带parentId属性的列表
 * @param parentId 父ID
 * @param mapping 自定义节点数据映射函数
 * @returns 树节点数据
 */
export function buildTreeData(
    list: DICTS.ParentTreeNode[],
    parentId: number | string = 0,
    mapping?: (item: any) => DICTS.ParentTreeNode,
): DICTS.ParentTreeNode[] {
    const nodes: DICTS.ParentTreeNode[] = [];
    list.filter((item) => item.pid === parentId).forEach((item) => {
        let node = { ...item };
        if (mapping) {
            node = mapping(node);
        }
        if (list.filter((t) => t.pid === item.id).length > 0) {
            node.children = buildTreeData(list, item.id, mapping);
        } else {
            node.isLeaf = true;
        }

        nodes.push(node);
    });
    return nodes;
}

/**
 * 生成树节点
 * @param list
 * @param pid
 * @param mapping
 * @returns
 */
export function buildTreeNodes<TData = any>(
    list: DICTS.ParentTreeNode[],
    pid: number | string = 0,
    mapping?: (item: any) => TreeDataNode,
): (TreeDataNode & { data: TData })[] {
    const nodes: (TreeDataNode & { data: TData })[] = [];
    list.filter((item) => item.pid === pid).forEach((item) => {
        let node = {
            key: item.id,
            title: item.name,
            isLeaf: false,
            data: item
        } as TreeDataNode;
        if (mapping) {
            node = mapping({ ...item, ...node });
        }
        if (list.filter((t) => t.pid === item.id).length > 0) {
            node.children = buildTreeNodes(list, item.id, mapping);
        } else {
            node.isLeaf = true;
        }

        nodes.push(node as TreeDataNode & { data: TData });
    });
    return nodes;

    // checkable?: boolean;
    // children?: DataNode[];
    // disabled?: boolean;
    // disableCheckbox?: boolean;
    // icon?: IconType;
    // isLeaf?: boolean;
    // key: string | number;
    // title?: React.ReactNode;
    // selectable?: boolean;
    // switcherIcon?: IconType;
    // /** Set style of TreeNode. This is not recommend if you don't have any force requirement */
    // className?: string;
    // style?: React.CSSProperties;
}

/**
 * 生成树形表数据
 * @param list
 * @param parentId
 * @param mapping
 * @returns
 */
export function buildTableTreeData(
    list: any[],
    idKey: string = 'id',
    parentKey: string = 'pid',
    parentId: number | string = 0,
    mapping?: (item: any) => any,
): any[] {
    const nodes: any[] = [];
    list.filter((item) => item[parentKey] === parentId).forEach((item) => {
        let node = { ...item };
        if (mapping) {
            node = mapping(node);
        }
        if (list.filter((t) => t[parentKey] === item[idKey]).length > 0) {
            node.children = buildTableTreeData(list, idKey, parentKey, item[idKey], mapping);
        }

        nodes.push(node);
    });
    return nodes;
}

/**
 * 生成树形表数据（自动设置顶级节点）
 * @param list 
 * @param idKey 
 * @param parentKey 
 * @param mapping 
 * @returns 
 */
export function buildTableTreeData2(
    list: any[],
    idKey: string = 'id',
    parentKey: string = 'pid',
    mapping?: (item: any) => any,
): any[] {
    const slist = list.map((t, i) => ({ ...t, _treeOrginSort: i }));
    const parentId = lodash.min(slist.map(t => t.pid));
    const plist = buildTableTreeData(slist, idKey, parentKey, parentId, mapping);
    let hids: any[] = [];
    const getIds = (pls: any[]) => {
        pls.forEach((t: any) => {
            hids.push(t.id);
            if (t.children) {
                getIds(t.children);
            }
        });
    }
    getIds(plist);
    const tlist = slist.filter(t => !hids.includes(t.id)).map(t => ({ ...t }));
    return [...plist, ...tlist].sort((a, b) => a._treeOrginSort - b._treeOrginSort);
}

export function getParentPath(
    list: any[],
    idKey: string = 'id',
    parentKey: string = 'parentId',
    id: number | string = 0,
    mapping?: (item: any) => any,
) {
    let nodes: any[] = [];
    const c = list.find((item) => item[idKey] === id);
    if (c) {
        let node = { ...c };
        if (mapping) {
            node = mapping(node);
        }
        nodes.splice(0, 1, node);
        const p = list.find((item) => item[idKey] === c[parentKey]);
        if (p) {
            const ps = getParentPath(list, idKey, parentKey, c[parentKey], mapping);
            nodes = [...ps, ...nodes];
        }
    }
    return nodes;
}

/**
 * 转换为选项
 * @param list 列表
 * @param mapping 自定义映射函数
 * @returns 选项列表
 */
export function toSelectOptions(
    list?: any[],
    mapping?: (item: any) => DICTS.SelectOptionItem,
): DICTS.SelectOptionItem[] {
    if (!list) {
        return [];
    }
    const items: DICTS.SelectOptionItem[] = [];
    if (mapping) {
        for (const item of list) {
            items.push(mapping(item));
        }
    } else {
        for (const item of list) {
            items.push({
                key: item.id,
                value: item.id,
                label: item.name,
            });
        }
    }
    return items;
}

/**
 * 列表转valueEnum
 * @param list 
 * @returns 
 */
export function toValueEnum(list: any[]) {
    if (!list || list.length === 0) {
        return {};
    }
    let items: Record<string | number, { text: string, status?: string }> = {};
    list.forEach(t => {
        items[t.id as number] = { text: t.name };
    });
    return items;
}

/**
 * 转换为以ID为键的字典
 * @param list 列表
 * @returns
 */
export function toIdKeyDict(list: any[]) {
    const dict: { [key: string]: any;[key: number]: any } = {};
    let id = 1;
    for (const item of list) {
        const opt = { id: id++, ...item };
        dict[opt.id] = opt;
    }
    return dict;
}

/**
 * 数字索引转EXCEL列名
 * @param index 索引号
 * @returns 
 */
export function toExcelColumnName(index: number) {
    let num = index;

    const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    let str = "";

    while (num >= 0) {
        const n = letters[num % 26];
        str = `${n}${str}`;
        if (num === 0) {
            break;
        }
        num = Math.floor(num / 26) - 1;
    }

    return str;
}