// 定义 TreeViewListItem 和 TreeViewListItemLeaf 接口
interface TreeViewListItem {
    IsExpanded: boolean;
    Items: ItemCollection;
    Parent: TreeViewListItem | null;
    NodeLevel: number;
    ParentLevel: number;
    Visibility: string;
    StyleNumber: number;
    Width: number;
    DescriptionName: string;
    // 假设这些静态方法存在
    static SetCheckBoxVisibility(item: TreeViewListItem, visibility: string): void;
    static GetIsChecked(item: TreeViewListItem): boolean;
    static SetIsChecked(item: TreeViewListItem, value: boolean): void;
}

interface TreeViewListItemLeaf extends TreeViewListItem {
    MenuCode: string;
}

interface ItemCollection extends Array<TreeViewListItem> { }

// 定义 TreeViewSource 类
class TreeViewSource {
    GetMenuTreeListByXML(rootNode: any): TreeViewListItem[] | null {
        // 实现从 XML 加载数据的逻辑
        return null;
    }

    GetMenuTreeListByDataTable(menuTable: any): TreeViewListItem[] | null {
        // 实现从数据库表加载数据的逻辑
        return null;
    }
}

// 定义 TreeViewList 类
export class TreeViewList {
    // 日志记录器
    log: any;
    // 路由事件
    ItemExpandedEvent: string = "ItemExpanded";
    ItemVisibiltyEvent: string = "ItemVisibilty";
    MouseLeftClickItemEvent: string = "MouseLeftClickItem";
    MouseRightClickItemEvent: string = "MouseRightClickItem";
    MouseDoubleClickItemEvent: string = "MouseDoubleClickItem";
    MouseAfterCheckItemEvent: string = "MouseAfterCheckItem";
    // 事件处理函数
    private eventHandlers: { [key: string]: Function[] } = {};
    // 依赖属性
    SearchBoxIsNotNull: boolean = false;
    IsShowCheckBox: boolean = false;
    IsAllExpanded: boolean = true;
    IsAllChecked: boolean = false;
    IsMouseRightClickSelected: boolean = true;
    StyleNumber: number = 0;
    ItemsVisibility: string = "Visible";
    SearchedTrades: TreeViewListItemLeaf[] | null = null;
    ItemsSource: TreeViewListItem[] | null = null;

    constructor() {
        // 模拟日志记录器
        this.log = {
            error: (msg: string) => console.error(msg),
            fatal: (msg: string, e: Error) => console.error(msg, e)
        };
    }

    // 事件处理方法
    addHandler(eventName: string, handler: Function) {
        if (!this.eventHandlers[eventName]) {
            this.eventHandlers[eventName] = [];
        }
        this.eventHandlers[eventName].push(handler);
    }

    removeHandler(eventName: string, handler: Function) {
        if (this.eventHandlers[eventName]) {
            this.eventHandlers[eventName] = this.eventHandlers[eventName].filter(h => h!== handler);
        }
    }

    raiseRoutedEvent(eventName: string) {
        if (this.eventHandlers[eventName]) {
            this.eventHandlers[eventName].forEach(handler => handler());
        }
    }

    // 私有方法
    private setCheckBoxVisibility(control: TreeViewListItem) {
        if (!control.Items || control.Items.length === 0) return;
        control.Items.forEach((item) => {
            TreeViewListItem.SetCheckBoxVisibility(item, this.IsShowCheckBox? "Visible" : "Collapsed");
            this.setCheckBoxVisibility(item);
        });
    }

    private expandAllItems(control: TreeViewListItem, value: boolean) {
        if (!control.Items || control.Items.length === 0) return;
        control.Items.forEach((item) => {
            item.IsExpanded = value;
            this.expandAllItems(item, value);
        });
    }

    private getCheckedItems(source: ItemCollection): TreeViewListItem[] {
        let checkedItems: TreeViewListItem[] = [];
        if (!source) return checkedItems;
        source.forEach((item) => {
            if (TreeViewListItem.GetIsChecked(item) && item.constructor.name === "TreeViewListItem") {
                checkedItems.push(item);
            }
            if (item.Items && item.Items.length > 0) {
                checkedItems = checkedItems.concat(this.getCheckedItems(item.Items));
            }
        });
        return checkedItems;
    }

    private setAllIsChecked(value: boolean) {
        if (!this.IsShowCheckBox) return;
        if (this.ItemsSource) {
            this.ItemsSource.forEach((item) => {
                TreeViewListItem.SetIsChecked(item, value);
            });
        }
    }

