/**
 * React Query mutations for transaction-case API calls.
 */

import { useMutation, useQueryClient } from '@tanstack/react-query';
import { captureCaught } from '@/lib/observability';

import { qk } from '@/lib/query/keys';

async function apiFetch<T>(url: string, init?: RequestInit): Promise<T> {
  const csrfToken =
    document.cookie
      .split('; ')
      .find((c) => c.startsWith('csrf_token='))
      ?.split('=')[1] ?? '';

  const res = await fetch(url, {
    ...init,
    headers: {
      'Content-Type': 'application/json',
      'x-csrf-token': csrfToken,
      ...(init?.headers ?? {}),
    },
  });
  if (!res.ok) {
    const body = (await res.json().catch((err) => {
      captureCaught(err, {
        scope: 'features.transaction-cases.useCaseMutations',
        severity: 'info',
      });
      return {};
    })) as { error?: string; code?: string };
    throw Object.assign(new Error(body?.error ?? `HTTP ${res.status}`), { code: body?.code });
  }
  return res.json() as Promise<T>;
}

// ─── Open case ────────────────────────────────────────────────────────────────

export interface OpenCaseInput {
  purchaseId: string;
  category: string;
  customerAskOutcome: string;
  customerAskAmountCents: number | null;
  description: string;
  escapeRequested: boolean;
}

export function useOpenCase() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (input: OpenCaseInput) =>
      apiFetch<{ ok: true; caseId: string; status: string }>('/api/cases', {
        method: 'POST',
        body: JSON.stringify(input),
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: qk.cases('customer') });
      qc.invalidateQueries({ queryKey: qk.cases('vendor') });
    },
  });
}

// ─── Post message ─────────────────────────────────────────────────────────────

export interface PostMessageInput {
  caseId: string;
  text: string;
  visibility?: 'public' | 'vendor_internal';
}

export function usePostMessage() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ caseId, ...body }: PostMessageInput) =>
      apiFetch<{ ok: true; messageId: string }>(`/api/cases/${caseId}/messages`, {
        method: 'POST',
        body: JSON.stringify(body),
      }),
    onSuccess: (_data, { caseId }) => {
      qc.invalidateQueries({ queryKey: qk.case(caseId) });
    },
  });
}

// ─── Vendor offer ─────────────────────────────────────────────────────────────

export interface PostOfferInput {
  caseId: string;
  outcome: string;
  amountCents: number | null;
  reason: string;
}

export function usePostOffer() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ caseId, ...body }: PostOfferInput) =>
      apiFetch<{ ok: true; offerId: string; autoExecuted: boolean }>(`/api/cases/${caseId}/offer`, {
        method: 'POST',
        body: JSON.stringify(body),
      }),
    onSuccess: (_data, { caseId }) => {
      qc.invalidateQueries({ queryKey: qk.case(caseId) });
      qc.invalidateQueries({ queryKey: qk.cases('customer') });
      qc.invalidateQueries({ queryKey: qk.cases('vendor') });
    },
  });
}

// ─── Customer decide ──────────────────────────────────────────────────────────

export interface DecideOfferInput {
  caseId: string;
  offerId: string;
  decision: 'accept' | 'reject';
}

export function useDecideOffer() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ caseId, ...body }: DecideOfferInput) =>
      apiFetch<{ ok: true; status: string }>(`/api/cases/${caseId}/decide`, {
        method: 'POST',
        body: JSON.stringify(body),
      }),
    onSuccess: (_data, { caseId }) => {
      qc.invalidateQueries({ queryKey: qk.case(caseId) });
      qc.invalidateQueries({ queryKey: qk.cases('customer') });
      qc.invalidateQueries({ queryKey: qk.cases('vendor') });
    },
  });
}

// ─── Reopen ───────────────────────────────────────────────────────────────────

export interface ReopenCaseInput {
  caseId: string;
  reason: string;
}

export function useReopenCase() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ caseId, reason }: ReopenCaseInput) =>
      apiFetch<{ ok: true; status: string }>(`/api/cases/${caseId}/reopen`, {
        method: 'POST',
        body: JSON.stringify({ reason }),
      }),
    onSuccess: (_data, { caseId }) => {
      qc.invalidateQueries({ queryKey: qk.case(caseId) });
      qc.invalidateQueries({ queryKey: qk.cases('customer') });
      qc.invalidateQueries({ queryKey: qk.cases('vendor') });
    },
  });
}
