/**
 * Exports domain hooks — draft DOCX files for a case.
 */

import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { apiRequest } from "./client";
import { casesKeys } from "./cases";
import { decisionBlocksKeys } from "./decision-blocks";

export type ExportFile = {
  filename: string;
  size: number;
  created_at: number;
  is_final: boolean;
};

export type ActiveDraft = {
  active_draft_path: string | null;
  filename: string | null;
  exists: boolean;
};

export type Revision = {
  id: string;
  type: "insert_after" | "insert_before" | "replace" | "delete";
  anchor_bookmark: string;
  content?: string;
  style?: "body" | "heading" | "quote" | "bold";
  reason?: string;
};

export type UploadResult = {
  filename: string;
  size: number;
  version: number;
  active_draft?: string;
  bookmarks_added?: string[];
  missing_blocks?: string[];
  structural_fallback?: string[];
  apply_status?: string;
};

export type ReviseResult = {
  status: string;
  output_path: string;
  version: number;
  applied: number;
  failed: number;
  results: { id: string; status: string; error?: string }[];
};

export const exportsKeys = {
  all: ["exports"] as const,
  list: (caseNumber: string) =>
    [...exportsKeys.all, "list", caseNumber] as const,
  activeDraft: (caseNumber: string) =>
    [...exportsKeys.all, "active-draft", caseNumber] as const,
  bookmarks: (caseNumber: string) =>
    [...exportsKeys.all, "bookmarks", caseNumber] as const,
};

export function useExports(caseNumber: string | undefined) {
  return useQuery({
    queryKey: exportsKeys.list(caseNumber ?? ""),
    queryFn: ({ signal }) =>
      apiRequest<ExportFile[]>(`/api/cases/${caseNumber}/exports`, { signal }),
    enabled: Boolean(caseNumber),
    staleTime: 5_000,
    refetchInterval: 5_000,
  });
}

export function useExportDocx(caseNumber: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: () =>
      apiRequest<{ status: string; path: string; message: string }>(
        `/api/cases/${caseNumber}/export-docx`,
        { method: "POST" },
      ),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: exportsKeys.list(caseNumber) });
      qc.invalidateQueries({ queryKey: casesKeys.detail(caseNumber) });
      // CAS-2 (INV-IA2): export flips active_draft → source_of_truth='docx';
      // the block viewer must re-fetch or its sync warning stays hidden.
      qc.invalidateQueries({ queryKey: decisionBlocksKeys.case(caseNumber) });
    },
  });
}

export function useUploadDraft(caseNumber: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: async (file: File): Promise<UploadResult> => {
      const form = new FormData();
      form.append("file", file);
      const res = await fetch(`/api/cases/${caseNumber}/exports/upload`, {
        method: "POST",
        body: form,
      });
      if (!res.ok) {
        const err = await res.json().catch(() => ({ detail: "שגיאה בהעלאה" }));
        throw new Error(err.detail ?? "שגיאה בהעלאה");
      }
      return res.json() as Promise<UploadResult>;
    },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: exportsKeys.list(caseNumber) });
      qc.invalidateQueries({ queryKey: exportsKeys.activeDraft(caseNumber) });
      qc.invalidateQueries({ queryKey: exportsKeys.bookmarks(caseNumber) });
      // CAS-1 (INV-IA2): uploading a DOCX draft makes it the source-of-truth;
      // refresh the block viewer so the divergence banner appears immediately.
      qc.invalidateQueries({ queryKey: decisionBlocksKeys.case(caseNumber) });
    },
  });
}

export function useActiveDraft(caseNumber: string | undefined) {
  return useQuery({
    queryKey: exportsKeys.activeDraft(caseNumber ?? ""),
    queryFn: ({ signal }) =>
      apiRequest<ActiveDraft>(`/api/cases/${caseNumber}/active-draft`, { signal }),
    enabled: Boolean(caseNumber),
    staleTime: 5_000,
  });
}

