// ---- Game Phase ----

export enum GamePhase {
  Walking = 'WALKING',
  Fighting = 'FIGHTING',
  Dead = 'DEAD',
  Resting = 'RESTING',
  InTown = 'IN_TOWN',
}

// ---- Buff Types ----

export enum BuffType {
  Rush = 'rush',               // +50% movement speed
  Rage = 'rage',               // +100% damage
  Shield = 'shield',           // -50% incoming damage
  Luck = 'luck',               // x2.5 loot
  Resurrection = 'resurrection', // auto-resurrect at 50% HP
  Heal = 'heal',               // +50% HP instant
  PowerPotion = 'power_potion', // +150% damage
  WarCry = 'war_cry',          // +100% attack speed
}

// ---- Debuff Types ----

export enum DebuffType {
  Poison = 'poison',   // -2% HP/sec
  Freeze = 'freeze',   // -50% attack speed
  Burn = 'burn',       // -3% HP/sec
  Stun = 'stun',       // no attacks (2 sec)
  Slow = 'slow',       // -40% movement
  Weaken = 'weaken',   // -30% outgoing damage
}

export interface BuffChargeState {
  remaining: number;
  periodEnd: string | null;
}

export interface ActiveDebuff {
  type: DebuffType;
  remainingMs: number;
  durationMs: number;
  /** Wall-clock expiry when synced from server (optional). */
  expiresAtMs?: number;
}

// ---- Rarity ----

export enum Rarity {
  Common = 'common',
  Uncommon = 'uncommon',
  Rare = 'rare',
  Epic = 'epic',
  Legendary = 'legendary',
}

// ---- Enemy Types ----

export enum EnemyType {
  Wolf = 'wolf',
  Boar = 'boar',
  Zombie = 'zombie',
  Spider = 'spider',
  Orc = 'orc',
  SkeletonArcher = 'skeleton_archer',
  BattleLizard = 'battle_lizard',
  FireDemon = 'fire_demon',
  IceGuardian = 'ice_guardian',
  SkeletonKing = 'skeleton_king',
  WaterElement = 'water_element',
  ForestWarden = 'forest_warden',
  LightningTitan = 'lightning_titan',
}

// ---- Weapon Types ----

export enum WeaponType {
  Daggers = 'daggers',
  Sword = 'sword',
  Axe = 'axe',
}

// ---- Armor Types ----

export enum ArmorType {
  Light = 'light',
  Medium = 'medium',
  Heavy = 'heavy',
}

// ---- Loot ----

export interface LootDrop {
  itemType: 'weapon' | 'armor' | 'gold';
  itemName?: string;
  rarity: Rarity;
  goldAmount: number;
  /** Optional equipment drop shown together with gold (backend may return gold + item). */
  bonusItem?: {
    itemType: 'weapon' | 'armor';
    rarity: Rarity;
    itemName?: string;
  };
}

// ---- Entity State ----

export interface Position {
  x: number;
  y: number;
}

export interface HeroState {
  id: number;
  hp: number;
  maxHp: number;
  position: Position;
  /** Server `state` field (walking | resting | in_town | …); used for movement/render parity */
  serverActivityState?: string;
  /** Server rest flavor: "town" */
  restKind?: string;
  attackSpeed: number;
  damage: number;
  defense: number;
  weaponType: WeaponType;
  weaponName: string;
  weaponRarity: Rarity;
  weaponIlvl?: number;
  armorType: ArmorType;
  armorName: string;
  armorRarity: Rarity;
  armorIlvl?: number;
  activeBuffs: ActiveBuff[];
  debuffs: ActiveDebuff[];
  level: number;
  xp: number;
  xpToNext: number;
  gold: number;
  // Secondary stats
  strength: number;
  constitution: number;
  agility: number;
  luck: number;
  /** Server-only meta for revive quota UI */
  reviveCount?: number;
  subscriptionActive?: boolean;
  /** Free buff activations left (non-subscribers); from server */
  buffFreeChargesRemaining?: number;
  /** ISO timestamp when the free buff quota window resets */
  buffQuotaPeriodEnd?: string;
  /** Per-buff charge quotas (remaining activations per 24h period) */
  buffCharges: Partial<Record<BuffType, BuffChargeState>>;
  /** Number of healing potions the hero currently holds */
  potions: number;
  /** Movement speed multiplier (1.0 = normal, affected by buffs/debuffs) */
  moveSpeed?: number;
  /** Extended equipment slots (§6.3): slot key -> equipped item */
  equipment?: Record<string, EquipmentItem>;
  /** Backpack items (server max 40) */
  inventory?: EquipmentItem[];
}

