import { Command } from './Command';
import { AppNodeType, AppNodeData } from '../types/node';

/**
 * Command to update a node's data
 */
export class UpdateNodeCommand implements Command {
    private nodeId: string;
    private oldData: Partial<AppNodeData>;
    private newData: Partial<AppNodeData>;
    private setNodes: (updater: (nodes: AppNodeType[]) => AppNodeType[]) => void;
    private getNodes: () => AppNodeType[];

    constructor(
        nodeId: string,
        newData: Partial<AppNodeData>,
        setNodes: (updater: (nodes: AppNodeType[]) => AppNodeType[]) => void,
        getNodes: () => AppNodeType[]
    ) {
        this.nodeId = nodeId;
        this.newData = newData;
        this.setNodes = setNodes;
        this.getNodes = getNodes;
        
        // Store old data for undo
        const node = getNodes().find(n => n.id === nodeId);
        if (node && node.type === 'appNode') {
            this.oldData = { ...node.data };
        } else {
            this.oldData = {};
        }
    }

    execute(): void {
        this.setNodes((nodes) => 
            nodes.map(n => 
                n.id === this.nodeId && n.type === 'appNode'
                    ? { ...n, data: { ...n.data, ...this.newData } }
                    : n
            )
        );
    }

    undo(): void {
        this.setNodes((nodes) => 
            nodes.map(n => 
                n.id === this.nodeId && n.type === 'appNode'
                    ? { ...n, data: { ...n.data, ...this.oldData } }
                    : n
            )
        );
    }

    getDescription(): string {
        return `Update node: ${this.nodeId}`;
    }
}
