/**
 * Canvas Store Types - 画布状态类型定义
 */
import { AppNodeType, Group } from '@/components/canvas/types';
import { Edge, NodeChange, EdgeChange, Connection as FlowConnection } from '@xyflow/react';
import { IncrementalHistory } from '@/lib/utils/historyDiff';
import { SmartHistoryMerger, MergeableOperation } from '@/lib/utils/historyMerge';

export interface CanvasStateSnapshot {
    nodes: AppNodeType[];
    edges: Edge[];
    groups: Group[];
}

export interface MemoryStats {
    historyMemoryBytes: number;
    historyMemoryKB: string;
    historyMemoryMB: string;
    totalSteps: number;
    snapshotCount: number;
    patchCount: number;
    averageBytesPerStep: number;
    timestamp: number;
}

export interface CanvasState extends CanvasStateSnapshot {
    // Incremental history system
    incrementalHistory: IncrementalHistory<CanvasStateSnapshot> | null;
    historyMerger: SmartHistoryMerger | null;

    // Memory monitoring
    memoryStats: MemoryStats | null;
    memoryMonitoringEnabled: boolean;

    // Internal state for throttling
    saveHistoryTimeout?: NodeJS.Timeout | null;

    scale: number;
    pan: { x: number; y: number };

    selectedNodeIds: string[];
    selectedGroupId: string | null;

    // Persistence status
    isDirty: boolean;
    isSaving: boolean;
    lastSavedAt: number | null;

    // Last operation tracking
    lastOperationType: 'node-move' | 'node-resize' | 'text-edit' | 'node-add' | 'node-delete' | 'other' | null;

    // Generation History
    generationHistory: any[];

    // Actions
    setNodes: (nodes: AppNodeType[] | ((prev: AppNodeType[]) => AppNodeType[])) => void;
    setEdges: (edges: Edge[] | ((prev: Edge[]) => Edge[])) => void;
    setGroups: (groups: Group[] | ((prev: Group[]) => Group[])) => void;

    onNodesChange: (changes: NodeChange<AppNodeType>[]) => void;
    onEdgesChange: (changes: EdgeChange[]) => void;
    onConnect: (connection: FlowConnection) => void;

    setGenerationHistory: (history: any[] | ((prev: any[]) => any[])) => void;
    addGenerationHistoryItem: (item: any) => void;

    saveHistory: () => void;
    saveHistoryThrottled: () => void;
    saveHistoryWithMerge: (operation?: MergeableOperation) => void;
    commitPendingHistory: () => void;
    undo: () => void;
    redo: () => void;
    canUndo: () => boolean;
    canRedo: () => boolean;
    getHistoryStats: () => any;

    // Memory monitoring actions
    updateMemoryStats: () => void;
    getMemoryStats: () => MemoryStats | null;
    enableMemoryMonitoring: () => void;
    disableMemoryMonitoring: () => void;
    getMemoryReport: () => string;

    setScale: (scale: number | ((prev: number) => number)) => void;
    setPan: (pan: { x: number; y: number } | ((prev: { x: number; y: number }) => { x: number; y: number })) => void;

    setSelectedNodeIds: (ids: string[] | ((prev: string[]) => string[])) => void;
    setSelectedGroupId: (id: string | null | ((prev: string | null) => string | null)) => void;
    setLastOperationType: (type: 'node-move' | 'node-resize' | 'text-edit' | 'node-add' | 'node-delete' | 'other' | null) => void;

    // Persistence actions
    setDirty: (isDirty: boolean) => void;
    setSaving: (isSaving: boolean) => void;
    setLastSavedAt: (timestamp: number) => void;

    addNode: (node: AppNodeType) => void;
    deleteNodes: (ids: string[]) => void;
    updateNode: (id: string, data: any, size?: any, title?: string) => void;
    updateNodePosition: (id: string, position: { x: number; y: number }) => void;
    updateNodeSize: (id: string, size: { width: number; height: number }) => void;

    // Group operations
    createGroupFromSelected: (title?: string) => string | null;
    addNodesToGroup: (nodeIds: string[], groupId: string) => void;
    removeNodesFromGroup: (nodeIds: string[], groupId: string) => void;
    deleteGroup: (groupId: string) => void;
    ungroup: (groupId: string) => void;
    getNodesInGroup: (groupId: string) => AppNodeType[];
    updateGroup: (groupId: string, updates: Partial<Group>) => void;

    // Bulk operations
    batchUpdate: (updates: () => void) => void;
    setCanvasState: (state: Partial<CanvasState>) => void;
}

export const MAX_HISTORY_SIZE = 50;
export const SAVE_HISTORY_DELAY = 300; // ms
