"use client";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useDefaultAgent } from "../agent";
import { useStigmer } from "../hooks";
import { useWorkspaceEntries } from "../workspace";
import { useSessionVariables } from "../execution/useSessionVariables";
import { fromProtoHarness } from "../models/harness";
import { Harness } from "@stigmer/protos/ai/stigmer/agentic/session/v1/enum_pb";
import { useSessionConversation } from "./useSessionConversation";
import { useAgentRefFromSession } from "./useAgentRefFromSession";
import { usePersistedModel } from "./usePersistedModel";
/**
 * Well-known Daytona sandbox workspace root. Used as the SDK safety-net
 * normalization target for cloud sessions (git-repo workspace entries).
 */
const DAYTONA_WORKSPACE_ROOT = "/home/daytona/workspace";
/**
 * Orchestrates the session page experience.
 *
 * Composes `useSessionConversation` with agent resolution, workspace
 * synchronization, model persistence, and follow-up submission logic.
 * Returns everything a session page needs to render its UI without
 * duplicating domain orchestration.
 *
 * Framework-agnostic — works identically in Next.js, Vite, Tauri, or
 * any React environment. The consumer provides layout, error states,
 * and loading skeletons.
 *
 * @example
 * ```tsx
 * const flow = useSessionPageFlow({ sessionId: "ses_abc", org: "acme" });
 *
 * if (flow.conv.isLoading) return <Spinner />;
 * if (flow.conv.loadError) return <ErrorView error={flow.conv.loadError} />;
 *
 * return (
 *   <>
 *     <MessageThread
 *       executions={flow.conv.completedExecutions}
 *       activeStreamExecution={flow.conv.activeStreamExecution}
 *       sandboxWorkspaceRoot={flow.sandboxWorkspaceRoot}
 *     />
 *     <SessionComposer
 *       onSubmit={flow.handleSubmit}
 *       isSubmitting={flow.conv.isSending}
 *       disabled={!flow.conv.canSendFollowUp}
 *       workspace={flow.workspace}
 *       agentRef={flow.agentRef}
 *       onAgentRefChange={flow.setAgentRef}
 *       onAgentResolutionChange={flow.setResolution}
 *       defaultModelId={flow.model[0]}
 *       onModelChange={flow.model[1]}
 *     />
 *   </>
 * );
 * ```
 */
