/**
 * Terminal 分屏管理 Hook
 * 支持树形嵌套布局，参考 VS Code 的分屏逻辑
 */
import { useState, useCallback } from 'react';
import type { EditorGroup, TerminalTab, SplitDirection, SplitLayout, SplitNode, SplitContainer, LayoutOrientation } from './types';
import { TerminalInstanceManager } from './core/TerminalInstanceManager';
import { getMinSplitSize, getMinSplitPercent } from './splitUtils';

interface UseSplitViewOptions {
    initialTab: TerminalTab;
    onWindowClose?: () => void;  // 最后一个Tab关闭时的回调
}

export const useSplitView = ({ initialTab, onWindowClose }: UseSplitViewOptions) => {
    const [layout, setLayout] = useState<SplitLayout>(() => ({
        root: {
            type: 'group',
            id: 'group-1',
            tabs: [initialTab],
            activeTabId: initialTab.id,
            size: 100,
        } as EditorGroup,
    }));

    const [activeGroupId, setActiveGroupId] = useState('group-1');

    // 在树中查找组
    const findGroup = useCallback((node: SplitNode, groupId: string): EditorGroup | null => {
        if (node.type === 'group') {
            return node.id === groupId ? node : null;
        }
        for (const child of node.children) {
            const found = findGroup(child, groupId);
            if (found) return found;
        }
        return null;
    }, []);

    // 查找父容器和节点索引
    const findParent = useCallback((
        node: SplitNode,
        targetId: string,
        parent: SplitContainer | null = null,
        index: number = 0
    ): { parent: SplitContainer | null; index: number; node: SplitNode } | null => {
        if (node.id === targetId) {
            return { parent, index, node };
        }
        if (node.type === 'container') {
            for (let i = 0; i < node.children.length; i++) {
                const result = findParent(node.children[i], targetId, node, i);
                if (result) return result;
            }
        }
        return null;
    }, []);

    // 获取当前激活的组
    const getActiveGroup = useCallback(() => {
        return findGroup(layout.root, activeGroupId);
    }, [layout.root, activeGroupId, findGroup]);

    // 向指定方向拆分
    // 辅助函数：安全地更新节点的 size，保持其他属性引用不变
    const updateNodeSize = (node: SplitNode, newSize: number): SplitNode => {
        if (node.size === newSize) {
            return node; // size 没变，返回原对象
        }
        // size 变了，创建新对象，但保持其他属性引用
        if (node.type === 'group') {
            return {
                ...node,
                size: newSize,
                // tabs 数组引用保持不变
            };
        } else {
            return {
                ...node,
                size: newSize,
                // children 数组引用保持不变
            };
        }
    };

    const splitToDirection = useCallback((direction: SplitDirection) => {
        const activeGroup = getActiveGroup();
        if (!activeGroup) return;

        const activeTab = activeGroup.tabs.find(t => t.id === activeGroup.activeTabId);
        if (!activeTab) return;

        const newGroupId = `group-${Date.now()}`;
        const newTab: TerminalTab = {
            id: `tab-${Date.now()}`,
            title: activeTab.title,
            serverId: activeTab.serverId,
            serverName: activeTab.serverName,
            isActive: true,
        };

        const newGroup: EditorGroup = {
            type: 'group',
            id: newGroupId,
            tabs: [newTab],
            activeTabId: newTab.id,
            size: 50,
        };

        setLayout(prev => {
            const result = findParent(prev.root, activeGroup.id);
            if (!result) return prev;

            const { parent, index, node } = result;
            const isHorizontalSplit = direction === 'left' || direction === 'right';
            const newOrientation: LayoutOrientation = isHorizontalSplit ? 'horizontal' : 'vertical';

            // 如果是根节点
            if (!parent) {
                const updatedNode = updateNodeSize(node, 50);
                
                const container: SplitContainer = {
                    type: 'container',
                    id: `container-${Date.now()}`,
                    orientation: newOrientation,
                    children: direction === 'right' || direction === 'down'
                        ? [updatedNode, newGroup]
                        : [newGroup, updatedNode],
                    size: 100,
                };
                return { root: container };
            }

            // 父容器方向一致：直接插入
            if (parent.orientation === newOrientation) {
                const newChildren = [...parent.children];
                const insertIndex = direction === 'right' || direction === 'down' ? index + 1 : index;
                newChildren.splice(insertIndex, 0, newGroup);
                
                // 重新分配大小
                const sizePerChild = 100 / newChildren.length;
                const resizedChildren = newChildren.map(child => updateNodeSize(child, sizePerChild));

                return {
                    root: updateNode(prev.root, parent.id, {
                        ...parent,
                        children: resizedChildren,
                    }),
                };
            }

            // 父容器方向不一致：创建新容器包裹当前节点和新节点
            const updatedNode = updateNodeSize(node, 50);
            
            const newContainer: SplitContainer = {
                type: 'container',
                id: `container-${Date.now()}`,
                orientation: newOrientation,
                children: direction === 'right' || direction === 'down'
                    ? [updatedNode, newGroup]
                    : [newGroup, updatedNode],
                size: node.size,
            };

            const newChildren = [...parent.children];
            newChildren[index] = newContainer;

            return {
                root: updateNode(prev.root, parent.id, {
                    ...parent,
                    children: newChildren,
                }),
            };
        });

        setActiveGroupId(newGroupId);
    }, [activeGroupId, getActiveGroup, findParent]);

    // 更新节点（递归）- 优化：只在真正需要更新时才创建新对象
    const updateNode = (node: SplitNode, targetId: string, newNode: SplitNode): SplitNode => {
        if (node.id === targetId) {
            return newNode;
        }
        if (node.type === 'container') {
            // 递归更新子节点
            const newChildren = node.children.map(child => updateNode(child, targetId, newNode));
            
            // 检查是否真的有子节点被更新了
            const hasChanged = newChildren.some((child, index) => child !== node.children[index]);
            
            // 如果没有变化，返回原节点（保持引用不变）
            if (!hasChanged) {
                return node;
            }
            
            // 有变化才创建新对象
            return {
                ...node,
                children: newChildren,
            };
        }
        return node;
    };

    // 在组中拆分（创建新标签页）
    const splitInGroup = useCallback((groupId?: string) => {
        // 如果提供了groupId就用它，否则用activeGroupId
        const targetGroupId = groupId || activeGroupId;
        
        const targetGroup = findGroup(layout.root, targetGroupId);
        if (!targetGroup) {
            return;
        }


        const activeTab = targetGroup.tabs.find(t => t.id === targetGroup.activeTabId);
        if (!activeTab) {
            return;
        }


        const newTab: TerminalTab = {
            id: `tab-${Date.now()}`,
            title: activeTab.title,
            serverId: activeTab.serverId,
            serverName: activeTab.serverName,
            isActive: true,
        };

        setLayout(prev => ({
            root: updateNode(prev.root, targetGroup.id, {
                ...targetGroup,
                tabs: [...targetGroup.tabs.map(t => ({ ...t, isActive: false })), newTab],
                activeTabId: newTab.id,
            }),
        }));
        
        // 更新activeGroupId
        setActiveGroupId(targetGroupId);
        
    }, [activeGroupId, findGroup, layout.root]);

    // 切换标签页
    const switchTab = useCallback((groupId: string, tabId: string) => {
        // 先设置activeGroupId，确保后续操作使用正确的组
        setActiveGroupId(groupId);
        
        setLayout(prev => {
            const group = findGroup(prev.root, groupId);
            if (!group) {
                return prev;
            }

            return {
                root: updateNode(prev.root, groupId, {
                    ...group,
                    tabs: group.tabs.map(t => ({ ...t, isActive: t.id === tabId })),
                    activeTabId: tabId,
                }),
            };
        });
    }, [findGroup]);

    // 关闭标签页
    const closeTab = useCallback((groupId: string, tabId: string) => {
        // 销毁 Terminal 实例
        const manager = TerminalInstanceManager.getInstance();
        manager.destroy(tabId);
        
        setLayout(prev => {
            const group = findGroup(prev.root, groupId);
            if (!group) return prev;

            if (group.tabs.length === 1) {
                // 关闭整个组
                return closeGroup(prev, groupId);
            }

            const newTabs = group.tabs.filter(t => t.id !== tabId);
            const newActiveTabId = group.activeTabId === tabId ? newTabs[0].id : group.activeTabId;

            // 更新 isActive 状态
            const updatedTabs = newTabs.map(t => ({
                ...t,
                isActive: t.id === newActiveTabId,
            }));

            return {
                root: updateNode(prev.root, groupId, {
                    ...group,
                    tabs: updatedTabs,
                    activeTabId: newActiveTabId,
                }),
            };
        });
    }, [findGroup]);

    // 关闭组
    const closeGroup = (prev: SplitLayout, groupId: string): SplitLayout => {
        // 销毁组内所有 Terminal 实例
        const group = findGroup(prev.root, groupId);
        if (group) {
            const manager = TerminalInstanceManager.getInstance();
            group.tabs.forEach(tab => {
                manager.destroy(tab.id);
            });
        }
        
        const result = findParent(prev.root, groupId);
        if (!result) return prev;

        const { parent } = result;
        if (!parent) {
            // 根节点 且 只有一个Tab，关闭整个窗口
            if (group && group.tabs.length === 1) {
                onWindowClose?.();
            }
            return prev;
        }

        const newChildren = parent.children.filter(c => c.id !== groupId);
        if (newChildren.length === 0) return prev;

        if (newChildren.length === 1) {
            // 只剩一个子节点，提升它
            const child = newChildren[0];
            const grandParentResult = findParent(prev.root, parent.id);
            
            if (!grandParentResult || !grandParentResult.parent) {
                // 父容器是根节点，提升子节点为新根
                return { root: { ...child, size: 100 } };
            }

            // 用子节点替换父容器
            const grandParent = grandParentResult.parent;
            const newGrandChildren = grandParent.children.map(c =>
                c.id === parent.id ? { ...child, size: parent.size } : c
            );

            return {
                root: updateNode(prev.root, grandParent.id, {
                    ...grandParent,
                    children: newGrandChildren,
                }),
            };
        }

        // 重新分配大小
        const sizePerChild = 100 / newChildren.length;
        newChildren.forEach(child => { child.size = sizePerChild; });

        return {
            root: updateNode(prev.root, parent.id, {
                ...parent,
                children: newChildren,
            }),
        };
    };

    // 调整分屏大小
    const resizeGroups = useCallback((nodeId: string, delta: number, containerSize?: number) => {
        setLayout(prev => {
            const result = findParent(prev.root, nodeId);
            if (!result || !result.parent) return prev;

            const { parent, index } = result;
            if (index >= parent.children.length - 1) return prev;

            const current = parent.children[index];
            const next = parent.children[index + 1];
            const totalSize = current.size + next.size;

            // 将像素delta转换为百分比delta
            // delta是像素值，需要转换为百分比：(delta / containerSize) * totalSize
            const deltaPercent = containerSize ? (delta / containerSize) * totalSize : delta;

            // 计算最小尺寸百分比：根据方向和容器尺寸计算
            let minSizePercent = totalSize * 0.2; // 默认20%
            if (containerSize && parent.type === 'container') {
                const minPixels = getMinSplitSize(containerSize, parent.orientation);
                minSizePercent = getMinSplitPercent(minPixels, containerSize, totalSize);
            }

            const newCurrentSize = Math.max(minSizePercent, Math.min(totalSize - minSizePercent, current.size + deltaPercent));
            const newNextSize = totalSize - newCurrentSize;

            const newChildren = parent.children.map((child, i) => {
                if (i === index) return { ...child, size: newCurrentSize };
                if (i === index + 1) return { ...child, size: newNextSize };
                return child;
            });

            return {
                root: updateNode(prev.root, parent.id, {
                    ...parent,
                    children: newChildren,
                }),
            };
        });
    }, [findParent]);

    // 关闭所有Tab（窗口关闭时调用）
    const closeAll = useCallback(() => {
        const manager = TerminalInstanceManager.getInstance();
        
        // 收集所有Tab ID
        const allTabIds: string[] = [];
        const collectTabIds = (node: SplitNode) => {
            if (node.type === 'group') {
                allTabIds.push(...node.tabs.map(t => t.id));
            } else if (node.type === 'container') {
                node.children.forEach(collectTabIds);
            }
        };
        collectTabIds(layout.root);
        
        // 销毁所有Terminal实例
        allTabIds.forEach(tabId => {
            manager.destroy(tabId);
        });
        
    }, [layout.root]);

    return {
        layout,
        activeGroupId,
        splitUp: () => splitToDirection('up'),
        splitDown: () => splitToDirection('down'),
        splitLeft: () => splitToDirection('left'),
        splitRight: () => splitToDirection('right'),
        splitInGroup,
        switchTab,
        closeTab,
        closeAll,
        resizeGroups,
        setActiveGroupId,
    };
};
