// frontend/lib/calendar/api.ts — calendarApi (week/day/meeting/materialize/focus/events)
import type {
  WeekBundle,
  DayBundle,
  Meeting,
  MaterializeResult,
  FocusBlock,
  CalEvent,
  EventWrite,
} from "./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 calendarApi = {
  week: () => fetch("/api/calendar/week", { cache: "no-store" }).then((r) => ok<WeekBundle>(r)),

  createEvent: (body: EventWrite) =>
    fetch("/api/calendar/events", { method: "POST", headers: J, body: JSON.stringify(body) }).then(
      (r) => ok<CalEvent>(r),
    ),

  updateEvent: (id: string, body: EventWrite) =>
    fetch(`/api/calendar/events/${id}`, {
      method: "PATCH",
      headers: J,
      body: JSON.stringify(body),
    }).then((r) => ok<CalEvent>(r)),

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

  rsvp: (id: string, status: "accepted" | "declined" | "tentative") =>
    fetch(`/api/calendar/events/${id}/rsvp`, {
      method: "POST",
      headers: J,
      body: JSON.stringify({ status }),
    }).then((r) => ok<CalEvent>(r)),

  day: (d: number) =>
    fetch(`/api/calendar/day/${d}`, { cache: "no-store" }).then((r) => ok<DayBundle>(r)),

  meeting: (id: string) =>
    fetch(`/api/calendar/meetings/${id}`, { cache: "no-store" }).then((r) => ok<Meeting>(r)),

  materialize: (mid: string, idx: number) =>
    fetch(`/api/calendar/meetings/${mid}/actions/${idx}/materialize`, { method: "POST" }).then(
      (r) => ok<MaterializeResult>(r),
    ),

  materializeAll: (mid: string) =>
    fetch(`/api/calendar/meetings/${mid}/actions/materialize-all`, { method: "POST" }).then((r) =>
      ok<MaterializeResult[]>(r),
    ),

  focusSuggest: (day: number, min_minutes = 20, create = false) =>
    fetch("/api/calendar/focus/suggest", {
      method: "POST",
      headers: J,
      body: JSON.stringify({ day, min_minutes, create }),
    }).then((r) => ok<{ day: number; suggestions: FocusBlock[]; created: boolean }>(r)),
};
