/**
 * Document-generation domain hooks (TaskMaster #214).
 *
 * The "הפקת מסמכים" card in the case "טיוטות והערות" tab fires two deterministic,
 * host-side generation actions through the CEO (structured-action wakeup):
 *   • party_claims_summary → an executive summary of the parties' claims
 *   • interim_draft        → a partial draft (blocks ה–ט, up to the discussion)
 *
 * Generation runs on the host (claude_session → claude -p), NOT in the container,
 * so the trigger endpoints return 202-accepted and the UI POLLS for completion:
 *   • summary → GET /api/cases/{n}/research/party-claims-summary (200 = ready)
 *   • interim draft → the exports list grows a "טיוטה-טענות_הצדדים_{N}.docx" file
 *     (polled via useExports — see exports.ts).
 *
 * The full-decision export ("הפק טיוטת החלטה מלאה") is NOT here — it reuses the
 * existing in-container useExportDocx (exports.ts), no LLM, no wakeup.
 */

import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { ApiError, apiRequest } from "./client";

/** Shape returned by the structured-action wakeup endpoints (#214). */
export type GenerateTriggerResult = {
  status: "ok" | "skipped" | "error";
  action?: string;
  issue_id?: string;
  ceo_id?: string;
  reason?: string;
  error?: string;
};

/** The two host-side background generation actions (poll target of the status chip). */
export type GenerateAction = "party_claims_summary" | "interim_draft";

export const generateKeys = {
  all: ["generate"] as const,
  partyClaimsSummary: (caseNumber: string) =>
    [...generateKeys.all, "party-claims-summary", caseNumber] as const,
  status: (caseNumber: string, action: GenerateAction) =>
    [...generateKeys.all, "status", action, caseNumber] as const,
};

/**
 * Server-derived background-run status (#227 ג). Reconstructed on the backend
 * from the CEO child issue + its heartbeat_run + the output artifact — so it is
 * correct after navigating away and back; it never depends on the browser having
 * stayed on the page. `started_at`/`finished_at` are server ISO-8601 UTC stamps,
 * so the client renders a correct elapsed time on return.
 */
export type GenerateState = "idle" | "queued" | "running" | "done" | "failed";

export type GenerateStatus = {
  case_number: string;
  action: GenerateAction;
  state: GenerateState;
  started_at: string | null;
  finished_at: string | null;
  output_ready: boolean;
  detail: string;
  issue_id: string | null;
};

export function useGenerateStatus(
  caseNumber: string | undefined,
  action: GenerateAction,
) {
  return useQuery<GenerateStatus>({
    queryKey: generateKeys.status(caseNumber ?? "", action),
    queryFn: ({ signal }) =>
      apiRequest<GenerateStatus>(
        `/api/cases/${caseNumber}/generate/${action}/status`,
        { signal },
      ),
    enabled: Boolean(caseNumber),
    // Poll only while a run is in flight; a terminal state stops the interval.
    refetchInterval: (query) => {
      const s = query.state.data?.state;
      return s === "running" || s === "queued" ? 5_000 : false;
    },
    staleTime: 2_000,
  });
}

/* ── Read: party-claims executive summary (poll target for button 1) ──
   404 (not generated yet) is a normal "not ready" state, not an error — we
   coerce it to null so the panel renders the empty/idle state cleanly. */
export type PartyClaimsSummary = { markdown: string } | null;

export function usePartyClaimsSummary(caseNumber: string | undefined) {
  return useQuery<PartyClaimsSummary>({
    queryKey: generateKeys.partyClaimsSummary(caseNumber ?? ""),
    queryFn: async ({ signal }) => {
      try {
        return await apiRequest<{ markdown: string }>(
          `/api/cases/${caseNumber}/research/party-claims-summary`,
          { signal },
        );
      } catch (e) {
        if (e instanceof ApiError && e.status === 404) return null;
        throw e;
      }
    },
    enabled: Boolean(caseNumber),
    staleTime: 5_000,
    retry: false,
  });
}

/* ── Trigger: party-claims executive summary (button 1) ── */
export function useGeneratePartyClaimsSummary(caseNumber: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: () =>
      apiRequest<GenerateTriggerResult>(
        `/api/cases/${caseNumber}/generate/party-claims-summary`,
        { method: "POST" },
      ),
    onSuccess: () => {
      // Start polling fresh — the file will appear after the host run completes,
      // and the status chip should pick up the new queued/running run.
      qc.invalidateQueries({
        queryKey: generateKeys.partyClaimsSummary(caseNumber),
      });
      qc.invalidateQueries({
        queryKey: generateKeys.status(caseNumber, "party_claims_summary"),
      });
    },
  });
}

/* ── Trigger: interim ("party-claims") partial draft (button 2) ── */
export function useGenerateInterimDraft(caseNumber: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: () =>
      apiRequest<GenerateTriggerResult>(
        `/api/cases/${caseNumber}/generate/interim-draft`,
        { method: "POST" },
      ),
    // The result lands in the exports list (טיוטה-טענות_הצדדים_*.docx, polled by
    // useExports); re-arm the status chip so it shows the new run immediately.
    onSuccess: () => {
      qc.invalidateQueries({
        queryKey: generateKeys.status(caseNumber, "interim_draft"),
      });
    },
  });
}
