export type AcademicPeriod = {
  id: number;
  name: string;
  displayName?: string | null;
  startDate: string; // YYYY-MM-DD
  endDate: string; // YYYY-MM-DD
  periodType: 'schuljahr' | 'semester' | 'trimester';
  isActive: boolean;
  isArchived: boolean;
  archivedAt?: string | null;
  archivedBy?: number | null;
  createdAt?: string;
  updatedAt?: string;
};

export type PeriodUsage = {
  linked_events: number;
  has_active_recurrence: boolean;
  blockers: string[];
};

async function api<T>(url: string, init?: RequestInit): Promise<T> {
  const res = await fetch(url, { credentials: 'include', ...init });
  if (!res.ok) {
    const text = await res.text();
    try {
      const err = JSON.parse(text);
      throw new Error(err.error || `HTTP ${res.status}`);
    } catch {
      throw new Error(`HTTP ${res.status}: ${text}`);
    }
  }
  return res.json();
}

export async function getAcademicPeriodForDate(date: Date): Promise<AcademicPeriod | null> {
  const iso = date.toISOString().slice(0, 10);
  const { period } = await api<{ period: AcademicPeriod | null }>(
    `/api/academic_periods/for_date?date=${iso}`
  );
  return period ?? null;
}

export async function listAcademicPeriods(options?: {
  includeArchived?: boolean;
  archivedOnly?: boolean;
}): Promise<AcademicPeriod[]> {
  const params = new URLSearchParams();
  if (options?.includeArchived) {
    params.set('includeArchived', '1');
  }
  if (options?.archivedOnly) {
    params.set('archivedOnly', '1');
  }
  const query = params.toString();
  const { periods } = await api<{ periods: AcademicPeriod[] }>(
    `/api/academic_periods${query ? `?${query}` : ''}`
  );
  return Array.isArray(periods) ? periods : [];
}

export async function getAcademicPeriod(id: number): Promise<AcademicPeriod> {
  const { period } = await api<{ period: AcademicPeriod }>(`/api/academic_periods/${id}`);
  return period;
}

export async function getActiveAcademicPeriod(): Promise<AcademicPeriod | null> {
  const { period } = await api<{ period: AcademicPeriod | null }>(`/api/academic_periods/active`);
  return period ?? null;
}

export async function createAcademicPeriod(payload: {
  name: string;
  displayName?: string;
  startDate: string;
  endDate: string;
  periodType: 'schuljahr' | 'semester' | 'trimester';
}): Promise<AcademicPeriod> {
  const { period } = await api<{ period: AcademicPeriod }>(`/api/academic_periods`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(payload),
  });
  return period;
}

export async function updateAcademicPeriod(
  id: number,
  payload: Partial<{
    name: string;
    displayName: string | null;
    startDate: string;
    endDate: string;
    periodType: 'schuljahr' | 'semester' | 'trimester';
  }>
): Promise<AcademicPeriod> {
  const { period } = await api<{ period: AcademicPeriod }>(`/api/academic_periods/${id}`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(payload),
  });
  return period;
}

export async function setActiveAcademicPeriod(id: number): Promise<AcademicPeriod> {
  const { period } = await api<{ period: AcademicPeriod }>(`/api/academic_periods/${id}/activate`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
  });
  return period;
}

export async function archiveAcademicPeriod(id: number): Promise<AcademicPeriod> {
  const { period } = await api<{ period: AcademicPeriod }>(`/api/academic_periods/${id}/archive`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
  });
  return period;
}

export async function restoreAcademicPeriod(id: number): Promise<AcademicPeriod> {
  const { period } = await api<{ period: AcademicPeriod }>(`/api/academic_periods/${id}/restore`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
  });
  return period;
}

export async function getAcademicPeriodUsage(id: number): Promise<PeriodUsage> {
  const { usage } = await api<{ usage: PeriodUsage }>(`/api/academic_periods/${id}/usage`);
  return usage;
}

export async function deleteAcademicPeriod(id: number): Promise<void> {
  await api(`/api/academic_periods/${id}`, {
    method: 'DELETE',
    headers: { 'Content-Type': 'application/json' },
  });
}
