"use client";
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { cn } from "@stigmer/theme";
import { WorkflowTaskStatus, ExecutionPhase } from "@stigmer/protos/ai/stigmer/agentic/workflowexecution/v1/enum_pb";
import { WorkflowTaskKind } from "@stigmer/protos/ai/stigmer/agentic/workflow/v1/enum_pb";
import { useWorkflowExecution } from "./useWorkflowExecution.js";
import { useWorkflowExecutionEventStream } from "./useWorkflowExecutionEventStream.js";
import { useWorkflowExecutionArtifacts } from "./useWorkflowExecutionArtifacts.js";
import { useWorkflowExecutionActions } from "./useWorkflowExecutionActions.js";
import { WorkflowExecutionHeader } from "./WorkflowExecutionHeader.js";
import { WorkflowExecutionTimeline } from "./WorkflowExecutionTimeline.js";
import { WaterfallTimeline } from "./waterfall/index.js";
import { WorkflowExecutionCostPanel } from "./WorkflowExecutionCostPanel.js";
import { WorkflowExecutionArtifactPanel } from "./WorkflowExecutionArtifactPanel.js";
import { WorkflowRepairCard } from "./WorkflowRepairCard.js";
import { WorkflowExecutionGraph } from "./WorkflowExecutionGraph.js";
import { ExecutionInspector } from "./execution-inspector/index.js";
import { ExecutionComparisonPicker } from "./execution-comparison/ExecutionComparisonPicker.js";
import { ExecutionComparisonView } from "./execution-comparison/ExecutionComparisonView.js";
import { WorkflowExecutionApprovalCard } from "./WorkflowExecutionApprovalCard.js";
import { WorkflowFileReviewList } from "./WorkflowFileReviewList.js";
import { ResizableSplit } from "../internal/ResizableSplit.js";
/**
 * Top-level composed viewer for a single workflow execution.
 *
 * Wires together all execution hooks and sub-components into a
 * two-region layout: an event timeline (main area) and a context
 * sidebar (tasks, budget, artifacts).
 *
 * This component is designed to work identically whether rendered
 * in the Stigmer Console or embedded in a third-party dashboard.
 * No dependencies on Console routing, auth, or layout context.
 *
 * @example
 * ```tsx
 * <WorkflowExecutionViewer
 *   executionId="wfx_abc123"
 *   onNavigateToAgentExecution={(id) => router.push(`/sessions/${id}`)}
 * />
 * ```
 */
