import { EasyEvent } from "@hitplay/playable_template";
import { Vector3 } from "three";
import type { Crate } from "../controllers/LootableC";

/**
 * Centralized event system. Controllers emit events instead of calling each other directly.
 * This decouples systems and makes it easy to add new listeners (e.g., sound, particles, analytics).
 *
 * Uses EasyEvent<Type> from @hitplay/playable_template (same pattern as UpdateController, JoystickC).
 * Subscribe: event.addDelegate(callback)
 * Emit: event.Invoke(data)
 */

// Event data types
export interface CrateHitData {
  crate: Crate;
  damage: number;
}

export interface CrateBrokenData {
  crate: Crate;
  position: Vector3;
}

export interface LootSpawnData {
  position: Vector3;
  count?: number;
}

export interface HealthDisplayData {
  crate: Crate;
  healthFraction: number;
}

export interface WoodCollectedData {
  amount: number;
  balance: number;
}

export interface WoodSpentData {
  amount: number;
  balance: number;
}

/**
 * Global game events. Use like:
 *   GameEvents.onCrateHit.Invoke({ crate, damage: 10 });
 *   GameEvents.onCrateHit.addDelegate(({ crate, damage }) => { ... });
 */
export class GameEvents {
  // Crate hit: damage applied, state may change
  static onCrateHit = new EasyEvent<CrateHitData>();

  // Crate destroyed: physics removed, loot will drop
  static onCrateBroken = new EasyEvent<CrateBrokenData>();

  // Health bar shown/updated for a crate
  static onHealthDisplay = new EasyEvent<HealthDisplayData>();

  // Health bar hidden
  static onHealthHide = new EasyEvent<Crate>();

  // Loot drops at a position (may be from crate break or state change)
  static onLootSpawn = new EasyEvent<LootSpawnData>();

  // Wood piece collected into UI counter
  static onWoodCollected = new EasyEvent<WoodCollectedData>();

  // Wood spent from counter (e.g., plank flying to pay zone)
  static onWoodSpent = new EasyEvent<WoodSpentData>();
}
