/**
 * Groups Slice - 组状态管理
 */
import { AppNodeType, Group } from '@/components/canvas/types';
import { CanvasState } from './types';

export const createGroupsActions = (set: any, get: any) => ({
    setGroups: (updater: Group[] | ((prev: Group[]) => Group[])) => set((state: CanvasState) => {
        state.groups = typeof updater === 'function' ? updater(state.groups) : updater;
    }),

    createGroupFromSelected: (title = 'Group') => {
        const { selectedNodeIds, nodes, groups } = get();

        if (selectedNodeIds.length < 2) {
            console.warn('[CanvasStore] Need at least 2 nodes to create a group');
            return null;
        }

        const selectedNodes = nodes.filter((n: AppNodeType) => selectedNodeIds.includes(n.id));
        if (selectedNodes.length === 0) return null;

        const minX = Math.min(...selectedNodes.map((n: AppNodeType) => n.position.x));
        const minY = Math.min(...selectedNodes.map((n: AppNodeType) => n.position.y));
        const maxX = Math.max(...selectedNodes.map((n: AppNodeType) => n.position.x + (n.width || 300)));
        const maxY = Math.max(...selectedNodes.map((n: AppNodeType) => n.position.y + (n.height || 200)));

        const padding = 20;
        const newGroup: Group = {
            id: `group-${Date.now()}`,
            x: minX - padding,
            y: minY - padding,
            width: maxX - minX + padding * 2,
            height: maxY - minY + padding * 2,
            title
        };

        set((state: CanvasState) => {
            state.groups.push(newGroup);
            selectedNodes.forEach((node: AppNodeType) => {
                const nodeInState = state.nodes.find(n => n.id === node.id);
                if (nodeInState) {
                    (nodeInState as any).parentId = newGroup.id;
                }
            });
            state.selectedGroupId = newGroup.id;
            state.isDirty = true;
        });

        get().saveHistory();
        return newGroup.id;
    },

    addNodesToGroup: (nodeIds: string[], groupId: string) => {
        const { groups, nodes } = get();
        const group = groups.find((g: Group) => g.id === groupId);
        if (!group) {
            console.warn(`[CanvasStore] Group ${groupId} not found`);
            return;
        }

        const nodesToAdd = nodes.filter((n: AppNodeType) => nodeIds.includes(n.id));
        if (nodesToAdd.length === 0) return;

        set((state: CanvasState) => {
            nodesToAdd.forEach((node: AppNodeType) => {
                const nodeInState = state.nodes.find(n => n.id === node.id);
                if (nodeInState) {
                    (nodeInState as any).parentId = groupId;
                }
            });

            const allGroupNodes = state.nodes.filter((n: AppNodeType) =>
                (n as any).parentId === groupId || nodeIds.includes(n.id)
            );

            if (allGroupNodes.length > 0) {
                const minX = Math.min(...allGroupNodes.map((n: AppNodeType) => n.position.x));
                const minY = Math.min(...allGroupNodes.map((n: AppNodeType) => n.position.y));
                const maxX = Math.max(...allGroupNodes.map((n: AppNodeType) => n.position.x + (n.width || 300)));
                const maxY = Math.max(...allGroupNodes.map((n: AppNodeType) => n.position.y + (n.height || 200)));

                const padding = 20;
                const groupInState = state.groups.find(g => g.id === groupId);
                if (groupInState) {
                    groupInState.x = minX - padding;
                    groupInState.y = minY - padding;
                    groupInState.width = maxX - minX + padding * 2;
                    groupInState.height = maxY - minY + padding * 2;
                }
            }

            state.isDirty = true;
        });

        get().saveHistory();
    },

    removeNodesFromGroup: (nodeIds: string[], groupId: string) => {
        set((state: CanvasState) => {
            nodeIds.forEach(nodeId => {
                const node = state.nodes.find(n => n.id === nodeId);
                if (node && (node as any).parentId === groupId) {
                    (node as any).parentId = undefined;
                }
            });

            const remainingNodes = state.nodes.filter((n: AppNodeType) => (n as any).parentId === groupId);
            if (remainingNodes.length === 0) {
                state.groups = state.groups.filter(g => g.id !== groupId);
                if (state.selectedGroupId === groupId) {
                    state.selectedGroupId = null;
                }
            } else {
                const minX = Math.min(...remainingNodes.map((n: AppNodeType) => n.position.x));
                const minY = Math.min(...remainingNodes.map((n: AppNodeType) => n.position.y));
                const maxX = Math.max(...remainingNodes.map((n: AppNodeType) => n.position.x + (n.width || 300)));
                const maxY = Math.max(...remainingNodes.map((n: AppNodeType) => n.position.y + (n.height || 200)));

                const padding = 20;
                const group = state.groups.find(g => g.id === groupId);
                if (group) {
                    group.x = minX - padding;
                    group.y = minY - padding;
                    group.width = maxX - minX + padding * 2;
                    group.height = maxY - minY + padding * 2;
                }
            }

            state.isDirty = true;
        });

        get().saveHistory();
    },

    deleteGroup: (groupId: string) => {
        set((state: CanvasState) => {
            state.nodes.forEach(node => {
                if ((node as any).parentId === groupId) {
                    (node as any).parentId = undefined;
                }
            });

            state.groups = state.groups.filter(g => g.id !== groupId);

            if (state.selectedGroupId === groupId) {
                state.selectedGroupId = null;
            }

            state.isDirty = true;
        });

        get().saveHistory();
    },

    ungroup: (groupId: string) => {
        get().deleteGroup(groupId);
    },

    getNodesInGroup: (groupId: string) => {
        const { nodes } = get();
        return nodes.filter((n: AppNodeType) => (n as any).parentId === groupId);
    },

    updateGroup: (groupId: string, updates: Partial<Group>) => {
        set((state: CanvasState) => {
            const group = state.groups.find(g => g.id === groupId);
            if (group) {
                Object.assign(group, updates);
                state.isDirty = true;
            }
        });

        get().saveHistoryThrottled();
    },
});
