import { useCallback, useMemo } from 'react';
import { useAutoSave } from './useAutoSave';
import { AppNodeType } from '../types/node';
import { Edge } from '@xyflow/react';
import { CanvasService } from '@/lib/api';

interface CanvasData {
    nodes: AppNodeType[];
    edges: Edge[];
}

interface UseCanvasAutoSaveOptions {
    /**
     * Canvas ID to save to
     */
    canvasId: string | null;
    
    /**
     * Project ID for the canvas
     */
    projectId: string | null;
    
    /**
     * Canvas type (main, asset, storyboard)
     */
    canvasType: 'main' | 'asset' | 'storyboard';
    
    /**
     * Whether canvas is loaded and ready to save
     */
    isLoaded: boolean;
    
    /**
     * Debounce delay in milliseconds
     * @default 2000
     */
    delay?: number;
    
    /**
     * Whether auto-save is enabled
     * @default true
     */
    enabled?: boolean;
    
    /**
     * Callback to update save status
     */
    onSaveStatusChange?: (isSaving: boolean) => void;
    
    /**
     * Callback when save completes
     */
    onSaveComplete?: () => void;
    
    /**
     * Callback when save fails
     */
    onSaveError?: (error: Error) => void;
}

/**
 * Hook to implement auto-save for Canvas
 * Automatically saves canvas state (nodes and edges) after 2 seconds of inactivity
 * 
 * @example
 * ```tsx
 * const { triggerSave, cancelSave } = useCanvasAutoSave({
 *   nodes,
 *   edges,
 *   canvasId: 'canvas-123',
 *   canvasType: 'asset',
 *   isLoaded: true
 * });
 * ```
 */
export const useCanvasAutoSave = (
    nodes: AppNodeType[],
    edges: Edge[],
    options: UseCanvasAutoSaveOptions
) => {
    const {
        canvasId,
        projectId,
        canvasType,
        isLoaded,
        delay = 2000,
        enabled = true,
        onSaveStatusChange,
        onSaveComplete,
        onSaveError
    } = options;

    // Memoize canvas data to prevent unnecessary re-renders
    const canvasData = useMemo<CanvasData>(() => ({
        nodes,
        edges
    }), [nodes, edges]);

    /**
     * Save function that persists canvas data
     */
    const saveCanvas = useCallback(async (data: CanvasData) => {
        if (!canvasId || !projectId || !isLoaded) {
            return;
        }

        try {
            // Call actual API to save canvas state
            await CanvasService.saveCanvasState({
                id: canvasId,
                projectId: projectId,
                nodes: data.nodes,
                connections: data.edges,
                groups: [],
                history: [],
                historyIndex: -1,
                updatedAt: Date.now()
            });

            console.log(`[AutoSave] Canvas saved successfully: ${canvasId} (${canvasType})`, {
                nodeCount: data.nodes.length,
                edgeCount: data.edges.length
            });
        } catch (error) {
            console.error(`[AutoSave] Failed to save canvas ${canvasId}:`, error);
            throw error;
        }
    }, [canvasId, projectId, canvasType, isLoaded]);

    /**
     * Handle save start
     */
    const handleSaveStart = useCallback(() => {
        onSaveStatusChange?.(true);
    }, [onSaveStatusChange]);

    /**
     * Handle save complete
     */
    const handleSaveComplete = useCallback(() => {
        onSaveStatusChange?.(false);
        onSaveComplete?.();
    }, [onSaveStatusChange, onSaveComplete]);

    /**
     * Handle save error
     */
    const handleSaveError = useCallback((error: Error) => {
        onSaveStatusChange?.(false);
        onSaveError?.(error);
        console.error('[AutoSave] Save failed:', error);
    }, [onSaveStatusChange, onSaveError]);

    // Use the generic auto-save hook
    const { triggerSave, cancelSave, scheduleSave } = useAutoSave(
        canvasData,
        saveCanvas,
        {
            delay,
            enabled: enabled && isLoaded && !!canvasId,
            onSaveStart: handleSaveStart,
            onSaveComplete: handleSaveComplete,
            onSaveError: handleSaveError
        }
    );

    return {
        /**
         * Trigger a save immediately
         */
        triggerSave,
        
        /**
         * Cancel any pending save
         */
        cancelSave,
        
        /**
         * Schedule a debounced save
         */
        scheduleSave
    };
};