export interface ActiveBuff {
  type: BuffType;
  remainingMs: number;
  durationMs: number;
  cooldownMs: number;
  cooldownRemainingMs: number;
  /** Wall-clock expiry when synced from server (optional). */
  expiresAtMs?: number;
}

export interface EnemyState {
  id: number;
  name: string;
  hp: number;
  maxHp: number;
  position: Position;
  attackSpeed: number;
  damage: number;
  defense: number;
  enemyType: EnemyType;
}

// ---- Full Game State ----

export interface GameState {
  phase: GamePhase;
  hero: HeroState | null;
  enemy: EnemyState | null;
  loot: LootDrop | null;
  /** Last victory rewards; kept after the transient loot popup clears */
  lastVictoryLoot: LootDrop | null;
  tick: number;
  serverTimeMs: number;
  /** Current road polyline from `route_assigned` (minimap / parity with ground renderer). */
  routeWaypoints: Array<{ x: number; y: number }> | null;
}

// ---- Rendering State (interpolated) ----

export interface RenderableEntity {
  id: string;
  screenX: number;
  screenY: number;
  animationState: AnimationState;
  facing: 'left' | 'right';
  flashTimer: number;
}

export enum AnimationState {
  Idle = 'idle',
  Walk = 'walk',
  Attack = 'attack',
  Hit = 'hit',
  Death = 'death',
  BuffActivation = 'buff_activation',
}

// ---- Adventure Log ----

export interface AdventureLogEntry {
  id: number;
  message: string;
  timestamp: number;
}

// ---- Town & NPC & Quest ----

export interface Town {
  id: number;
  name: string;
  biome: string;
  worldX: number;
  worldY: number;
  radius: number;
  levelMin: number;
  levelMax: number;
}

export interface NPC {
  id: number;
  townId: number;
  name: string;
  type: 'quest_giver' | 'merchant' | 'healer';
  offsetX: number;
  offsetY: number;
  buildingId?: number;
}

export interface Quest {
  id: number;
  npcId: number;
  title: string;
  description: string;
  type: 'kill_count' | 'visit_town' | 'collect_item';
  targetCount: number;
  targetEnemyType?: string;
  targetTownId?: number;
  dropChance: number;
  minLevel: number;
  maxLevel: number;
  rewardXp: number;
  rewardGold: number;
  rewardPotions: number;
}

export interface HeroQuest {
  id: number;
  questId: number;
  title: string;
  description: string;
  type: string;
  targetCount: number;
  progress: number;
  status: 'accepted' | 'completed' | 'claimed';
  rewardXp: number;
  rewardGold: number;
  rewardPotions: number;
  npcName: string;
  townName: string;
}

// ---- Equipment Item (extended slots per §6.3) ----

export interface EquipmentItem {
  id: number;
  slot: string;
  formId: string;
  name: string;
  rarity: Rarity;
  ilvl: number;
  primaryStat: number;
  statType: string; // 'attack' | 'defense' | 'speed' | 'mixed'
}

/** Canonical equipment slot keys from spec §6.3 */
export type EquipmentSlot =
  | 'main_hand'
  | 'off_hand'
  | 'head'
  | 'chest'
  | 'legs'
  | 'feet'
  | 'cloak'
  | 'neck'
  | 'finger'
  | 'wrist'
  | 'quiver';

/** NPC data for map rendering and interaction */
export interface NPCData {
  id: number;
  name: string;
  type: 'quest_giver' | 'merchant' | 'healer';
  worldX: number;
  worldY: number;
  buildingId?: number;
}

/** Server-driven building placed in a town */
export interface BuildingData {
  id: number;
  buildingType: string;
  worldX: number;
  worldY: number;
  facing: 'north' | 'south' | 'east' | 'west';
  footprintW: number;
  footprintH: number;
}

/** Alias: engine-facing town data for map rendering */
export interface TownData {
  id: number;
  name: string;
  centerX: number;
  centerY: number;
  radius: number;
  /** Server biome id (meadow, forest, …) — drives wild tiles around the road network. */
  biome: string;
  levelMin: number;
  size: string;
  npcs?: NPCData[];
  buildings?: BuildingData[];
}

/** NPC encounter event returned instead of an enemy */
export interface NPCEncounterEvent {
  type: 'npc_event';
  npcName: string;
  message: string;
  cost: number;
}

// ---- Daily Tasks ----

export interface DailyTask {
  id: string;
  label: string;
  current: number;
  target: number;
}

// ---- Nearby Heroes (shared world) ----

