// frontend/lib/mail/api.ts — mailApi (accounts/folders/list/detail/extract/reply/send)
import type {
  AccountFolder,
  Conversation,
  EmailDetail,
  EmailRow,
  ExtractAllResponse,
  ExtractKind,
  ExtractResponse,
  MailAccount,
  ReplyDraft,
  SendRequest,
  SendResponse,
} from "@/lib/types";

const J = { "Content-Type": "application/json" };
async function ok<T>(r: Response): Promise<T> {
  if (!r.ok) {
    let msg = `${r.status} ${r.statusText}`;
    try {
      const j = await r.json();
      if (j?.detail) msg = j.detail;
    } catch {
      /* 본문 없음 */
    }
    throw new Error(msg);
  }
  return r.json() as Promise<T>;
}

export const mailApi = {
  accounts: () =>
    fetch("/api/mail/accounts", { cache: "no-store" }).then((r) => ok<MailAccount[]>(r)),

  folders: () =>
    fetch("/api/mail/folders", { cache: "no-store" }).then((r) => ok<AccountFolder[]>(r)),

  list: (account: string | null, folder: string, q?: string) => {
    const qs = new URLSearchParams();
    if (account) qs.set("account", account);
    qs.set("folder", folder);
    if (q && q.trim()) qs.set("q", q.trim());
    return fetch(`/api/mail?${qs}`, { cache: "no-store" }).then((r) => ok<EmailRow[]>(r));
  },

  sent: (account: string | null) => {
    const qs = new URLSearchParams();
    if (account) qs.set("account", account);
    const suffix = qs.toString() ? `?${qs}` : "";
    return fetch(`/api/mail/sent${suffix}`, { cache: "no-store" }).then((r) => ok<EmailRow[]>(r));
  },

  drafts: (account: string | null) => {
    const qs = new URLSearchParams();
    if (account) qs.set("account", account);
    const suffix = qs.toString() ? `?${qs}` : "";
    return fetch(`/api/mail/drafts${suffix}`, { cache: "no-store" }).then((r) => ok<EmailRow[]>(r));
  },

  detail: (id: string) =>
    fetch(`/api/mail/${id}`, { cache: "no-store" }).then((r) => ok<EmailDetail>(r)),

  extract: (id: string, kind: ExtractKind, index = 0) =>
    fetch(`/api/mail/${id}/extract`, {
      method: "POST",
      headers: J,
      body: JSON.stringify({ kind, index }),
    }).then((r) => ok<ExtractResponse>(r)),

  extractAll: (id: string) =>
    fetch(`/api/mail/${id}/extract-all`, { method: "POST", headers: J, body: "{}" }).then((r) =>
      ok<ExtractAllResponse>(r),
    ),

  // 아리 비서: 안읽음 집중 메일 중 미분석분을 LLM 으로 배치 분석(점진).
  triageAnalyze: (limit = 6) =>
    fetch(`/api/mail/triage/analyze?limit=${limit}`, { method: "POST", headers: J, body: "{}" }).then(
      (r) => ok<{ analyzed: number; remaining: number; errors: number }>(r),
    ),

  // 아리 정리 기준 시각(이 시각 이후 도착한 새 메일만 정리) + 새 메일 수(읽음 무관).
  triageBaseline: () =>
    fetch("/api/mail/triage/baseline", { cache: "no-store" }).then((r) =>
      ok<{ since: string; count: number }>(r),
    ),

  // 기준 시각을 지금으로 재설정 — 이후 새 메일부터 다시.
  triageBaselineReset: () =>
    fetch("/api/mail/triage/baseline", { method: "POST", headers: J, body: "{}" }).then((r) =>
      ok<{ since: string; count: number }>(r),
    ),

  replyDraft: (id: string, reply_index: number | null) =>
    fetch(`/api/mail/${id}/reply-draft`, {
      method: "POST",
      headers: J,
      body: JSON.stringify({ reply_index }),
    }).then((r) => ok<ReplyDraft>(r)),

  send: (body: SendRequest) =>
    fetch("/api/mail/send", { method: "POST", headers: J, body: JSON.stringify(body) }).then((r) =>
      ok<SendResponse>(r),
    ),

  sync: () =>
    fetch("/api/mail/sync", { method: "POST", headers: J, body: "{}" }).then((r) =>
      ok<{ accounts: number; upserted: number }>(r),
    ),

  star: (id: string, starred: boolean) =>
    fetch(`/api/mail/${id}/star`, {
      method: "PATCH",
      headers: J,
      body: JSON.stringify({ starred }),
    }).then((r) => ok<EmailRow>(r)),

  setRead: (id: string, read: boolean) =>
    fetch(`/api/mail/${id}/read`, {
      method: "PATCH",
      headers: J,
      body: JSON.stringify({ read }),
    }).then((r) => ok<EmailRow>(r)),

  archive: (id: string) =>
    fetch(`/api/mail/${id}/archive`, { method: "POST", headers: J, body: "{}" }).then((r) =>
      ok<EmailRow>(r),
    ),

  unarchive: (id: string) =>
    fetch(`/api/mail/${id}/unarchive`, { method: "POST", headers: J, body: "{}" }).then((r) =>
      ok<EmailRow>(r),
    ),

  remove: (id: string) =>
    fetch(`/api/mail/${id}`, { method: "DELETE" }).then((r) => ok<{ ok: boolean; id: string }>(r)),

  // 첨부 다운로드용 URL(브라우저가 직접 내려받음)
  attachmentUrl: (id: string, attId: string) => `/api/mail/${id}/attachments/${attId}`,

  thread: (id: string) =>
    fetch(`/api/mail/${id}/thread`, { cache: "no-store" }).then((r) => ok<Conversation>(r)),

  labels: (id: string, add: string[], remove: string[]) =>
    fetch(`/api/mail/${id}/labels`, {
      method: "PATCH",
      headers: J,
      body: JSON.stringify({ add, remove }),
    }).then((r) => ok<EmailRow>(r)),

  bulk: (ids: string[], action: string) =>
    fetch("/api/mail/bulk", {
      method: "POST",
      headers: J,
      body: JSON.stringify({ ids, action }),
    }).then((r) => ok<{ ok: boolean; count: number; action: string }>(r)),
};
