import type { AppNotification } from './notifications-types';

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

async function handle<T>(res: Response): Promise<T> {
  if (res.status === 204) return undefined as T;
  const data = (await res.json().catch(() => null)) as
    | T
    | { message: string | string[] }
    | null;
  if (!res.ok) {
    const msg =
      (data as { message?: string | string[] } | null)?.message ??
      `Request failed (${res.status})`;
    throw new NotificationsClientError(
      Array.isArray(msg) ? msg.join('\n') : msg,
      res.status,
    );
  }
  return data as T;
}

export const notificationsClient = {
  async list(): Promise<AppNotification[]> {
    return handle<AppNotification[]>(await fetch('/api/notifications', { cache: 'no-store' }));
  },
  async unreadCount(): Promise<number> {
    const r = await handle<{ count: number }>(
      await fetch('/api/notifications/unread-count', { cache: 'no-store' }),
    );
    return r.count;
  },
  async markRead(id: string): Promise<AppNotification> {
    return handle<AppNotification>(
      await fetch(`/api/notifications/${id}/read`, { method: 'POST' }),
    );
  },
  async markAllRead(): Promise<number> {
    const r = await handle<{ updated: number }>(
      await fetch('/api/notifications/read-all', { method: 'POST' }),
    );
    return r.updated;
  },
};