export interface NearbyHeroData {
  id: number;
  name: string;
  level: number;
  positionX: number;
  positionY: number;
}

// ---- Floating Damage ----

export interface FloatingDamageData {
  id: number;
  value: number;
  x: number;
  y: number;
  isCrit: boolean;
  createdAt: number;
}

// ---- Server -> Client Message Payloads ----

export type ServerMessageType =
  | 'hero_state'
  | 'hero_move'
  | 'position_sync'
  | 'route_assigned'
  | 'combat_start'
  | 'attack'
  | 'combat_end'
  | 'hero_died'
  | 'hero_revived'
  | 'buff_applied'
  | 'town_enter'
  | 'town_exit'
  | 'town_npc_visit'
  | 'npc_encounter'
  | 'npc_encounter_end'
  | 'level_up'
  | 'equipment_change'
  | 'potion_collected'
  | 'quest_available'
  | 'quest_progress'
  | 'quest_complete'
  | 'merchant_loot'
  | 'error'
  | 'pong';

export interface HeroMovePayload {
  x: number;
  y: number;
  targetX: number;
  targetY: number;
  speed: number;
  heading?: number;
}

export interface PositionSyncPayload {
  x: number;
  y: number;
  waypointIndex: number;
  waypointFraction: number;
  state: string;
}

export interface RouteAssignedPayload {
  roadId: number;
  waypoints: Array<{ x: number; y: number }>;
  destinationTownId: number;
  speed: number;
}

export interface CombatStartPayload {
  enemy: {
    name: string;
    type: string;
    hp: number;
    maxHp: number;
    attack: number;
    defense: number;
    speed: number;
    isElite?: boolean;
  };
}

export interface AttackPayload {
  source: 'hero' | 'enemy' | 'potion';
  damage: number;
  isCrit: boolean;
  heroHp: number;
  enemyHp: number;
  debuffApplied?: string;
}

export interface CombatEndPayload {
  xpGained: number;
  goldGained: number;
  loot: Array<{ itemType: string; name: string; rarity: string }>;
  leveledUp: boolean;
  newLevel?: number;
}

/** Wandering merchant trade result (after npc alms). */
export interface MerchantLootPayload {
  goldSpent: number;
  itemType: string;
  itemName?: string;
  rarity?: string;
  goldAmount?: number;
}

export interface HeroDiedPayload {
  killedBy: string;
}

export interface HeroRevivedPayload {
  hp: number;
}

export interface BuffAppliedPayload {
  buffType: string;
  duration: number;
  magnitude?: number;
}

export interface TownEnterPayload {
  townId: number;
  townName: string;
  biome?: string;
  npcs?: Array<{ id: number; name: string; type: string; buildingId?: number }>;
  buildings?: Array<{
    id: number;
    buildingType: string;
    worldX: number;
    worldY: number;
    facing: string;
    footprintW: number;
    footprintH: number;
  }>;
  restDurationMs?: number;
}

export interface TownNPCVisitPayload {
  npcId: number;
  name: string;
  type: string;
  townId: number;
}

/** Server-persisted adventure log line (e.g. town NPC visit narration). */
export interface AdventureLogLinePayload {
  message: string;
}

export interface TownExitPayload {}

export interface NPCEncounterPayload {
  npcId: number;
  npcName: string;
  role: string;
  dialogue?: string;
  cost: number;
}

export interface NPCEncounterEndPayload {
  reason: 'timeout' | 'declined' | string;
}

export interface LevelUpPayload {
  newLevel: number;
  statChanges: {
    hp?: number;
    attack?: number;
    defense?: number;
    strength?: number;
    constitution?: number;
    agility?: number;
    luck?: number;
  };
}

export interface EquipmentChangePayload {
  slot: string;
  item: EquipmentItem;
}

export interface PotionCollectedPayload {
  count: number;
}

export interface QuestAvailablePayload {
  questId: number;
  title: string;
  description: string;
  npcName: string;
}

export interface QuestProgressPayload {
  questId: number;
  current: number;
  target: number;
  title?: string;
}

export interface QuestCompletePayload {
  questId: number;
  title: string;
  rewards: { xp: number; gold: number };
}

export interface ServerErrorPayload {
  code: string;
  message: string;
}

// ---- Client -> Server Commands ----

export type ClientCommandType =
  | 'activate_buff'
  | 'use_potion'
  | 'revive'
  | 'accept_quest'
  | 'claim_quest'
  | 'npc_interact'
  | 'npc_alms_accept'
  | 'npc_alms_decline'
  | 'ping';
