import type {
  ActivityEvent,
  BankTx,
  Client,
  ClientQuery,
  Invoice,
  InvoiceStatus,
  Settings,
  Suggestion,
} from "./ledger-types";

const API_BASE = import.meta.env.VITE_API_URL ?? "/api";
const USE_API = import.meta.env.VITE_USE_API !== "false";

export const isApiEnabled = () => USE_API;

async function request<T>(path: string, init?: RequestInit): Promise<T> {
  const response = await fetch(`${API_BASE}${path}`, {
    headers: {
      "Content-Type": "application/json",
      ...(init?.headers ?? {}),
    },
    ...init,
  });

  if (!response.ok) {
    const message = await response.text();
    throw new Error(message || `Request failed: ${response.status}`);
  }

  if (response.status === 204) {
    return undefined as T;
  }

  return (await response.json()) as T;
}

export interface LedgerStatePayload {
  clients: Client[];
  invoices: Invoice[];
  transactions: BankTx[];
  queries: ClientQuery[];
  activity: ActivityEvent[];
  settings: Settings;
}

export async function checkApiHealth(): Promise<boolean> {
  try {
    const response = await fetch(`${API_BASE}/health`);
    return response.ok;
  } catch {
    return false;
  }
}

export function fetchLedgerState() {
  return request<LedgerStatePayload>("/v1/state");
}

export function uploadDocumentApi(clientId: string, fileName: string, actor: string) {
  return request<Invoice>("/v1/documents/upload", {
    method: "POST",
    body: JSON.stringify({ clientId, fileName, actor }),
  });
}

export function updateInvoiceApi(id: string, patch: Partial<Invoice>) {
  return request<Invoice>(`/v1/invoices/${id}`, {
    method: "PATCH",
    body: JSON.stringify({ patch }),
  });
}

export function updateSuggestionApi(id: string, patch: Partial<Suggestion>) {
  return request<Invoice>(`/v1/invoices/${id}/suggestion`, {
    method: "PATCH",
    body: JSON.stringify({ patch }),
  });
}

export function setInvoiceStatusApi(id: string, status: InvoiceStatus) {
  return request<Invoice>(`/v1/invoices/${id}/status`, {
    method: "POST",
    body: JSON.stringify({ status }),
  });
}

export function approveInvoiceApi(id: string) {
  return request<Invoice>(`/v1/invoices/${id}/approve`, { method: "POST" });
}

export function rejectInvoiceApi(id: string) {
  return request<Invoice>(`/v1/invoices/${id}/reject`, { method: "POST" });
}

export function syncInvoiceApi(id: string) {
  return request<Invoice>(`/v1/invoices/${id}/sync`, { method: "POST" });
}

export function bulkApproveApi(ids: string[]) {
  return request<Invoice[]>("/v1/invoices/bulk/approve", {
    method: "POST",
    body: JSON.stringify({ ids }),
  });
}

export function bulkNeedsReviewApi(ids: string[]) {
  return request<Invoice[]>("/v1/invoices/bulk/needs-review", {
    method: "POST",
    body: JSON.stringify({ ids }),
  });
}

export function createQueryApi(clientId: string, question: string, invoiceId?: string) {
  return request<ClientQuery>("/v1/queries", {
    method: "POST",
    body: JSON.stringify({ clientId, question, invoiceId }),
  });
}

export function answerQueryApi(id: string, answer: string, proof?: string) {
  return request<ClientQuery>(`/v1/queries/${id}/answer`, {
    method: "POST",
    body: JSON.stringify({ answer, proof }),
  });
}

export function approveQueryApi(id: string) {
  return request<ClientQuery>(`/v1/queries/${id}/approve`, { method: "POST" });
}

export function setTxStatusApi(id: string, status: BankTx["status"]) {
  return request<BankTx>(`/v1/transactions/${id}/status`, {
    method: "POST",
    body: JSON.stringify({ status }),
  });
}

export function updateSettingsApi(patch: Partial<Settings>) {
  return request<Settings>("/v1/settings", {
    method: "PATCH",
    body: JSON.stringify({ patch }),
  });
}

export function setClientRuleApi(clientId: string, rule: string) {
  return request<Settings>(`/v1/settings/client-rules/${clientId}`, {
    method: "PATCH",
    body: JSON.stringify({ rule }),
  });
}
