"use client";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { ExecutionPhase } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
import { getUserMessage } from "@stigmer/sdk";
import { useCreateSession } from "../session/useCreateSession";
import { useCreateAgentExecution } from "../execution/useCreateAgentExecution";
import { useExecutionStream } from "../execution/useExecutionStream";
import { isTerminalPhase } from "../execution/execution-phases";
import { useConversationStoreRef } from "../internal/store";
import { extractWorkflowYaml, } from "./extract-workflow-yaml";
import { WORKFLOW_ARCHITECT_RESPONSE_SCHEMA } from "./architect-response-schema";
const AGENT_REF = { org: "", slug: "workflow-architect" };
const MIN_INSTRUCTION_LENGTH = 5;
/**
 * Behavior hook that orchestrates agent-powered workflow refinement
 * using the built-in Workflow Architect system agent.
 *
 * Manages a multi-turn conversation within a single Session:
 * - First turn creates a Session + AgentExecution
 * - Subsequent turns reuse the Session (conversational context)
 * - Each turn streams agent messages via {@link useExecutionStream}
 * - YAML is extracted from agent responses via {@link extractWorkflowYaml}
 *
 * The `currentYaml` prop is captured at send-time (ref-based, not reactive)
 * and included in the message only when it differs from the last-sent version.
 *
 * Framework-agnostic (DD-004), referentially stable returns (DD-010).
 *
 * @example
 * ```tsx
 * const flow = useRefineWorkflowFlow({
 *   org: "acme",
 *   currentYaml: editor.yaml,
 *   onError: (msg) => toast.error(msg),
 * });
 *
 * <WorkflowRefinePanel flow={flow} onAccept={...} onClose={...} />
 * ```
 */
