// api.ts から分割（挙動不変）: スペースカレンダー（予定 + 日次集計 + クロススペース）。
import { BASE } from './client';

// --- Space calendar (予定 + 日次集計) ---
// spec: docs/superpowers/specs/2026-06-19-space-calendar-design.md

export interface CalendarEvent {
  id: number;
  spaceId: string;
  ownerId: string | null;
  date: string;             // 開始日 YYYY-MM-DD（ローカル日付）
  endDate: string | null;   // 終了日 YYYY-MM-DD。null = 単日
  time: string | null;      // 開始 HH:MM。null = 終日
  endTime: string | null;   // 終了 HH:MM。null = 終了時刻なし（time が null なら常に null）
  title: string;
  description: string | null;
  createdBy: 'user' | 'agent';
  sourceTaskId: number | null;
  createdAt: string;
  updatedAt?: string;
}

export interface CalendarDayCounts {
  taskCount: number;
  eventCount: number;
}

export interface CalendarMonth {
  days: Record<string, CalendarDayCounts>;
  events: CalendarEvent[];
}

export interface CalendarDayTask {
  id: number;
  title: string;
  state: string;
  status: string | null;
  createdAt: string;
}

export interface CalendarDayFile {
  name: string;
  path: string;
  size: number;
  mtime: string;
}

export interface CalendarDay {
  tasks: CalendarDayTask[];
  files: CalendarDayFile[];
  events: CalendarEvent[];
}

// ── V2: cross-space calendar ──────────────────────────────────────────────
export interface CrossCalendarSpace {
  id: string;
  name: string;
  color: string;   // brand_color、無ければ spaceColor(id) で導出済み
}

export interface CrossCalendarMonth {
  // days[date][spaceId] = そのスペースのその日の集計
  days: Record<string, Record<string, CalendarDayCounts>>;
  events: CalendarEvent[];   // 各イベントは spaceId を持つ
  spaces: CrossCalendarSpace[];
}

export async function fetchCrossSpaceCalendarMonth(
  month: string,
  tzOffset: number,
): Promise<CrossCalendarMonth> {
  const params = new URLSearchParams({ month, tz_offset: String(tzOffset) });
  const res = await fetch(`${BASE}/calendar/cross?${params.toString()}`);
  const data = await res.json();
  if (!res.ok) throw new Error(data?.error ?? 'Failed to fetch calendar');
  return data as CrossCalendarMonth;
}

export async function fetchSpaceCalendarMonth(
  spaceId: string,
  month: string,
  tzOffset: number,
): Promise<CalendarMonth> {
  const params = new URLSearchParams({ month, tz_offset: String(tzOffset) });
  const res = await fetch(`${BASE}/local/spaces/${spaceId}/calendar?${params.toString()}`);
  const data = await res.json();
  if (!res.ok) throw new Error(data?.error ?? 'Failed to fetch calendar');
  return data as CalendarMonth;
}

export async function fetchSpaceCalendarDay(
  spaceId: string,
  date: string,
  tzOffset: number,
): Promise<CalendarDay> {
  const params = new URLSearchParams({ date, tz_offset: String(tzOffset) });
  const res = await fetch(`${BASE}/local/spaces/${spaceId}/calendar/day?${params.toString()}`);
  const data = await res.json();
  if (!res.ok) throw new Error(data?.error ?? 'Failed to fetch calendar day');
  return data as CalendarDay;
}

export async function createCalendarEvent(
  spaceId: string,
  input: { date: string; endDate?: string | null; time?: string | null; endTime?: string | null; title: string; description?: string | null },
): Promise<CalendarEvent> {
  const { endDate, endTime, ...rest } = input;
  const res = await fetch(`${BASE}/local/spaces/${spaceId}/calendar/events`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ ...rest, end_date: endDate ?? null, end_time: endTime ?? null }),
  });
  const data = await res.json();
  if (!res.ok) throw new Error(data?.error ?? 'Failed to create event');
  return data as CalendarEvent;
}

export async function updateCalendarEvent(
  spaceId: string,
  eventId: number,
  patch: { date?: string; endDate?: string | null; time?: string | null; endTime?: string | null; title?: string; description?: string | null },
): Promise<CalendarEvent> {
  const { endDate, endTime, ...rest } = patch;
  const body: Record<string, unknown> = { ...rest };
  if (endDate !== undefined) body.end_date = endDate;
  if (endTime !== undefined) body.end_time = endTime;
  const res = await fetch(`${BASE}/local/spaces/${spaceId}/calendar/events/${eventId}`, {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });
  const data = await res.json();
  if (!res.ok) throw new Error(data?.error ?? 'Failed to update event');
  return data as CalendarEvent;
}

export async function deleteCalendarEvent(spaceId: string, eventId: number): Promise<void> {
  const res = await fetch(`${BASE}/local/spaces/${spaceId}/calendar/events/${eventId}`, {
    method: 'DELETE',
  });
  if (!res.ok && res.status !== 204) {
    const err = await res.json().catch(() => ({ error: res.statusText }));
    throw new Error(err.error || res.statusText);
  }
}
