"use client";
import { useCallback, useEffect, useRef, useState } from "react";
import { createDagreLayoutEngine } from "./dagre-layout-engine";
// ---------------------------------------------------------------------------
// Hook
// ---------------------------------------------------------------------------
/**
 * Behavior hook (DD-003 layer 2) that orchestrates async layout computation.
 *
 * Manages:
 * - **Generation counter**: overlapping requests are deduplicated; only the
 *   latest result is returned. Stale results from prior requests are discarded.
 * - **Error fallback**: if the primary engine fails, the fallback (dagre) is
 *   tried automatically. Both failures result in a null return + error state.
 * - **Loading state**: `isLayouting` tracks whether computation is in flight.
 * - **Cleanup**: terminates the engine's Web Worker on unmount.
 */
export function useWorkflowLayout(options = {}) {
    const { engine, fallbackEngine, getNodeDimensions } = options;
    const [isLayouting, setIsLayouting] = useState(false);
    const [lastResult, setLastResult] = useState(null);
    const [error, setError] = useState(null);
    const generationRef = useRef(0);
    const dagreFallbackRef = useRef(null);
    function getFallback() {
        if (fallbackEngine)
            return fallbackEngine;
        if (!dagreFallbackRef.current) {
            dagreFallbackRef.current = createDagreLayoutEngine();
        }
        return dagreFallbackRef.current;
    }
    useEffect(() => {
        return () => {
            engine?.terminate?.();
        };
    }, [engine]);
    const layoutGraph = useCallback(async (graph, scope) => {
        const generation = ++generationRef.current;
        setIsLayouting(true);
        setError(null);
        const input = { graph, scope, getNodeDimensions };
        const activeEngine = engine ?? getFallback();
        try {
            const result = await activeEngine.layout(input);
            if (generation !== generationRef.current) {
                return null;
            }
            setLastResult(result);
            setIsLayouting(false);
            return result;
        }
        catch (primaryError) {
            if (generation !== generationRef.current) {
                return null;
            }
            if (activeEngine !== getFallback()) {
                const message = primaryError instanceof Error
                    ? primaryError.message
                    : "Layout engine failed";
                if (process.env.NODE_ENV !== "production") {
                    console.warn(`[useWorkflowLayout] Primary engine "${activeEngine.name}" failed: ${message}. Falling back to dagre.`);
                }
                try {
                    const fallbackResult = await getFallback().layout(input);
                    if (generation !== generationRef.current) {
                        return null;
                    }
                    setLastResult(fallbackResult);
                    setError(`Layout optimized with fallback engine (${message})`);
                    setIsLayouting(false);
                    return fallbackResult;
                }
                catch (fallbackError) {
                    if (generation !== generationRef.current)
                        return null;
                    const msg = fallbackError instanceof Error
                        ? fallbackError.message
                        : "Fallback layout also failed";
                    setError(msg);
                    setIsLayouting(false);
                    return null;
                }
            }
            const msg = primaryError instanceof Error
                ? primaryError.message
                : "Layout failed";
            setError(msg);
            setIsLayouting(false);
            return null;
        }
    }, [engine, fallbackEngine, getNodeDimensions]);
    return { layoutGraph, isLayouting, lastResult, error };
}
//# sourceMappingURL=use-workflow-layout.js.map