export function useRefineWorkflowFlow(options) {
    const { org, currentYaml, onError } = options;
    const [phase, setPhase] = useState("idle");
    const [executionId, setExecutionId] = useState(null);
    const [completedExecutions, setCompletedExecutions] = useState([]);
    const [extracted, setExtracted] = useState(null);
    const [error, setError] = useState(null);
    const orgRef = useRef(org);
    orgRef.current = org;
    const yamlRef = useRef(currentYaml);
    yamlRef.current = currentYaml;
    const onErrorRef = useRef(onError);
    onErrorRef.current = onError;
    const sessionIdRef = useRef(null);
    const lastSentYamlRef = useRef(null);
    const prevTerminalRef = useRef(false);
    const { create: createSession } = useCreateSession();
    const { create: createExecution } = useCreateAgentExecution();
    const conversationStore = useConversationStoreRef();
    const stream = useExecutionStream(executionId, {
        store: conversationStore,
    });
    // -------------------------------------------------------------------------
    // Terminal phase detection — extract YAML or transition to ready
    // -------------------------------------------------------------------------
    useEffect(() => {
        if (phase !== "streaming")
            return;
        const isTerminal = stream.phase !== ExecutionPhase.EXECUTION_PHASE_UNSPECIFIED &&
            isTerminalPhase(stream.phase);
        if (isTerminal && !prevTerminalRef.current) {
            prevTerminalRef.current = true;
            if (stream.execution) {
                setCompletedExecutions((prev) => [...prev, stream.execution]);
            }
            // Primary: read from structured output (deterministic)
            const structuredOutput = stream.execution?.status?.structuredOutput;
            if (structuredOutput) {
                const action = structuredOutput.action;
                const yaml = structuredOutput.yaml;
                const explanation = structuredOutput.explanation;
                if (action === "generated_yaml" && yaml) {
                    setExtracted({ yaml, explanation: explanation ?? "" });
                    setPhase("complete");
                }
                else if (action === "clarification" || action === "no_changes") {
                    setPhase("ready");
                }
                else {
                    setPhase("ready");
                }
            }
            else {
                // Fallback: regex extraction (backward compat / extraction failure)
                const result = extractWorkflowYaml(stream.execution);
                if (result) {
                    setExtracted(result);
                    setPhase("complete");
                }
                else {
                    setPhase("ready");
                }
            }
            setExecutionId(null);
        }
    }, [phase, stream.phase, stream.execution]);
    // -------------------------------------------------------------------------
    // Stream error surfacing
    // -------------------------------------------------------------------------
    useEffect(() => {
        if (stream.error && phase === "streaming") {
            const msg = getUserMessage(stream.error, "Agent stream interrupted");
            setPhase("error");
            setError(msg);
            onErrorRef.current?.(msg);
        }
    }, [stream.error, phase]);
    // -------------------------------------------------------------------------
    // Build the message with optional YAML context
    // -------------------------------------------------------------------------
    const buildMessage = useCallback((instruction) => {
        const capturedYaml = yamlRef.current;
        const yamlChanged = capturedYaml !== lastSentYamlRef.current;
        lastSentYamlRef.current = capturedYaml;
        if (yamlChanged && capturedYaml) {
            return ("Here is the current workflow YAML:\n\n" +
                "```yaml\n" +
                capturedYaml +
                "\n```\n\n" +
                instruction);
        }
        return instruction;
    }, []);
    // -------------------------------------------------------------------------
    // Send a refinement instruction
    // -------------------------------------------------------------------------
    const sendInstruction = useCallback(async (instruction) => {
        const trimmed = instruction.trim();
        if (trimmed.length < MIN_INSTRUCTION_LENGTH) {
            setError(`Instruction must be at least ${MIN_INSTRUCTION_LENGTH} characters`);
            return;
        }
        if (phase !== "idle" &&
            phase !== "ready" &&
            phase !== "complete" &&
            phase !== "error") {
            return;
        }
        setPhase("starting");
        setError(null);
        setExtracted(null);
        prevTerminalRef.current = false;
        try {
            let activeSessionId = sessionIdRef.current;
            if (!activeSessionId) {
                const { sessionId: newSessionId } = await createSession({
                    org: orgRef.current,
                    agentRef: { ...AGENT_REF, org: orgRef.current },
                });
                sessionIdRef.current = newSessionId;
                activeSessionId = newSessionId;
            }
            const message = buildMessage(trimmed);
            const { executionId: newExecutionId } = await createExecution({
                org: orgRef.current,
                sessionId: activeSessionId,
                message,
                structuredOutputSchema: WORKFLOW_ARCHITECT_RESPONSE_SCHEMA,
            });
            setExecutionId(newExecutionId);
            setPhase("streaming");
        }
        catch (err) {
            const msg = getUserMessage(err, "Failed to start the Workflow Architect agent");
            setPhase("error");
            setError(msg);
            onErrorRef.current?.(msg);
        }
    }, [phase, createSession, createExecution, buildMessage]);
    // -------------------------------------------------------------------------
    // Accept / discard extracted YAML
    // -------------------------------------------------------------------------
    const acceptResult = useCallback(() => {
        if (phase !== "complete" || !extracted)
            return null;
        const yaml = extracted.yaml;
        setExtracted(null);
        setPhase("ready");
        return yaml;
    }, [phase, extracted]);
    const discardResult = useCallback(() => {
        if (phase !== "complete")
            return;
        setExtracted(null);
        setPhase("ready");
    }, [phase]);
    // -------------------------------------------------------------------------
    // Reset all state
    // -------------------------------------------------------------------------
    const reset = useCallback(() => {
        setPhase("idle");
        setExecutionId(null);
        setCompletedExecutions([]);
        setExtracted(null);
        setError(null);
        sessionIdRef.current = null;
        lastSentYamlRef.current = null;
        prevTerminalRef.current = false;
    }, []);
    // -------------------------------------------------------------------------
    // Referentially stable return (DD-010)
    // -------------------------------------------------------------------------
    return useMemo(() => ({
        phase,
        completedExecutions,
        activeExecution: stream.execution,
        isStreaming: stream.isStreaming || stream.isConnecting,
        extractedYaml: extracted?.yaml ?? null,
        explanation: extracted?.explanation ?? null,
        error,
        sendInstruction,
        acceptResult,
        discardResult,
        reset,
    }), [
        phase,
        completedExecutions,
        stream.execution,
        stream.isStreaming,
        stream.isConnecting,
        extracted,
        error,
        sendInstruction,
        acceptResult,
        discardResult,
        reset,
    ]);
}
//# sourceMappingURL=useRefineWorkflowFlow.js.map