export const WorkflowExecutionViewer = memo(function WorkflowExecutionViewer({ executionId, org, onNavigateToAgentExecution, onNavigateToWorkflowEditor, additionalActions, headerActions, nodesDraggable, className, }) {
    const { execution, isLoading: isLoadingExecution, error: executionError, refetch: refetchExecution, } = useWorkflowExecution(executionId);
    const phase = execution?.status?.phase;
    const isRunning = phase === ExecutionPhase.EXECUTION_PENDING || phase === ExecutionPhase.EXECUTION_IN_PROGRESS;
    const { events, taskStates, costSummary, streamState, totalTasks, error: streamError, reconnect, } = useWorkflowExecutionEventStream(executionId, {
        executionPhase: phase,
    });
    // Fallback: when the event log is empty but the execution has task status
    // snapshots (e.g., due to event persistence failure), derive task states
    // from the status.tasks array so the panel is never completely blank.
    const fallbackTaskStates = useMemo(() => {
        if (events.length > 0 || streamState.stage !== "complete")
            return null;
        const tasks = execution?.status?.tasks;
        if (!tasks || tasks.length === 0)
            return null;
        const map = new Map();
        for (const t of tasks) {
            const name = t.taskName;
            if (!name)
                continue;
            let status = "pending";
            switch (t.status) {
                case WorkflowTaskStatus.WORKFLOW_TASK_IN_PROGRESS:
                    status = "running";
                    break;
                case WorkflowTaskStatus.WORKFLOW_TASK_COMPLETED:
                    status = "completed";
                    break;
                case WorkflowTaskStatus.WORKFLOW_TASK_FAILED:
                    status = "failed";
                    break;
                case WorkflowTaskStatus.WORKFLOW_TASK_SKIPPED:
                    status = "skipped";
                    break;
                case WorkflowTaskStatus.WORKFLOW_TASK_WAITING_APPROVAL:
                    status = "waiting_approval";
                    break;
                default:
                    status = "pending";
            }
            let durationMs = 0;
            if (t.startedAt && t.completedAt) {
                durationMs = new Date(t.completedAt).getTime() - new Date(t.startedAt).getTime();
            }
            map.set(name, {
                taskName: name,
                taskKind: WorkflowTaskKind.workflow_task_kind_unspecified,
                status,
                durationMs,
                costMicros: BigInt(0),
                tokensUsed: BigInt(0),
                attemptNumber: 1,
                error: t.error ?? "",
                childExecutionId: "",
                agentSlug: "",
                currentToolName: "",
                messagesCount: 0,
                toolCallsCount: 0,
            });
        }
        return map;
    }, [events.length, streamState.stage, execution?.status?.tasks]);
    const effectiveTaskStates = fallbackTaskStates ?? taskStates;
    const effectiveTotalTasks = fallbackTaskStates ? fallbackTaskStates.size : totalTasks;
    const executionDurationMs = useMemo(() => {
        const startedAt = execution?.status?.startedAt;
        const completedAt = execution?.status?.completedAt;
        if (startedAt && completedAt) {
            return new Date(completedAt).getTime() - new Date(startedAt).getTime();
        }
        return undefined;
    }, [execution?.status?.startedAt, execution?.status?.completedAt]);
    const { artifacts, isLoading: isLoadingArtifacts, } = useWorkflowExecutionArtifacts(executionId);
    const actions = useWorkflowExecutionActions(executionId, {
        onSuccess: refetchExecution,
    });
    const [selectedTaskName, setSelectedTaskName] = useState(null);
    const [showDiagnosis, setShowDiagnosis] = useState(false);
    const [showComparePicker, setShowComparePicker] = useState(false);
    const [compareTargetId, setCompareTargetId] = useState(null);
    const handleDiagnose = useCallback(() => {
        setShowDiagnosis(true);
    }, []);
    const handleCloseDiagnosis = useCallback(() => {
        setShowDiagnosis(false);
    }, []);
    const handleOpenComparePicker = useCallback(() => {
        setShowComparePicker(true);
    }, []);
    const handleCloseComparePicker = useCallback(() => {
        setShowComparePicker(false);
    }, []);
    const handleCompareConfirm = useCallback((compareId) => {
        setCompareTargetId(compareId);
        setShowComparePicker(false);
    }, []);
    const handleExitComparison = useCallback(() => {
        setCompareTargetId(null);
    }, []);
    const handleApplyFix = useCallback((yaml) => {
        if (onNavigateToWorkflowEditor) {
            const slug = execution?.metadata?.slug ?? execution?.metadata?.name ?? "";
            onNavigateToWorkflowEditor(yaml, slug);
        }
    }, [onNavigateToWorkflowEditor, execution]);
    // Loading state
    if (isLoadingExecution) {
        return (_jsx("div", { className: cn("flex h-full items-center justify-center", className), children: _jsx(LoadingSkeleton, {}) }));
    }
    // Error state
    if (executionError) {
        return (_jsxs("div", { className: cn("flex h-full flex-col items-center justify-center gap-3 px-6", className), children: [_jsx("p", { className: "text-sm text-destructive", children: executionError.message }), _jsx("button", { type: "button", onClick: refetchExecution, className: "rounded border border-border px-3 py-1.5 text-xs font-medium text-foreground hover:bg-muted", children: "Retry" })] }));
    }
    // Not found
    if (!execution) {
        return (_jsx("div", { className: cn("flex h-full items-center justify-center text-sm text-muted-foreground", className), children: "Execution not found" }));
    }
    return (_jsxs("div", { className: cn("flex h-full flex-col overflow-hidden", className), children: [_jsx(WorkflowExecutionHeader, { execution: execution, streamState: streamState, costSummary: costSummary, actions: actions, onDiagnose: org ? handleDiagnose : undefined, isDiagnosing: showDiagnosis, onCompare: handleOpenComparePicker, headerActions: headerActions }), _jsx(ExecutionComparisonPicker, { open: showComparePicker, workflowId: execution.spec?.workflowId ?? execution.spec?.workflowInstanceId ?? "", baseExecutionId: executionId, basePhase: phase ?? 0, onConfirm: handleCompareConfirm, onClose: handleCloseComparePicker }), actions.error && (_jsxs("div", { className: "flex items-center gap-2 border-b border-destructive/20 bg-destructive/5 px-4 py-2", children: [_jsx("p", { className: "flex-1 text-xs text-destructive", children: actions.error.message }), _jsx("button", { type: "button", onClick: actions.clearError, className: "shrink-0 rounded border border-destructive/30 px-2 py-1 text-xs text-destructive hover:bg-destructive/10", children: "Dismiss" })] })), compareTargetId ? (_jsx("div", { className: "min-h-0 flex-1 overflow-y-auto p-4", children: _jsx(ExecutionComparisonView, { baseExecutionId: executionId, compareExecutionId: compareTargetId, onBack: handleExitComparison }) })) : (_jsxs(_Fragment, { children: [streamError && (_jsxs("div", { className: "flex items-center gap-2 border-b border-destructive/20 bg-destructive/5 px-4 py-2", children: [_jsx("p", { className: "flex-1 text-xs text-destructive", children: streamError.message }), _jsx("button", { type: "button", onClick: reconnect, className: "shrink-0 rounded border border-destructive/30 px-2 py-1 text-xs text-destructive hover:bg-destructive/10", children: "Reconnect" })] })), _jsxs("div", { className: "flex min-h-0 flex-1 flex-col", children: [_jsx(ResizableSplit, { defaultSize: showDiagnosis ? 440 : 384, minSize: 280, maxSize: 800, storageKey: "stgm-wf-exec-inspector-width", primary: _jsx(WorkflowExecutionGraph, { executionId: executionId, execution: execution, taskStates: effectiveTaskStates, onTaskSelect: setSelectedTaskName, onAutoSelectTask: setSelectedTaskName, followExecution: isRunning, nodesDraggable: nodesDraggable, className: "h-full" }), secondary: _jsx("aside", { className: "flex h-full flex-col overflow-hidden", children: showDiagnosis && org ? (_jsx(WorkflowRepairCard, { executionId: executionId, org: org, onApplyFix: onNavigateToWorkflowEditor ? handleApplyFix : undefined, onClose: handleCloseDiagnosis, className: "h-full" })) : (_jsxs("div", { className: "flex min-h-0 flex-1 flex-col overflow-hidden", children: [_jsx(ExecutionInspector, { selectedTaskName: selectedTaskName, events: events, taskStates: effectiveTaskStates, taskSnapshots: execution?.status?.tasks ?? undefined, onNavigateToAgentExecution: onNavigateToAgentExecution, pendingApprovals: execution?.status?.pendingApprovals, onSubmitApproval: actions.submitApproval, approvalSubmittingToolCallIds: actions.approvalSubmittingToolCallIds, approvalErrorsByToolCallId: actions.approvalErrorsByToolCallId, onSubmitTaskApproval: actions.submitTaskApproval, taskApprovalSubmittingTaskNames: actions.taskApprovalSubmittingTaskNames, taskApprovalErrorsByTaskName: actions.taskApprovalErrorsByTaskName, className: "min-h-0 flex-1" }), _jsx("div", { className: "border-t border-[var(--stgm-border,#e5e5e5)]", children: _jsx(WorkflowExecutionCostPanel, { costSummary: costSummary }) }), artifacts.length > 0 && (_jsx("div", { className: "border-t border-[var(--stgm-border,#e5e5e5)]", children: _jsx(WorkflowExecutionArtifactPanel, { artifacts: artifacts }) })), additionalActions && (_jsx("div", { className: "border-t border-[var(--stgm-border,#e5e5e5)] px-3 py-2", children: additionalActions }))] })) }) }), _jsx(ExecutionBottomPanel, { events: events, streamState: streamState, executionStartIso: execution.status?.startedAt ?? "", executionDurationMs: executionDurationMs, selectedTaskName: selectedTaskName, onTaskSelect: setSelectedTaskName, onNavigateToAgentExecution: onNavigateToAgentExecution, taskStates: effectiveTaskStates, onSubmitTaskApproval: actions.submitTaskApproval, taskApprovalSubmittingTaskNames: actions.taskApprovalSubmittingTaskNames, taskApprovalErrorsByTaskName: actions.taskApprovalErrorsByTaskName, pendingApprovals: execution?.status?.pendingApprovals, onSubmitApproval: actions.submitApproval, approvalSubmittingToolCallIds: actions.approvalSubmittingToolCallIds, approvalErrorsByToolCallId: actions.approvalErrorsByToolCallId, pendingFileReviews: execution?.status?.pendingFileReviews, onSubmitFileDecision: actions.submitFileDecision, fileDecisionSubmittingKeys: actions.fileDecisionSubmittingKeys, fileDecisionErrorsByKey: actions.fileDecisionErrorsByKey })] })] }))] }));
});
function LoadingSkeleton() {
    return (_jsxs("div", { className: "flex w-full flex-col gap-3 p-6", children: [_jsx("div", { className: "h-4 w-48 animate-pulse rounded bg-muted" }), _jsx("div", { className: "h-3 w-32 animate-pulse rounded bg-muted" }), _jsx("div", { className: "mt-4 space-y-2", children: Array.from({ length: 5 }, (_, i) => (_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "size-3 animate-pulse rounded-full bg-muted" }), _jsx("div", { className: "h-3 flex-1 animate-pulse rounded bg-muted" })] }, i))) })] }));
}
function ExecutionBottomPanel({ events, streamState, executionStartIso, executionDurationMs, selectedTaskName, onTaskSelect, onNavigateToAgentExecution, taskStates, onSubmitTaskApproval, taskApprovalSubmittingTaskNames, taskApprovalErrorsByTaskName, pendingApprovals, onSubmitApproval, approvalSubmittingToolCallIds, approvalErrorsByToolCallId, pendingFileReviews, onSubmitFileDecision, fileDecisionSubmittingKeys, fileDecisionErrorsByKey, }) {
    const [collapsed, setCollapsed] = useState(false);
    const [activeTab, setActiveTab] = useState("waterfall");
    const prevHitlCountRef = useRef(0);
    const approvalCount = pendingApprovals?.length ?? 0;
    const fileReviewCount = pendingFileReviews?.length ?? 0;
    // Both HITL kinds (tool approvals + file reviews) share the one "Approvals" tab.
    const hitlCount = approvalCount + fileReviewCount;
    const hasHitl = hitlCount > 0;
    // Auto-switch to the Approvals tab when a new HITL gate (approval or file
    // review) arrives; leave it when everything is resolved.
    useEffect(() => {
        if (hitlCount > prevHitlCountRef.current && hitlCount > 0) {
            setActiveTab("approvals");
            setCollapsed(false);
        }
        if (hitlCount === 0 && activeTab === "approvals") {
            setActiveTab("waterfall");
        }
        prevHitlCountRef.current = hitlCount;
    }, [hitlCount, activeTab]);
    return (_jsxs("div", { className: "border-t border-[var(--stgm-border,#e5e5e5)]", children: [_jsxs("div", { className: "flex items-center gap-0 border-b border-[var(--stgm-border,#e5e5e5)]", children: [_jsx("button", { type: "button", onClick: () => setCollapsed(!collapsed), className: "flex items-center gap-1.5 px-3 py-1.5 text-xs text-[var(--stgm-muted-foreground,#737373)] hover:bg-[var(--stgm-muted,#f5f5f5)]", "aria-label": collapsed ? "Expand bottom panel" : "Collapse bottom panel", children: _jsx("svg", { width: "10", height: "10", viewBox: "0 0 10 10", className: cn("transition-transform", !collapsed && "rotate-180"), "aria-hidden": "true", children: _jsx("path", { d: "M2 4L5 7L8 4", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) }), _jsx(TabButton, { label: "Waterfall", isActive: activeTab === "waterfall", onClick: () => { setActiveTab("waterfall"); setCollapsed(false); } }), _jsx(TabButton, { label: `Events (${events.length})`, isActive: activeTab === "events", onClick: () => { setActiveTab("events"); setCollapsed(false); } }), hasHitl && (_jsx(TabButton, { label: `Approvals (${hitlCount})`, isActive: activeTab === "approvals", onClick: () => { setActiveTab("approvals"); setCollapsed(false); } }))] }), !collapsed && (_jsxs("div", { className: "h-52", children: [activeTab === "waterfall" && (_jsx(WaterfallTimeline, { events: events, streamState: streamState, executionStartIso: executionStartIso, executionDurationMs: executionDurationMs, selectedTaskName: selectedTaskName, onTaskSelect: onTaskSelect, className: "h-full" })), activeTab === "events" && (_jsx(WorkflowExecutionTimeline, { events: events, streamState: streamState, onNavigateToAgentExecution: onNavigateToAgentExecution, taskStates: taskStates, onSubmitTaskApproval: onSubmitTaskApproval, taskApprovalSubmittingTaskNames: taskApprovalSubmittingTaskNames, taskApprovalErrorsByTaskName: taskApprovalErrorsByTaskName, className: "h-full" })), activeTab === "approvals" && (_jsx("div", { className: "h-full overflow-y-auto px-4 py-3", children: _jsxs("div", { className: "space-y-3", children: [pendingApprovals && onSubmitApproval && pendingApprovals.map((pa) => {
                                    const toolCallId = pa.approval?.toolCallId ?? "";
                                    return (_jsx(WorkflowExecutionApprovalCard, { prompt: pa.approval?.message || `Tool "${pa.approval?.toolName}" requires approval`, toolCallId: toolCallId, approvers: [], timeoutSeconds: 0, onSubmitApproval: onSubmitApproval, isSubmitting: approvalSubmittingToolCallIds.has(toolCallId), error: approvalErrorsByToolCallId.get(toolCallId) ?? null }, toolCallId || pa.childAgentExecutionId));
                                }), pendingFileReviews && pendingFileReviews.length > 0 && (_jsx(WorkflowFileReviewList, { pendingFileReviews: pendingFileReviews, onSubmitFileDecision: onSubmitFileDecision, submittingDecisionKeys: fileDecisionSubmittingKeys, decisionErrors: fileDecisionErrorsByKey, onNavigateToAgentExecution: onNavigateToAgentExecution }))] }) }))] }))] }));
}
function TabButton({ label, isActive, onClick, }) {
    return (_jsx("button", { type: "button", onClick: onClick, className: cn("px-3 py-1.5 text-xs font-medium transition-colors", isActive
            ? "border-b-2 border-[var(--stgm-primary,#3b82f6)] text-[var(--stgm-foreground,#171717)]"
            : "text-[var(--stgm-muted-foreground,#737373)] hover:text-[var(--stgm-foreground,#171717)]"), children: label }));
}
//# sourceMappingURL=WorkflowExecutionViewer.js.map