import { useCallback, useRef } from "react";

import { toServerSafeUIMessages } from "@phoenix/agent/chat/serverSafeMessages";
import type { AgentUIMessage } from "@phoenix/agent/chat/types";
import type { components, paths } from "@phoenix/api/__generated__/v1";
import { authApiFetch } from "@phoenix/api/authApiFetch";
import { useAgentStore } from "@phoenix/contexts/AgentContext";
import {
  getEffectiveAttachUserId,
  getEffectiveTraceRecordingSettings,
} from "@phoenix/store/agentStore";

const SUMMARIZE_PATH =
  "/agents/{agent_id}/sessions/{session_id}/summary" as const satisfies keyof paths;

const ASSISTANT_AGENT_ID = "assistant";

export type AgentModelSelection =
  components["schemas"]["_SummarizeRequest"]["model"];

async function fetchSummary({
  sessionId,
  modelSelection,
  messages,
  ingestTraces,
  exportRemoteTraces,
  attachUserId,
}: {
  sessionId: string;
  modelSelection: AgentModelSelection;
  messages: AgentUIMessage[];
  ingestTraces: boolean;
  exportRemoteTraces: boolean;
  attachUserId: boolean;
}): Promise<string> {
  const { data, response } = await authApiFetch.POST(SUMMARIZE_PATH, {
    params: {
      path: { agent_id: ASSISTANT_AGENT_ID, session_id: sessionId },
    },
    body: {
      messages: toServerSafeUIMessages(messages),
      ingestTraces,
      exportRemoteTraces,
      attachUserId,
      model: modelSelection,
    },
  });
  if (!response.ok || !data) {
    throw new Error(`summarize request failed: ${response.status}`);
  }
  return data.summary.trim();
}

/**
 * Hook that provides a function to asynchronously generate a session summary
 * after the first assistant response completes.
 *
 * The summary is generated by POSTing the session's full message history to
 * the dedicated session summary endpoint, which owns the prompt and the
 * structured-output tool schema. Fire-and-forget so the UI never blocks on
 * it.
 */
export function useGenerateSessionSummary() {
  const store = useAgentStore();
  const requestedSessionsRef = useRef(new Set<string>());

  const generateSummary = useCallback(
    ({
      sessionId,
      modelSelection,
    }: {
      sessionId: string;
      modelSelection: AgentModelSelection;
    }) => {
      if (requestedSessionsRef.current.has(sessionId)) return;

      const state = store.getState();
      const session = state.sessionMap[sessionId];
      if (!session) return;
      if (session.shortSummary) return;
      if (session.messages.length === 0) return;

      requestedSessionsRef.current.add(sessionId);

      const traceRecording = getEffectiveTraceRecordingSettings({
        agentsConfig: state.agentsConfig,
        observability: state.observability,
      });

      void fetchSummary({
        sessionId,
        modelSelection,
        messages: session.messages,
        ingestTraces: traceRecording.ingestTraces,
        exportRemoteTraces: traceRecording.exportRemoteTraces,
        attachUserId: getEffectiveAttachUserId({
          agentsConfig: state.agentsConfig,
          observability: state.observability,
        }),
      })
        .then((summary) => {
          if (summary) {
            store.getState().updateSessionSummary(sessionId, summary);
          }
        })
        .catch(() => {
          requestedSessionsRef.current.delete(sessionId);
        });
    },
    [store]
  );

  return { generateSummary };
}