export function useSessionPageFlow(options) {
    const { sessionId, org } = options;
    const stigmer = useStigmer();
    const conv = useSessionConversation(sessionId, org);
    const harness = fromProtoHarness(conv.session?.spec?.harness ?? Harness.UNSPECIFIED);
    const [persistedModelId, setPersistedModelId] = usePersistedModel({ harness });
    const lastExecModelId = useMemo(() => {
        const lastExec = conv.completedExecutions.at(-1);
        return lastExec?.spec?.executionConfig?.modelName || undefined;
    }, [conv.completedExecutions]);
    const modelId = persistedModelId ?? lastExecModelId;
    const model = [modelId, setPersistedModelId];
    const workspace = useWorkspaceEntries();
    const sessionVariables = useSessionVariables();
    const [mcpServerUsages, setMcpServerUsages] = useState([]);
    const [skillRefs, setSkillRefs] = useState([]);
    const initialSyncDone = useRef(false);
    // -------------------------------------------------------------------------
    // Agent — derive from session, allow mid-session changes
    // -------------------------------------------------------------------------
    const sessionInstanceId = conv.session?.spec?.agentInstanceId ?? null;
    const { agentRef: derivedAgentRef } = useAgentRefFromSession(sessionInstanceId);
    const { agent: defaultAgent, isLoading: isDefaultAgentLoading } = useDefaultAgent(org);
    const [agentRef, setAgentRef] = useState(null);
    const [resolution, setResolution] = useState(null);
    const [agentInitDone, setAgentInitDone] = useState(false);
    if (!agentInitDone && derivedAgentRef && sessionInstanceId && !isDefaultAgentLoading) {
        setAgentInitDone(true);
        const isDefault = defaultAgent &&
            derivedAgentRef.org === defaultAgent.metadata?.org &&
            derivedAgentRef.slug === defaultAgent.metadata?.slug;
        if (!isDefault) {
            setAgentRef(derivedAgentRef);
            setResolution({ mode: "saved", instanceId: sessionInstanceId });
        }
    }
    // -------------------------------------------------------------------------
    // Workspace — sync entries from session on first load
    // -------------------------------------------------------------------------
    useEffect(() => {
        if (!conv.session || initialSyncDone.current)
            return;
        initialSyncDone.current = true;
        const protoEntries = conv.session.spec?.workspaceEntries ?? [];
        for (const entry of protoEntries) {
            if (entry.source?.source.case === "gitRepo") {
                const { url, branch } = entry.source.source.value;
                workspace.addGitRepo(url, branch || undefined);
            }
            else if (entry.source?.source.case === "localPath") {
                workspace.addLocalPath(entry.source.source.value.path);
            }
        }
    }, [conv.session, workspace]);
    // -------------------------------------------------------------------------
    // Follow-up submission with agent override
    // -------------------------------------------------------------------------
    const handleSubmit = useCallback(async (message, selectedModel, context) => {
        let agentInstanceIdOverride;
        if (resolution) {
            if (resolution.mode === "saved" &&
                resolution.instanceId !== sessionInstanceId) {
                agentInstanceIdOverride = resolution.instanceId;
            }
            else if (resolution.mode === "direct" && agentRef) {
                const agent = await stigmer.agent.getByReference(agentRef);
                const defaultId = agent.status?.defaultInstanceId;
                if (defaultId && defaultId !== sessionInstanceId) {
                    agentInstanceIdOverride = defaultId;
                }
            }
        }
        conv.sendFollowUp(message, {
            agentInstanceId: agentInstanceIdOverride,
            modelName: selectedModel ?? modelId,
            workspaceEntries: workspace.hasEntries
                ? workspace.toInput()
                : undefined,
            mcpServerUsages: mcpServerUsages.length > 0 ? mcpServerUsages : undefined,
            skillRefs: skillRefs.length > 0 ? skillRefs : undefined,
            runtimeEnv: context?.runtimeEnv,
            attachments: context?.attachments,
        });
        sessionVariables.clear();
    }, [conv.sendFollowUp, modelId, workspace, mcpServerUsages, skillRefs, sessionVariables.clear, resolution, agentRef, sessionInstanceId, stigmer]);
    // -------------------------------------------------------------------------
    // Derived display state
    // -------------------------------------------------------------------------
    const displayExecution = useMemo(() => {
        if (conv.activeStreamExecution)
            return conv.activeStreamExecution;
        const completed = conv.completedExecutions;
        return completed.length > 0 ? completed[completed.length - 1] : null;
    }, [conv.activeStreamExecution, conv.completedExecutions]);
    const allExecutions = useMemo(() => [
        ...conv.completedExecutions,
        ...(conv.activeStreamExecution ? [conv.activeStreamExecution] : []),
    ], [conv.completedExecutions, conv.activeStreamExecution]);
    const sandboxWorkspaceRoot = useMemo(() => {
        const entries = conv.workspaceEntries;
        const hasGitRepo = entries.some((e) => e.source?.source.case === "gitRepo");
        return hasGitRepo ? DAYTONA_WORKSPACE_ROOT : undefined;
    }, [conv.workspaceEntries]);
    return {
        conv,
        harness,
        model,
        agentRef,
        setAgentRef,
        resolution,
        setResolution,
        mcpServerUsages,
        setMcpServerUsages,
        skillRefs,
        setSkillRefs,
        workspace,
        sessionVariables,
        handleSubmit,
        displayExecution,
        allExecutions,
        sandboxWorkspaceRoot,
    };
}
//# sourceMappingURL=useSessionPageFlow.js.map