import { CloudError } from './client';

/** Client for the shared-campaign + member-owned-character API (same-origin /api). */

const TOKEN_KEY = 'ttrpg-cloud-token';
const base = () => `${location.origin}/api`;
function authHeaders(): Record<string, string> {
  const t = localStorage.getItem(TOKEN_KEY);
  return t ? { authorization: `Bearer ${t}` } : {};
}

export interface CloudCampaignInfo { id: string; name: string; system: string; role: 'owner' | 'member'; inviteCode?: string }
export interface CloudCharInfo { id: string; name: string; ownerUserId: string; mine: boolean; data: string; updatedAt: number }

async function req<T>(path: string, init?: RequestInit): Promise<T> {
  let res: Response;
  try {
    res = await fetch(`${base()}${path}`, { ...init, headers: { 'content-type': 'application/json', ...authHeaders(), ...(init?.headers ?? {}) } });
  } catch {
    throw new CloudError('Could not reach the server.');
  }
  if (res.status === 401) throw new CloudError('Sign in to use shared campaigns.');
  const data = (await res.json().catch(() => ({}))) as Record<string, unknown> & { message?: string };
  if (!res.ok) throw new CloudError(data.message ?? 'Request failed.');
  return data as T;
}

export function listCloudCampaigns(): Promise<CloudCampaignInfo[]> {
  return req<CloudCampaignInfo[]>('/campaigns');
}
export function createCloudCampaign(name: string, system: string): Promise<CloudCampaignInfo> {
  return req<CloudCampaignInfo>('/campaigns', { method: 'POST', body: JSON.stringify({ name, system }) });
}
export function joinCloudCampaign(inviteCode: string): Promise<CloudCampaignInfo> {
  return req<CloudCampaignInfo>('/campaigns/join', { method: 'POST', body: JSON.stringify({ inviteCode }) });
}
export function publishCharacter(campaignId: string, character: { id: string; name: string; data: string }): Promise<{ ok: boolean }> {
  return req('/characters', { method: 'PUT', body: JSON.stringify({ campaignId, character }) });
}
export function listCloudCharacters(campaignId: string): Promise<CloudCharInfo[]> {
  return req<CloudCharInfo[]>(`/campaigns/${campaignId}/characters`);
}
export async function cloudUsageBytes(): Promise<number> {
  return (await req<{ bytes: number }>('/usage')).bytes;
}

export interface AdminUserRow { username: string; usageBytes: number; quotaBytes: number }
export function getUsage(): Promise<{ bytes: number; admin: boolean }> {
  return req<{ bytes: number; admin: boolean }>('/usage');
}
export function adminListUsers(): Promise<{ users: AdminUserRow[] }> {
  return req<{ users: AdminUserRow[] }>('/admin/users');
}
export function adminSetQuota(username: string, quotaBytes: number): Promise<{ ok: boolean }> {
  return req<{ ok: boolean }>('/admin/quota', { method: 'POST', body: JSON.stringify({ username, quotaBytes }) });
}