export function useBookmarks(caseNumber: string | undefined) {
  return useQuery({
    queryKey: exportsKeys.bookmarks(caseNumber ?? ""),
    queryFn: ({ signal }) =>
      apiRequest<{
        status: string;
        active_draft_path?: string;
        bookmarks?: string[];
      }>(`/api/cases/${caseNumber}/exports/bookmarks`, { signal }),
    enabled: Boolean(caseNumber),
    staleTime: 10_000,
  });
}

export function useReviseDraft(caseNumber: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (payload: { revisions: Revision[]; author?: string }) =>
      apiRequest<ReviseResult>(`/api/cases/${caseNumber}/exports/revise`, {
        method: "POST",
        body: payload,
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: exportsKeys.list(caseNumber) });
      qc.invalidateQueries({ queryKey: exportsKeys.activeDraft(caseNumber) });
    },
  });
}

export function useRetrofit(caseNumber: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (filename: string) =>
      apiRequest<{
        status: string;
        active_draft_path: string;
        bookmarks_added: string[];
        missing_blocks: string[];
        structural_fallback?: string[];
      }>(`/api/cases/${caseNumber}/exports/${filename}/retrofit`, {
        method: "POST",
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: exportsKeys.activeDraft(caseNumber) });
      qc.invalidateQueries({ queryKey: exportsKeys.bookmarks(caseNumber) });
    },
  });
}

export function useDeleteDraft(caseNumber: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (filename: string) =>
      apiRequest<{ deleted: boolean; filename: string }>(
        `/api/cases/${caseNumber}/exports/${filename}`,
        { method: "DELETE" },
      ),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: exportsKeys.list(caseNumber) });
    },
  });
}

/* ── Chair's signed final decision — clean upload path + staged pipeline ── */

export type FinalUploadResult = {
  final_filename: string;
  training_copy: string;
  pair_id: string | null;
  draft_words: number;
  final_words: number;
  chair_name?: string;
  library?: {
    enrolled: boolean;
    case_law_id?: string | null;
    linked?: number;
    missing_flagged?: number;
    error?: string;
    citation_error?: string;
  };
  status: string;
};

export type FinalTaskResult = {
  status: string;
  sub_issue_id?: string;
  curator_id?: string;
  reason?: string;
  error?: string;
};

/** Upload Dafna's signed final decision (distinct from "upload a revised draft"). */
export function useUploadFinalDecision(caseNumber: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: async (file: File): Promise<FinalUploadResult> => {
      const form = new FormData();
      form.append("file", file);
      const res = await fetch(`/api/cases/${caseNumber}/final/upload`, {
        method: "POST",
        body: form,
      });
      if (!res.ok) {
        const err = await res
          .json()
          .catch(() => ({ detail: "שגיאה בהעלאת ההחלטה הסופית" }));
        throw new Error(err.detail ?? "שגיאה בהעלאת ההחלטה הסופית");
      }
      return res.json() as Promise<FinalUploadResult>;
    },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: exportsKeys.list(caseNumber) });
      qc.invalidateQueries({ queryKey: casesKeys.detail(caseNumber) });
    },
  });
}

/** Staged step 1 — voice learning (Opus distillation + DeepSeek+Gemini style panel). */
export function useRunFinalLearning(caseNumber: string) {
  return useMutation({
    mutationFn: () =>
      apiRequest<FinalTaskResult>(
        `/api/cases/${caseNumber}/final/run-learning`,
        { method: "POST" },
      ),
  });
}

/** Staged step 2 — halacha validation (cited-halacha extraction + 3-judge panel). */
export function useRunFinalHalacha(caseNumber: string) {
  return useMutation({
    mutationFn: () =>
      apiRequest<FinalTaskResult>(
        `/api/cases/${caseNumber}/final/run-halacha`,
        { method: "POST" },
      ),
  });
}

export function useMarkFinal(caseNumber: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (filename: string) =>
      apiRequest<{ final_filename: string; status: string }>(
        `/api/cases/${caseNumber}/exports/${filename}/mark-final`,
        { method: "POST" },
      ),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: exportsKeys.list(caseNumber) });
      qc.invalidateQueries({ queryKey: casesKeys.detail(caseNumber) });
    },
  });
}
