/*
 * @Author: code4eat awesomedema@gmail.com
 * @Date: 2024-03-19 10:27:43
 * @LastEditors: code4eat awesomedema@gmail.com
 * @LastEditTime: 2024-10-12 15:40:45
 * @FilePath: /CostAccountingSys/src/components/KCIMLeftList/index.tsx
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

import { createFromIconfontCN } from '@ant-design/icons';
import Dropdown from '@ant-design/pro-table/es/components/Dropdown';
import { Input, Tooltip, TreeProps, Empty } from 'antd'
import { Key, useEffect, useState } from 'react';
import DirectoryTree from 'antd/es/tree/DirectoryTree';
import { DataNode } from 'antd/es/tree';

import './style.less';


const IconFont = createFromIconfontCN({
    scriptUrl: '',
});


interface ListItem {
    name: string,
    subText: string,
    [key: string]: any
}

interface TreeNodeItem {
    [key: string]: any
}

export interface KCIMLeftListProps {
    dataSource?: any[],
    searchKey: string,
    placeholder?: string,
    listType?: 'list' | 'tree',
    icon?: string,
    contentH?: number|string,
    rowKey?: string,
    fieldNames?: { title?: string, key?: string, children?: string },
    onChange?: (selectedItem: ListItem) => void
}


function searchTreeAndKeepHierarchy(tree: any[], keyword: string, searchKey: string, childrenKeyName: string) {
    const children = childrenKeyName?childrenKeyName:'children'
    function search(node: any) {
        // 深度复制节点，避免修改原始树
        let newNode = { ...node };

        // 忽略大小写进行匹配
        const keywordLower = keyword.toLowerCase();
        const nodeKeyLower = node[`${searchKey}`].toLowerCase();

        // 首先检查当前节点是否匹配
        const isMatch = nodeKeyLower.includes(keywordLower);

        // 递归检查子节点
        if (node[`${children}`] && node[`${children}`].length > 0) {
            let filteredChildren = node[`${children}`].map(search).filter((child: any) => child !== null);

            if (filteredChildren.length > 0) {
                // 如果有子节点匹配，保留当前节点，并仅保留匹配的子节点
                newNode[`${children}`] = filteredChildren;
                return newNode;
            }
        }

        // 如果当前节点匹配，返回该节点及其所有子节点
        if (isMatch) {
            return newNode;
        }

        // 如果既不匹配当前节点，也没有匹配的子节点，返回 null
        return null;
    }

    // 对树的每个根节点进行搜索，并过滤掉不匹配的节点
    return tree.map(search).filter(node => node !== null);
}





const findFirstLeafNodeWithParents: any = (node: any, children: string) => {
    // 定义一个内部递归函数来处理节点和跟踪父节点
    const findNode: any = (currentNode: any, parents: any[]) => {

        // 检查当前节点是否为叶子节点（无子节点或子节点为空数组）
        if (!currentNode[children] || currentNode[children].length === 0) {
            return { leafNode: currentNode, parents };
        }

        // 添加当前节点到父节点列表
        parents.push(currentNode);

        // 递归查找第一个子节点的第一个叶子节点
        return findNode(currentNode[children][0], parents);
    };

    // 调用内部函数，初始父节点列表为空
    return findNode(node, []);
}





export const KCIMLeftList = (props: KCIMLeftListProps) => {

    const { searchKey, placeholder = '请输入', onChange, listType = 'list', dataSource: data = [], icon, contentH = 500, rowKey = 'id', fieldNames = { title: 'title', key: 'key', children: 'children' } } = props;
    
    const [dataSource, set_dataSource] = useState<ListItem[] | TreeNodeItem[]>([]);
    const [showList, set_showList] = useState<ListItem[] | TreeNodeItem[]>([]);
    const [currentSelected, set_currentSelected] = useState<undefined | any>(undefined);
    const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
    const [autoExpandParent, setAutoExpandParent] = useState(true);
    const [defaultSelectedKeys, set_defaultSelectedKeys] = useState<Key[]>([]);

    const onSelect: TreeProps['onSelect'] = (selectedKeys, info) => {
        // console.log('selected', selectedKeys, info);
        const { node } = info;
        if (!node[fieldNames.children as keyof typeof node] || (node[fieldNames.children as keyof typeof node] as any[]).length === 0) {
            set_currentSelected(node);
        }
        
    };

    const onExpand = (newExpandedKeys: React.Key[]) => {
        setExpandedKeys(newExpandedKeys);
        setAutoExpandParent(false);
    };


    useEffect(() => {
        onChange && onChange(currentSelected);
    }, [currentSelected])

    useEffect(() => {
        if (showList.length > 0) {
            if (listType == 'list') {
                set_currentSelected(showList[0]);
            }
            if (listType == 'tree') {
                const result = findFirstLeafNodeWithParents(showList[0], fieldNames.children ? fieldNames.children : 'children');
                // console.log({ result });
        
                setExpandedKeys([...(result.parents.map((parent:any) => parent[fieldNames.key as string]))]);
                set_currentSelected(result.leafNode);
                set_defaultSelectedKeys([result.leafNode[`${fieldNames.key}`]]);
            }

        } else {
            set_currentSelected(undefined);
        }
    }, [showList]);


    useEffect(() => {
        set_dataSource([...data]);
        set_showList([...data]);
    }, [data]);


    return (
        <div className="KCIMLeftList">
            <div className='toolbar'>
                <Input placeholder={placeholder} allowClear autoComplete='off'
                    suffix={
                        <IconFont style={{ color: '#99A6BF' }} type="iconsousuo" />
                    }
                    // style={{ width: 156 }}
                    onChange={(e) => {
                        if (listType == 'list') {
                            const result = dataSource.filter(item => item[`${searchKey}`].indexOf(e.target.value) != -1);
                            set_showList(result);
                        }
                        if (listType == 'tree') {
                            const result = searchTreeAndKeepHierarchy(dataSource, e.target.value, searchKey, fieldNames.children as string);
                          
                            set_showList(result);
                        }

                    }}

                />
                {/* <UpDataActBtn key={'act'} record={undefined} type='ADD_LEFTDATA' /> */}

            </div>
            <div className='wrap' style={{ height: contentH, overflow: 'scroll' }}>
                {
                    listType == 'list' && showList.map((item, index) => {
                        return (
                            <div className={currentSelected ? currentSelected[`${rowKey}`] == item[`${rowKey}`] ? 'list on' : 'list' : 'list'}
                                key={index}
                                onClick={() => {
                                    set_currentSelected(item);

                                    // _currentSelectedType = item;
                                }}
                            >
                                {/* <img className='icon' src={icon ? icon : require('../../../static/departmentIcon.png')} alt="" /> */}
                                <div className='content'>
                                    <Tooltip title={item.subText} >
                                        <div className='name'>{item.name}</div>
                                        <div className='sub'>{item.subText}</div>
                                    </Tooltip>
                                </div>

                                {/* <Dropdown menu={{ items: moreItems }} placement="bottom" onOpenChange={(bool) => { bool && set_currentEditLeftData(item) }}>
                                        <div className='more'>
                                            <img src={require('../../../../../static/more_point_gray.png')} alt="" />
                                        </div>
                                    </Dropdown> */}
                            </div>
                        )
                    })
                }

                {
                    (!showList || showList.length == 0) && (
                        <div><Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /></div>
                    )
                }

                {
                    listType == 'tree' && showList.length > 0 && currentSelected && defaultSelectedKeys.length > 0 && (
                        <DirectoryTree
                            className='KC-DirectoryTree'
                            fieldNames={fieldNames}
                            rootStyle={{paddingBottom:0,}}
                            onSelect={onSelect}
                            onExpand={onExpand}
                            expandedKeys={expandedKeys}
                            autoExpandParent={autoExpandParent}
                            selectedKeys={[currentSelected[`${fieldNames.key}`]]}
                            blockNode={true}
                            icon={() => null}
                            titleRender={
                                (nodeData: any) => {
                                    // console.log({nodeData});
                                    const strTitle = nodeData.name as string;
                                    const title = <span className='strTitle' style={{
                                        display: 'flex', flexDirection: 'row',
                                        width: '100%',
                                        justifyContent: 'flex-start', alignItems: 'center', height: 32,
                                        borderRadius: '4px',
                                        // overflow: 'hidden',
                                        color: '#17181A',
                                        textOverflow: 'ellipsis',
                                        whiteSpace: 'nowrap'

                                    }}>{strTitle}</span>;
                                    return title
                                }
                            }
                            // defaultSelectedKeys={['B0100']}
                            treeData={showList as unknown as DataNode[]}
                            // treeData={treeDataNew}
                            switcherIcon={(props: any) => {
                                const { expanded } = props;
                                return <IconFont style={{fontSize:16,position:'relative',top:2}} type={expanded?'icon-shouqi1':'icon-zhankai1'} />
                            }}
                        />
                    )
                }
            </div>

        </div>
    )
}