/**
 * Typed client for the @void-nav/api custom-pages backend.
 *
 * Custom pages are user-created documentation pages that live in the API's
 * SQLite store. They are rendered dynamically from stored HTML and appear in
 * the docs sidebar under "Custom Pages".
 */

const BASE = '/api/pages';

export interface CustomPage {
  id: string;
  slug: string;
  title: string;
  icon: string;
  blurb: string;
  content: string;
  html: string;
  beautified: boolean;
  createdAt: string;
  updatedAt: string;
}

export interface CustomPageInput {
  title: string;
  icon?: string;
  blurb?: string;
  content?: string;
}

class ApiError extends Error {
  constructor(
    message: string,
    readonly status: number,
  ) {
    super(message);
    this.name = 'ApiError';
  }
}

async function req<T>(path: string, init?: RequestInit): Promise<T> {
  const res = await fetch(`${BASE}${path}`, {
    ...init,
    headers: { 'Content-Type': 'application/json', ...(init?.headers ?? {}) },
  });
  if (!res.ok) {
    let detail = `${res.status} ${res.statusText}`;
    try {
      const body = await res.json();
      if (body?.error) detail = body.error;
    } catch {
      /* non-JSON error body; keep status text */
    }
    throw new ApiError(detail, res.status);
  }
  if (res.status === 204) return undefined as T;
  return (await res.json()) as T;
}

export const pagesApi = {
  list: () => req<CustomPage[]>(''),
  get: (slug: string) => req<CustomPage>(`/${encodeURIComponent(slug)}`),

  create: (input: CustomPageInput) =>
    req<CustomPage>('', { method: 'POST', body: JSON.stringify(input) }),

  update: (id: string, input: Partial<CustomPageInput>) =>
    req<CustomPage>(`/${id}`, { method: 'PATCH', body: JSON.stringify(input) }),

  remove: (id: string) => req<void>(`/${id}`, { method: 'DELETE' }),

  beautify: (id: string) =>
    req<CustomPage>(`/${id}/beautify`, { method: 'POST' }),
};
