/**
 * Attached-precedent hooks — user-supplied case-law quotes that
 * justify chair positions in the compose screen.
 *
 * Backed by POST/GET/DELETE /api/cases/{n}/precedents and the
 * cross-case library search at GET /api/precedents/search. The
 * optional PDF archive chains through POST .../upload-pdf before
 * precedent creation; that's a plain async function, not a mutation
 * hook, because it has no cache invalidation of its own.
 */

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

export type CasePrecedent = {
  id: string;
  case_id: string;
  section_id: string | null;
  quote: string;
  citation: string;
  chair_note: string;
  pdf_document_id: string | null;
  practice_area: PracticeArea | null;
  created_at: string;
  updated_at: string;
};

export type PrecedentCreateInput = {
  quote: string;
  citation: string;
  section_id?: string;
  chair_note?: string;
  pdf_document_id?: string;
};

export type LibraryMatch = {
  id: string;
  citation: string;
  quote: string;
  chair_note: string;
  practice_area: PracticeArea | null;
  created_at: string;
};

export const precedentKeys = {
  all: ["precedents"] as const,
  forCase: (caseNumber: string) =>
    [...precedentKeys.all, "case", caseNumber] as const,
  librarySearch: (q: string, area: string) =>
    [...precedentKeys.all, "library", area, q] as const,
};

export function useCasePrecedents(caseNumber: string | undefined) {
  return useQuery({
    queryKey: precedentKeys.forCase(caseNumber ?? ""),
    queryFn: ({ signal }) =>
      apiRequest<CasePrecedent[]>(
        `/api/cases/${caseNumber}/precedents`,
        { signal },
      ),
    enabled: Boolean(caseNumber),
    staleTime: 30_000,
  });
}

export function useCreatePrecedent(caseNumber: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (input: PrecedentCreateInput) =>
      apiRequest<CasePrecedent>(`/api/cases/${caseNumber}/precedents`, {
        method: "POST",
        body: input,
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: precedentKeys.forCase(caseNumber) });
      qc.invalidateQueries({ queryKey: [...precedentKeys.all, "library"] });
    },
  });
}

export function useDeletePrecedent(caseNumber: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (precedentId: string) =>
      apiRequest<{ deleted: boolean }>(`/api/precedents/${precedentId}`, {
        method: "DELETE",
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: precedentKeys.forCase(caseNumber) });
    },
  });
}

export function usePrecedentLibrarySearch(
  query: string,
  practiceArea: PracticeArea | null | undefined,
  enabled: boolean,
) {
  return useQuery({
    queryKey: precedentKeys.librarySearch(query, practiceArea ?? ""),
    queryFn: ({ signal }) => {
      const params = new URLSearchParams({ q: query });
      if (practiceArea) params.set("practice_area", practiceArea);
      return apiRequest<LibraryMatch[]>(
        `/api/precedents/search?${params.toString()}`,
        { signal },
      );
    },
    enabled: enabled && query.trim().length >= 2,
    staleTime: 10_000,
    placeholderData: (prev) => prev,
  });
}

/**
 * One-shot PDF archive upload. Returns the new document_id so the
 * caller can pass it into useCreatePrecedent. No cache invalidation
 * — we only care about the id as a handle.
 */
export async function uploadPrecedentPdf(
  caseNumber: string,
  file: File,
): Promise<{ document_id: string; filename: string }> {
  const fd = new FormData();
  fd.append("file", file);
  const res = await fetch(
    `/api/cases/${encodeURIComponent(caseNumber)}/precedents/upload-pdf`,
    { method: "POST", body: fd },
  );
  const parsed = await res.json().catch(() => null);
  if (!res.ok) {
    throw new ApiError(
      `Upload failed with ${res.status}`,
      res.status,
      parsed,
    );
  }
  return parsed as { document_id: string; filename: string };
}
