import type {
  Campaign,
  Character,
  Gear,
  Talent,
  GameItem,
  GameTalent,
  RollResult,
} from "./types";

const BASE = "/api";

async function request<T>(path: string, options?: RequestInit): Promise<T> {
  const res = await fetch(`${BASE}${path}`, {
    headers: { "Content-Type": "application/json" },
    ...options,
  });
  if (!res.ok) {
    const err = await res.json().catch(() => ({ error: res.statusText }));
    throw new Error(err.error || res.statusText);
  }
  if (res.status === 204) return undefined as T;
  return res.json();
}

// Campaigns
export const getCampaigns = () => request<Campaign[]>("/campaigns");
export const createCampaign = (name: string) =>
  request<Campaign>("/campaigns", {
    method: "POST",
    body: JSON.stringify({ name }),
  });
export const deleteCampaign = (id: number) =>
  request<void>(`/campaigns/${id}`, { method: "DELETE" });

// Characters
export const getCharacters = (campaignId: number) =>
  request<Character[]>(`/campaigns/${campaignId}/characters`);
export const createCharacter = (
  campaignId: number,
  data: { name: string; class?: string; ancestry?: string; hp_max?: number },
) =>
  request<Character>(`/campaigns/${campaignId}/characters`, {
    method: "POST",
    body: JSON.stringify(data),
  });
export const updateCharacter = (id: number, data: Partial<Character>) =>
  request<Character>(`/characters/${id}`, {
    method: "PATCH",
    body: JSON.stringify(data),
  });
export const deleteCharacter = (id: number) =>
  request<void>(`/characters/${id}`, { method: "DELETE" });

// Stats
export const updateStat = (
  characterId: number,
  statName: string,
  value: number,
) =>
  request<{ characterId: number; statName: string; value: number }>(
    `/characters/${characterId}/stats/${statName}`,
    { method: "PATCH", body: JSON.stringify({ value }) },
  );

// Gear
export const addGear = (
  characterId: number,
  data: {
    name: string;
    type?: string;
    slot_count?: number;
    properties?: Record<string, unknown>;
    effects?: Record<string, unknown>;
    game_item_id?: number | null;
  },
) =>
  request<Gear>(`/characters/${characterId}/gear`, {
    method: "POST",
    body: JSON.stringify(data),
  });
export const removeGear = (characterId: number, gearId: number) =>
  request<void>(`/characters/${characterId}/gear/${gearId}`, {
    method: "DELETE",
  });

// Talents
export const addTalent = (
  characterId: number,
  data: {
    name: string;
    description?: string;
    effect?: Record<string, unknown>;
    game_talent_id?: number | null;
  },
) =>
  request<Talent>(`/characters/${characterId}/talents`, {
    method: "POST",
    body: JSON.stringify(data),
  });
export const removeTalent = (characterId: number, talentId: number) =>
  request<void>(`/characters/${characterId}/talents/${talentId}`, {
    method: "DELETE",
  });

// Game Items
export const getGameItems = () => request<GameItem[]>("/game-items");

// Game Talents
export const getGameTalents = () => request<GameTalent[]>("/game-talents");

// Rolls
export const getRolls = (campaignId: number) =>
  request<RollResult[]>(`/campaigns/${campaignId}/rolls`);
