/**
 * Game Registry System
 * Manages registration and lifecycle of HTML5 games
 */

import { HTML5GameConfig, HTML5GameTemplate, createHTML5Game } from './html5GameTemplate';

export interface RegisteredGame {
  id: string;
  config: HTML5GameConfig;
  template: HTML5GameTemplate;
  status: 'active' | 'maintenance' | 'disabled';
  createdAt: Date;
  updatedAt: Date;
  stats: {
    totalSpins: number;
    totalWagered: number;
    totalWon: number;
    playerCount: number;
  };
}

export class GameRegistry {
  private games: Map<string, RegisteredGame> = new Map();

  /**
   * Register a new game
   */
  registerGame(config: HTML5GameConfig): RegisteredGame {
    if (this.games.has(config.id)) {
      throw new Error(`Game ${config.id} is already registered`);
    }

    const template = createHTML5Game(config);

    const registeredGame: RegisteredGame = {
      id: config.id,
      config,
      template,
      status: 'active',
      createdAt: new Date(),
      updatedAt: new Date(),
      stats: {
        totalSpins: 0,
        totalWagered: 0,
        totalWon: 0,
        playerCount: 0,
      },
    };

    this.games.set(config.id, registeredGame);
    console.log(`[GameRegistry] Registered game: ${config.name} (${config.id})`);

    return registeredGame;
  }

  /**
   * Get a registered game
   */
  getGame(gameId: string): RegisteredGame | null {
    return this.games.get(gameId) || null;
  }

  /**
   * Get all registered games
   */
  getAllGames(): RegisteredGame[] {
    return Array.from(this.games.values());
  }

  /**
   * Get active games
   */
  getActiveGames(): RegisteredGame[] {
    return Array.from(this.games.values()).filter((g) => g.status === 'active');
  }

  /**
   * Update game status
   */
  updateGameStatus(gameId: string, status: 'active' | 'maintenance' | 'disabled'): RegisteredGame | null {
    const game = this.games.get(gameId);
    if (!game) return null;

    game.status = status;
    game.updatedAt = new Date();

    console.log(`[GameRegistry] Updated game ${gameId} status to ${status}`);
    return game;
  }

  /**
   * Update game statistics
   */
  updateGameStats(
    gameId: string,
    stats: Partial<RegisteredGame['stats']>
  ): RegisteredGame | null {
    const game = this.games.get(gameId);
    if (!game) return null;

    game.stats = { ...game.stats, ...stats };
    game.updatedAt = new Date();

    return game;
  }

  /**
   * Record a spin
   */
  recordSpin(gameId: string, bet: number, win: number): void {
    const game = this.games.get(gameId);
    if (!game) return;

    game.stats.totalSpins++;
    game.stats.totalWagered += bet;
    game.stats.totalWon += win;
  }

  /**
   * Record a player
   */
  recordPlayer(gameId: string): void {
    const game = this.games.get(gameId);
    if (!game) return;

    game.stats.playerCount++;
  }

  /**
   * Get game statistics
   */
  getGameStats(gameId: string): RegisteredGame['stats'] | null {
    const game = this.games.get(gameId);
    return game?.stats || null;
  }

  /**
   * Get all game statistics
   */
  getAllGameStats(): Record<string, RegisteredGame['stats']> {
    const stats: Record<string, RegisteredGame['stats']> = {};

    for (const [id, game] of this.games) {
      stats[id] = game.stats;
    }

    return stats;
  }

  /**
   * Remove a game
   */
  removeGame(gameId: string): boolean {
    return this.games.delete(gameId);
  }

  /**
   * Get game count
   */
  getGameCount(): number {
    return this.games.size;
  }

  /**
   * Get active game count
   */
  getActiveGameCount(): number {
    return Array.from(this.games.values()).filter((g) => g.status === 'active').length;
  }

  /**
   * Clear all games (for testing)
   */
  clearAll(): void {
    this.games.clear();
    console.log('[GameRegistry] Cleared all games');
  }