    private getClickItem(source: ItemCollection): TreeViewListItem | null {
        if (!source || source.length === 0) return null;
        for (let i = 0; i < source.length; i++) {
            const item = source[i];
            // 模拟鼠标位置判断
            // 实际实现需要根据前端 DOM 事件处理
            // 这里简化处理
            if (item.IsExpanded) {
                const selectedItem = this.getClickItem(item.Items);
                if (selectedItem) {
                    return selectedItem;
                }
            }
            return item;
        }
        return null;
    }

    private initNodeLevel(source: TreeViewListItem[], filterTradeNoArray: string[] | null) {
        source.forEach((item) => {
            const Multdescrption = { DescriptionName: item.DescriptionName } as TreeViewListItem;
            item.StyleNumber = this.StyleNumber;
            item.Width = this.ItemsSource? this.ItemsSource[0].Width : 0;
            if (item.Parent) {
                item.ParentLevel = item.Parent.NodeLevel;
            }
            if (item instanceof TreeViewListItemLeaf) {
                if (this.isTradeToFilter(item.MenuCode, filterTradeNoArray)) {
                    item.Visibility = "Collapsed";
                    if (filterTradeNoArray) {
                        filterTradeNoArray = filterTradeNoArray.filter(no => no!== item.MenuCode);
                    }
                    const parentItem = item.Parent;
                    if (parentItem &&!this.isHasVisibleChild(parentItem)) {
                        this.hideMenuTreeItemCategory(parentItem);
                    }
                }
            } else {
                if (!item.Parent) {
                    item.NodeLevel = 0;
                } else {
                    item.NodeLevel = item.Parent.NodeLevel + 1;
                }
                if (item.Items && item.Items.length > 0) {
                    this.initNodeLevel(item.Items, filterTradeNoArray);
                } else {
                    item.Visibility = "Collapsed";
                }
            }
        });
    }

    private hideMenuTreeItemCategory(parentItem: TreeViewListItem) {
        if (parentItem &&!this.isHasVisibleChild(parentItem)) {
            parentItem.Visibility = "Collapsed";
            if (parentItem.Parent) {
                this.hideMenuTreeItemCategory(parentItem.Parent);
            }
        }
    }

    private findSigleTradeByTradeNo(tradeno: string, source: TreeViewListItem[]): TreeViewListItemLeaf | null {
        for (let i = 0; i < source.length; i++) {
            const item = source[i];
            if (item instanceof TreeViewListItemLeaf) {
                if (item.MenuCode === tradeno) {
                    return item;
                }
            } else {
                const foundItem = this.findSigleTradeByTradeNo(tradeno, item.Items);
                if (foundItem) {
                    return foundItem;
                }
            }
        }
        return null;
    }

    private isTradeToFilter(tradeno: string, filterTradeNoArray: string[] | null): boolean {
        if (!filterTradeNoArray ||!tradeno) return false;
        return filterTradeNoArray.includes(tradeno);
    }

    private isHasVisibleChild(item: TreeViewListItem): boolean {
        if (!item.Items) return false;
        return item.Items.some(child => child.Visibility === "Visible");
    }

    // 公共方法
    getMenuTreeItems(rootNode: any, filterTradeNoArray: string[] | null = null): boolean {
        if (!rootNode) {
            this.log.error("根节点menu不存在或配置有误!");
            return false;
        }
        try {
            const source = new TreeViewSource().GetMenuTreeListByXML(rootNode);
            if (!source) {
                this.log.error("从配置文件中读取主菜单配置信息发生错误！");
                return false;
            }
            this.initNodeLevel(source, filterTradeNoArray);
            this.ItemsSource = source;
            return true;
        } catch (e) {
            this.log.fatal("从配置文件中读取主菜单配置信息发生异常！", e);
            return false;
        }
    }

    getMenuTreeItemsFromTable(menuTable: any, filterTradeNoArray: string[] | null = null): boolean {
        if (!menuTable || menuTable.length < 1) {
            this.log.error("主菜单数据库表为null或行数小于1！");
            return true;
        }
        try {
            const source = new TreeViewSource().GetMenuTreeListByDataTable(menuTable);
            if (!source) {
                this.log.error("从数据库表中获取主菜单配置信息发生错误！");
                return false;
            }
            this.initNodeLevel(source, filterTradeNoArray);
            this.ItemsSource = source;
            return true;
        } catch (e) {
            this.log.fatal("从数据表中获取主菜单配置信息发生异常！", e);
            return false;
        }
    }

    getSingleTradeByTradeNo(tradeno: string): TreeViewListItemLeaf | null {
        if (!tradeno) return null;
        const regex = /^\d{4}$/;
        if (regex.test(tradeno) && this.ItemsSource && this.ItemsSource.length > 0) {
            return this.findSigleTradeByTradeNo(tradeno, this.ItemsSource);
        }
        return null;
    }
}