/**
 * History Types
 *
 * Shared types for the delta-based undo/redo system.
 */

import type { GraphNodeAttributes, GraphEdgeAttributes, NodePosition } from './types';

// =============================================================================
// Delta Types
// =============================================================================

export type HistoryDelta =
    | { type: 'move-node'; nodeId: string; from: NodePosition; to: NodePosition }
    | { type: 'resize-node'; nodeId: string; from: { width: number; height: number }; to: { width: number; height: number } }
    | { type: 'add-node'; nodeId: string; attributes: GraphNodeAttributes }
    | { type: 'remove-node'; nodeId: string; attributes: GraphNodeAttributes; connectedEdges: Array<{ id: string; source: string; target: string; attributes: GraphEdgeAttributes }> }
    | { type: 'add-edge'; edgeId: string; source: string; target: string; attributes: GraphEdgeAttributes }
    | { type: 'remove-edge'; edgeId: string; source: string; target: string; attributes: GraphEdgeAttributes }
    | { type: 'update-node-attr'; nodeId: string; key: string; from: unknown; to: unknown }
    | { type: 'batch'; deltas: HistoryDelta[] }
    | { type: 'full-snapshot'; nodes: Array<{ id: string; attributes: GraphNodeAttributes }>; edges: Array<{ id: string; source: string; target: string; attributes: GraphEdgeAttributes }> };

export interface HistoryEntry {
    /** Forward delta (what happened) */
    forward: HistoryDelta;
    /** Reverse delta (how to undo) */
    reverse: HistoryDelta;
    /** Timestamp */
    timestamp: number;
    /** Description of the operation */
    label?: string;
}

export interface HistoryState {
    /** Past entries (for undo) */
    past: HistoryEntry[];
    /** Future entries (for redo) */
    future: HistoryEntry[];
    /** Whether history is currently being applied (to prevent recursion) */
    isApplying: boolean;
}

export interface GraphSnapshot {
    timestamp: number;
    label?: string;
    nodes: Array<{ id: string; attributes: GraphNodeAttributes }>;
    edges: Array<{ id: string; source: string; target: string; attributes: GraphEdgeAttributes }>;
}
