"use client";
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { memo, useCallback, useMemo, useState } from "react";
import { cn } from "@stigmer/theme";
import { useWorkflowEditor } from "./useWorkflowEditor.js";
import { WorkflowYamlEditor } from "./WorkflowYamlEditor.js";
import { WorkflowCodePreviewGraph } from "./WorkflowCodePreviewGraph.js";
import { WorkflowCanvasEditor } from "./WorkflowCanvasEditor.js";
import { WorkflowRefinePanel } from "./WorkflowRefinePanel.js";
import { WorkflowExplainDialog } from "./WorkflowExplainDialog.js";
import { yamlToGraph } from "./workflow-graph-conversions.js";
export const WorkflowEditorView = memo(function WorkflowEditorView({ initialYaml, org, onSaveSuccess, onSaveError, defaultMode = "code", className, layoutEngine, }) {
    const editor = useWorkflowEditor(initialYaml, { org });
    const [isFullPage, setIsFullPage] = useState(false);
    const [mode, setMode] = useState(defaultMode);
    const [showModeWarning, setShowModeWarning] = useState(false);
    const [canvasIsSaving, setCanvasIsSaving] = useState(false);
    const [showRefinePanel, setShowRefinePanel] = useState(false);
    const [pendingFixInstruction, setPendingFixInstruction] = useState(undefined);
    const [showExplainDialog, setShowExplainDialog] = useState(false);
    // Track canvas dirty state separately for mode switch prompts
    const [canvasDirty, setCanvasDirty] = useState(false);
    const [showDirtyPrompt, setShowDirtyPrompt] = useState(false);
    const handleSave = useCallback(async () => {
        const success = await editor.save();
        if (success) {
            onSaveSuccess?.();
        }
        else if (editor.saveError) {
            onSaveError?.(editor.saveError);
        }
    }, [editor, onSaveSuccess, onSaveError]);
    const toggleFullPage = useCallback(() => {
        setIsFullPage((prev) => !prev);
    }, []);
    // -------------------------------------------------------------------------
    // Mode switching (AD-T15-B3-003)
    // -------------------------------------------------------------------------
    const handleSwitchToVisual = useCallback(() => {
        try {
            yamlToGraph(editor.yaml);
            setShowModeWarning(true);
        }
        catch {
            onSaveError?.(new Error("Cannot switch to visual mode: the current YAML has structural errors that prevent parsing."));
        }
    }, [editor.yaml, onSaveError]);
    const confirmSwitchToVisual = useCallback(() => {
        setShowModeWarning(false);
        setMode("visual");
    }, []);
    const cancelSwitchToVisual = useCallback(() => {
        setShowModeWarning(false);
    }, []);
    const handleSwitchToCode = useCallback(() => {
        if (canvasDirty) {
            setShowDirtyPrompt(true);
            return;
        }
        setMode("code");
    }, [canvasDirty]);
    const confirmDiscardAndSwitchToCode = useCallback(() => {
        setShowDirtyPrompt(false);
        setMode("code");
        setCanvasDirty(false);
    }, []);
    const cancelSwitchToCode = useCallback(() => {
        setShowDirtyPrompt(false);
    }, []);
    // Canvas save handler (AD-T15-B3-002: save via YAML)
    const handleCanvasSave = useCallback(async (yamlStr) => {
        setCanvasIsSaving(true);
        editor.setYaml(yamlStr);
        // Allow React to propagate the YAML before saving
        setTimeout(async () => {
            const success = await editor.save();
            setCanvasIsSaving(false);
            setCanvasDirty(false);
            if (success) {
                onSaveSuccess?.();
            }
            else if (editor.saveError) {
                onSaveError?.(editor.saveError);
            }
        }, 0);
    }, [editor, onSaveSuccess, onSaveError]);
    const toggleRefinePanel = useCallback(() => {
        setShowRefinePanel((prev) => !prev);
        setPendingFixInstruction(undefined);
    }, []);
    const handleFixWithAI = useCallback(() => {
        const errorDiags = editor.diagnostics.filter((d) => d.severity === "error");
        if (errorDiags.length === 0)
            return;
        const lines = errorDiags.map((d, i) => `${i + 1}. ${d.message}`);
        const instruction = [
            "Fix the following validation errors in this workflow:",
            "",
            ...lines,
            "",
            "Please fix these issues and return the corrected workflow.",
        ].join("\n");
        setPendingFixInstruction(instruction);
        setShowRefinePanel(true);
    }, [editor.diagnostics]);
    const handleRefineAccept = useCallback((updatedYaml) => {
        editor.setYaml(updatedYaml);
        if (mode === "visual") {
            try {
                yamlToGraph(updatedYaml);
            }
            catch {
                // Canvas will re-parse on next render
            }
        }
    }, [editor, mode]);
    // Validation error mapping for canvas mode
    const nodeErrors = useMemo(() => {
        if (mode !== "visual")
            return new Map();
        const errorMap = new Map();
        for (const diag of editor.diagnostics) {
            if (diag.severity !== "error")
                continue;
            const match = diag.message.match(/task\s+"([^"]+)"/i) ??
                diag.message.match(/task\s+(\S+)/i);
            if (match) {
                const taskName = match[1];
                const existing = errorMap.get(taskName);
                if (existing) {
                    existing.push(diag.message);
                }
                else {
                    errorMap.set(taskName, [diag.message]);
                }
            }
        }
        return errorMap;
    }, [mode, editor.diagnostics]);
    const rootClassName = cn("stgm-workflow-editor flex flex-col", isFullPage && "fixed inset-0 z-50 bg-background", !isFullPage && "h-full", className);
    return (_jsxs("div", { className: rootClassName, children: [_jsxs("div", { className: "flex items-center justify-between border-b border-border px-3 py-2", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(ModeToggle, { mode: mode, onSwitchToCode: handleSwitchToCode, onSwitchToVisual: handleSwitchToVisual }), _jsx("div", { className: "mx-1 h-4 w-px bg-[var(--stgm-border,#d4d4d8)]", "aria-hidden": "true" }), _jsxs("button", { type: "button", onClick: toggleRefinePanel, className: cn("inline-flex items-center gap-1 rounded px-2 py-1 text-xs font-medium transition-colors", showRefinePanel
                                    ? "bg-primary/10 text-primary"
                                    : "text-muted-foreground hover:bg-muted hover:text-foreground"), "aria-pressed": showRefinePanel, "aria-label": "Refine with AI", children: [_jsx(RefineSparklesIcon, {}), "Refine"] }), _jsx("div", { className: "mx-1 h-4 w-px bg-[var(--stgm-border,#d4d4d8)]", "aria-hidden": "true" }), _jsx(ValidationSummary, { errorCount: editor.errorCount, warningCount: editor.warningCount }), editor.errorCount > 0 && (_jsxs("button", { type: "button", onClick: handleFixWithAI, className: cn("inline-flex items-center gap-1 rounded px-2 py-1 text-xs font-medium transition-colors", "text-muted-foreground hover:bg-muted hover:text-foreground"), "aria-label": "Fix validation errors with AI", children: [_jsx(FixSparklesIcon, {}), "Fix with AI"] })), (editor.isDirty || canvasDirty) && (_jsx("span", { className: "text-xs text-muted-foreground", children: "Unsaved changes" }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [mode === "code" && (editor.isDirty || editor.versionMessage) && (_jsx("input", { type: "text", value: editor.versionMessage, onChange: (e) => editor.setVersionMessage(e.target.value), placeholder: "Version message (optional)", disabled: editor.isSaving, className: cn("h-7 w-48 rounded border border-[var(--stgm-border,#d4d4d8)] bg-[var(--stgm-background,#fff)] px-2 text-xs", "text-[var(--stgm-foreground,#1a1a2e)] placeholder:text-[var(--stgm-muted-foreground,#a3a3a3)]", "focus:border-[var(--stgm-primary,#6366f1)] focus:outline-none focus:ring-1 focus:ring-[var(--stgm-primary,#6366f1)]", "disabled:opacity-40") })), mode === "code" && (_jsx("button", { type: "button", onClick: editor.reset, disabled: !editor.isDirty || editor.isSaving, className: cn("rounded px-2.5 py-1 text-xs font-medium transition-colors", "text-muted-foreground hover:bg-muted hover:text-foreground", "disabled:pointer-events-none disabled:opacity-40"), children: "Reset" })), mode === "code" && (_jsx("button", { type: "button", onClick: handleSave, disabled: !editor.isDirty || editor.isSaving || editor.errorCount > 0, className: cn("rounded bg-primary px-3 py-1 text-xs font-medium text-primary-foreground transition-colors", "hover:bg-primary/90", "disabled:pointer-events-none disabled:opacity-40"), children: editor.isSaving ? "Saving\u2026" : "Save" })), _jsxs("button", { type: "button", onClick: () => setShowExplainDialog(true), className: cn("inline-flex items-center gap-1 rounded px-2 py-1 text-xs font-medium transition-colors", "text-muted-foreground hover:bg-muted hover:text-foreground"), "aria-label": "Explain this workflow", children: [_jsx(ExplainIcon, {}), "Explain"] }), _jsx("button", { type: "button", onClick: toggleFullPage, className: "rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground", "aria-label": isFullPage ? "Exit full page" : "Full page", children: _jsx(ExpandIcon, { expanded: isFullPage }) })] })] }), editor.saveError && (_jsx("div", { className: "border-b border-destructive/20 bg-destructive/5 px-3 py-2 text-xs text-destructive", children: editor.saveError.message })), showModeWarning && (_jsx(ModeWarningDialog, { onConfirm: confirmSwitchToVisual, onCancel: cancelSwitchToVisual })), showDirtyPrompt && (_jsx(DirtyPromptDialog, { onDiscard: confirmDiscardAndSwitchToCode, onCancel: cancelSwitchToCode })), _jsx(WorkflowExplainDialog, { open: showExplainDialog, onOpenChange: setShowExplainDialog, org: org, currentYaml: editor.yaml }), _jsx("div", { className: "flex min-h-0 flex-1", children: mode === "code" ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "flex-1 overflow-hidden border-r border-border", children: _jsx(WorkflowYamlEditor, { value: editor.yaml, onChange: editor.setYaml, diagnostics: editor.diagnostics, className: "h-full rounded-none border-0" }) }), _jsx("div", { className: "w-[40%] min-w-[240px] overflow-hidden", children: showRefinePanel ? (_jsx(WorkflowRefinePanel, { org: org, currentYaml: editor.yaml, onAccept: handleRefineAccept, onClose: toggleRefinePanel, initialInstruction: pendingFixInstruction, className: "h-full" })) : (_jsx(WorkflowCodePreviewGraph, { yaml: editor.yaml, className: "h-full" })) })] })) : (_jsxs(_Fragment, { children: [_jsx(WorkflowCanvasEditor, { yaml: editor.yaml, onSave: handleCanvasSave, isSaving: canvasIsSaving, onDirtyChange: setCanvasDirty, nodeErrors: nodeErrors, layoutEngine: layoutEngine, className: showRefinePanel ? "w-[60%]" : "flex-1" }), showRefinePanel && (_jsx("div", { className: "w-[40%] min-w-[240px] overflow-hidden", children: _jsx(WorkflowRefinePanel, { org: org, currentYaml: editor.yaml, onAccept: handleRefineAccept, onClose: toggleRefinePanel, initialInstruction: pendingFixInstruction, className: "h-full" }) }))] })) })] }));
});
// ---------------------------------------------------------------------------
// Mode Toggle
// ---------------------------------------------------------------------------
function ModeToggle({ mode, onSwitchToCode, onSwitchToVisual, }) {
    const segmentClass = (active) => cn("rounded px-2.5 py-1 text-xs font-medium transition-colors", active
        ? "bg-[var(--stgm-primary,#6366f1)] text-[var(--stgm-primary-foreground,#fff)]"
        : "text-[var(--stgm-muted-foreground,#737373)] hover:bg-[var(--stgm-muted,#f5f5f5)] hover:text-[var(--stgm-foreground,#1a1a2e)]");
    return (_jsxs("div", { className: "flex items-center gap-0.5 rounded-md border border-[var(--stgm-border,#d4d4d8)] p-0.5", role: "tablist", "aria-label": "Editor mode", children: [_jsx("button", { type: "button", role: "tab", "aria-selected": mode === "code", onClick: onSwitchToCode, className: segmentClass(mode === "code"), children: "Code" }), _jsx("button", { type: "button", role: "tab", "aria-selected": mode === "visual", onClick: onSwitchToVisual, className: segmentClass(mode === "visual"), children: "Visual" })] }));
}
// ---------------------------------------------------------------------------
// Mode Warning Dialog
// ---------------------------------------------------------------------------
function ModeWarningDialog({ onConfirm, onCancel, }) {
    return (_jsx("div", { className: "border-b border-[var(--stgm-border,#e5e5e5)] bg-[var(--stgm-accent,#fffbeb)] px-3 py-2", children: _jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx("p", { className: "text-xs text-[var(--stgm-foreground,#1a1a2e)]", children: "Switching to visual mode will normalize YAML formatting. Comments and custom ordering will not be preserved." }), _jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [_jsx("button", { type: "button", onClick: onCancel, className: "rounded px-2 py-1 text-xs text-[var(--stgm-muted-foreground,#737373)] hover:bg-[var(--stgm-muted,#f5f5f5)]", children: "Cancel" }), _jsx("button", { type: "button", onClick: onConfirm, className: "rounded bg-[var(--stgm-primary,#6366f1)] px-2.5 py-1 text-xs font-medium text-[var(--stgm-primary-foreground,#fff)] hover:opacity-90", children: "Continue" })] })] }) }));
}
// ---------------------------------------------------------------------------
// Dirty Prompt Dialog
// ---------------------------------------------------------------------------
function DirtyPromptDialog({ onDiscard, onCancel, }) {
    return (_jsx("div", { className: "border-b border-[var(--stgm-border,#e5e5e5)] bg-[var(--stgm-accent,#fffbeb)] px-3 py-2", children: _jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx("p", { className: "text-xs text-[var(--stgm-foreground,#1a1a2e)]", children: "You have unsaved changes in the visual editor. Switching to code mode will discard them." }), _jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [_jsx("button", { type: "button", onClick: onCancel, className: "rounded px-2 py-1 text-xs text-[var(--stgm-muted-foreground,#737373)] hover:bg-[var(--stgm-muted,#f5f5f5)]", children: "Stay in Visual" }), _jsx("button", { type: "button", onClick: onDiscard, className: "rounded bg-[var(--stgm-destructive,#ef4444)] px-2.5 py-1 text-xs font-medium text-[var(--stgm-destructive-foreground,#fff)] hover:opacity-90", children: "Discard & Switch" })] })] }) }));
}
// ---------------------------------------------------------------------------
// Sub-components
// ---------------------------------------------------------------------------
function ValidationSummary({ errorCount, warningCount, }) {
    if (errorCount === 0 && warningCount === 0) {
        return (_jsxs("span", { className: "text-xs text-success", children: [_jsx(CheckCircleIcon, {}), " ", "Valid"] }));
    }
    return (_jsxs("div", { className: "flex items-center gap-2", children: [errorCount > 0 && (_jsxs("span", { className: "text-xs text-destructive", children: [errorCount, " ", errorCount === 1 ? "error" : "errors"] })), warningCount > 0 && (_jsxs("span", { className: "text-xs text-warning", children: [warningCount, " ", warningCount === 1 ? "warning" : "warnings"] }))] }));
}
function CheckCircleIcon() {
    return (_jsxs("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", className: "inline-block", children: [_jsx("circle", { cx: "8", cy: "8", r: "6.5" }), _jsx("path", { d: "M5.5 8l2 2 3-3.5" })] }));
}
function RefineSparklesIcon() {
    return (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "M8 2l1.5 4.5L14 8l-4.5 1.5L8 14l-1.5-4.5L2 8l4.5-1.5z" }) }));
}
function ExplainIcon() {
    return (_jsxs("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("circle", { cx: "8", cy: "8", r: "6.5" }), _jsx("path", { d: "M6.5 6a1.5 1.5 0 1 1 1.5 1.5V9" }), _jsx("circle", { cx: "8", cy: "11.5", r: "0.5", fill: "currentColor" })] }));
}
function FixSparklesIcon() {
    return (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "M8 2l1.5 4.5L14 8l-4.5 1.5L8 14l-1.5-4.5L2 8l4.5-1.5z" }) }));
}
function ExpandIcon({ expanded }) {
    return (_jsx("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: expanded ? (_jsxs(_Fragment, { children: [_jsx("path", { d: "M6 2H2v4M10 14h4v-4" }), _jsx("path", { d: "M2 2l5 5M14 14l-5-5" })] })) : (_jsxs(_Fragment, { children: [_jsx("path", { d: "M14 2h-4M2 14h4" }), _jsx("path", { d: "M14 2l-5 5M2 14l5-5" })] })) }));
}
//# sourceMappingURL=WorkflowEditorView.js.map