import { z } from 'zod';
import { int, systemIdSchema } from './common';

// ---------------- Notes / Wiki ----------------
export const noteSchema = z.object({
  id: z.string(),
  campaignId: z.string(),
  title: z.string().min(1).max(200),
  body: z.string().max(100000).default(''),
  tags: z.array(z.string().min(1)).default([]),
  createdAt: z.string(),
  updatedAt: z.string(),
});
export type Note = z.infer<typeof noteSchema>;

// ---------------- NPCs ----------------
export const npcSchema = z.object({
  id: z.string(),
  campaignId: z.string(),
  name: z.string().min(1).max(120),
  role: z.string().max(120).default(''),
  location: z.string().max(120).default(''),
  faction: z.string().max(120).default(''),
  status: z.enum(['alive', 'dead', 'unknown']).default('alive'),
  description: z.string().max(20000).default(''),
  createdAt: z.string(),
  updatedAt: z.string(),
});
export type Npc = z.infer<typeof npcSchema>;

// ---------------- Quests ----------------
export const objectiveSchema = z.object({
  id: z.string(),
  text: z.string().min(1).max(500),
  done: z.boolean().default(false),
});
export type Objective = z.infer<typeof objectiveSchema>;

export const questSchema = z.object({
  id: z.string(),
  campaignId: z.string(),
  title: z.string().min(1).max(200),
  status: z.enum(['active', 'completed', 'failed', 'on-hold']).default('active'),
  description: z.string().max(20000).default(''),
  reward: z.string().max(500).default(''),
  objectives: z.array(objectiveSchema).default([]),
  createdAt: z.string(),
  updatedAt: z.string(),
});
export type Quest = z.infer<typeof questSchema>;

// ---------------- Calendar (in-world) ----------------
// Stored as a plain integer "day number" — no real Date, so no timezone/DST bugs.
export const calendarEventSchema = z.object({
  id: z.string(),
  day: int,
  title: z.string().min(1).max(200),
});
export type CalendarEvent = z.infer<typeof calendarEventSchema>;

export const calendarSchema = z.object({
  /** one calendar per campaign — campaignId is the primary key */
  campaignId: z.string(),
  /** current in-world day number (arbitrary epoch) */
  currentDay: int.default(0),
  events: z.array(calendarEventSchema).default([]),
});
export type Calendar = z.infer<typeof calendarSchema>;

// ---------------- Homebrew content ----------------
export const homebrewKindSchema = z.enum(['monster', 'spell', 'item', 'feat', 'condition']);
export type HomebrewKind = z.infer<typeof homebrewKindSchema>;

export const homebrewSchema = z.object({
  id: z.string(),
  campaignId: z.string(),
  system: systemIdSchema,
  kind: homebrewKindSchema,
  name: z.string().min(1).max(160),
  /** category-specific scalar fields (AC, HP, CR, Level, School, Rarity, …) */
  fields: z.record(z.string(), z.union([z.string(), z.number()])).default({}),
  description: z.string().max(20000).default(''),
  createdAt: z.string(),
  updatedAt: z.string(),
});
export type Homebrew = z.infer<typeof homebrewSchema>;

// ---------------- Battle maps (VTT) ----------------
export const mapTokenSchema = z.object({
  id: z.string(),
  label: z.string().max(40).default(''),
  color: z.string().max(20).default('#d4af37'),
  /** grid cell coordinates */
  col: int,
  row: int,
});
export type MapToken = z.infer<typeof mapTokenSchema>;

export const battleMapSchema = z.object({
  id: z.string(),
  campaignId: z.string(),
  name: z.string().min(1).max(120),
  /** image as a data URL (stored locally) */
  image: z.string().default(''),
  gridSize: int.min(10).max(400).default(50),
  showGrid: z.boolean().default(true),
  fogEnabled: z.boolean().default(false),
  /** revealed cell keys "col,row"; everything else is fogged when enabled */
  revealed: z.array(z.string()).default([]),
  tokens: z.array(mapTokenSchema).default([]),
  createdAt: z.string(),
  updatedAt: z.string(),
});
export type BattleMap = z.infer<typeof battleMapSchema>;