  /**
   * Export game registry
   */
  export(): Record<string, RegisteredGame> {
    const exported: Record<string, RegisteredGame> = {};

    for (const [id, game] of this.games) {
      exported[id] = {
        ...game,
        template: undefined as any, // Don't export template instance
      };
    }

    return exported;
  }

  /**
   * Get registry health
   */
  getHealth(): {
    totalGames: number;
    activeGames: number;
    maintenanceGames: number;
    disabledGames: number;
    totalSpins: number;
    totalWagered: number;
    totalWon: number;
  } {
    const games = Array.from(this.games.values());

    return {
      totalGames: games.length,
      activeGames: games.filter((g) => g.status === 'active').length,
      maintenanceGames: games.filter((g) => g.status === 'maintenance').length,
      disabledGames: games.filter((g) => g.status === 'disabled').length,
      totalSpins: games.reduce((sum, g) => sum + g.stats.totalSpins, 0),
      totalWagered: games.reduce((sum, g) => sum + g.stats.totalWagered, 0),
      totalWon: games.reduce((sum, g) => sum + g.stats.totalWon, 0),
    };
  }
}

// Global game registry instance
export const gameRegistry = new GameRegistry();

/**
 * Initialize default games
 */
export function initializeDefaultGames(): void {
  // Register default games
  const defaultGames: HTML5GameConfig[] = [
    {
      id: 'classic-3-reel',
      name: 'Classic 3-Reel Slots',
      description: 'Traditional slot machine',
      thumbnail: '🎰',
      rtp: 94.5,
      volatility: 'low',
      minBet: 0.1,
      maxBet: 100,
      reels: 3,
      rows: 3,
      paylines: 9,
      symbols: [
        { id: 'cherry', name: 'Cherry', emoji: '🍒', payouts: { 3: 10, 2: 5 } },
        { id: 'lemon', name: 'Lemon', emoji: '🍋', payouts: { 3: 15, 2: 7 } },
        { id: 'orange', name: 'Orange', emoji: '🍊', payouts: { 3: 20, 2: 10 } },
        { id: 'bell', name: 'Bell', emoji: '🔔', payouts: { 3: 50, 2: 25 } },
        { id: 'seven', name: 'Seven', emoji: '7️⃣', payouts: { 3: 100, 2: 50 }, isWild: true },
      ],
      features: ['Free Spins', 'Wild Symbol', 'Multipliers'],
    },
    {
      id: 'treasure-quest',
      name: 'Treasure Quest 5-Reel',
      description: 'Adventure-themed game',
      thumbnail: '💎',
      rtp: 95.2,
      volatility: 'medium',
      minBet: 0.1,
      maxBet: 100,
      reels: 5,
      rows: 3,
      paylines: 20,
      symbols: [
        { id: 'gem', name: 'Gem', emoji: '💎', payouts: { 5: 500, 4: 100, 3: 20 } },
        { id: 'treasure', name: 'Treasure', emoji: '🏆', payouts: { 5: 400, 4: 80, 3: 15 }, isScatter: true },
        { id: 'map', name: 'Map', emoji: '🗺️', payouts: { 5: 300, 4: 60, 3: 12 } },
        { id: 'compass', name: 'Compass', emoji: '🧭', payouts: { 5: 200, 4: 40, 3: 8 } },
        { id: 'coin', name: 'Coin', emoji: '🪙', payouts: { 5: 100, 4: 20, 3: 5 } },
      ],
      features: ['Bonus Rounds', 'Free Spins', 'Scatter Pays', 'Multipliers'],
      bonusRounds: [
        {
          id: 'treasure-bonus',
          name: 'Treasure Bonus',
          type: 'free_spins',
          triggerSymbol: 'treasure',
          triggerCount: 3,
          reward: 10,
        },
      ],
    },
  ];

  for (const config of defaultGames) {
    try {
      gameRegistry.registerGame(config);
    } catch (error) {
      console.error(`Failed to register game ${config.id}:`, error);
    }
  }

  console.log(`[GameRegistry] Initialized ${gameRegistry.getGameCount()} default games`);
}
