/**
 * Slot Game Engine - Game Generator
 * Auto-generates original slot games from JSON configurations
 */

import type { GameConfig, Symbol, Reel, Payline } from './types.ts';

export class GameGenerator {
  /**
   * Generate a complete game from configuration
   */
  static generateGame(config: {
    name: string;
    type: 'classic' | 'video' | 'megaways' | 'hold_spin' | 'bonus_feature' | 'progressive';
    reels: number;
    rows: number;
    rtp: number;
    volatility: 'low' | 'medium' | 'high' | 'extreme';
    theme: string;
    features: string[];
  }): GameConfig {
    const symbols = this.generateSymbols(config.theme, config.type);
    const reelConfig = this.generateReels(config.reels, config.rows, symbols, config.type);
    const paylines = config.type === 'classic' ? this.generatePaylines(config.reels, config.rows) : [];

    return {
      id: `game_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      name: config.name,
      type: config.type,
      reels: config.reels,
      rows: config.rows,
      rtp: Math.max(85, Math.min(98, config.rtp)),
      volatility: config.volatility,
      minBet: 0.1,
      maxBet: 100,
      paylines,
      waysToWin: config.type === 'megaways' ? { enabled: true, ways: 243, adjacentOnly: true } : undefined,
      cascadingReels: config.type === 'megaways',
      clusterPays: false,
      symbols,
      reelConfig,
      features: config.features as any[],
      bonusConfig: this.generateBonusConfig(config.features, symbols),
      theme: config.theme,
      createdAt: new Date(),
      updatedAt: new Date(),
      enabled: true,
    };
  }

  /**
   * Generate theme-appropriate symbols
   */
  static generateSymbols(theme: string, gameType: string): Symbol[] {
    const symbolSets: Record<string, Symbol[]> = {
      fishing: [
        { id: 'fish_small', name: 'Small Fish', type: 'regular', value: 10 },
        { id: 'fish_medium', name: 'Medium Fish', type: 'regular', value: 25 },
        { id: 'fish_large', name: 'Large Fish', type: 'regular', value: 50 },
        { id: 'treasure_chest', name: 'Treasure Chest', type: 'scatter', value: 100 },
        { id: 'wild_fish', name: 'Wild Fish', type: 'wild', value: 75 },
        { id: 'hook', name: 'Hook', type: 'bonus', value: 150 },
      ],
      dragon: [
        { id: 'coin', name: 'Gold Coin', type: 'regular', value: 15 },
        { id: 'gem', name: 'Gem', type: 'regular', value: 30 },
        { id: 'dragon_egg', name: 'Dragon Egg', type: 'scatter', value: 100 },
        { id: 'dragon_wild', name: 'Dragon', type: 'wild', value: 80, multiplier: 2 },
        { id: 'treasure', name: 'Treasure', type: 'bonus', value: 200 },
      ],
      classic: [
        { id: 'cherry', name: 'Cherry', type: 'regular', value: 5 },
        { id: 'lemon', name: 'Lemon', type: 'regular', value: 10 },
        { id: 'orange', name: 'Orange', type: 'regular', value: 15 },
        { id: 'bell', name: 'Bell', type: 'regular', value: 25 },
        { id: 'seven', name: 'Seven', type: 'scatter', value: 100 },
        { id: 'wild_symbol', name: 'Wild', type: 'wild', value: 50 },
      ],
      space: [
        { id: 'star', name: 'Star', type: 'regular', value: 20 },
        { id: 'planet', name: 'Planet', type: 'regular', value: 35 },
        { id: 'alien', name: 'Alien', type: 'scatter', value: 120 },
        { id: 'spaceship', name: 'Spaceship', type: 'wild', value: 90, multiplier: 2 },
        { id: 'ufo', name: 'UFO', type: 'bonus', value: 250 },
      ],
    };

    return symbolSets[theme] || symbolSets.classic;
  }

  /**
   * Generate reel configuration
   */
  static generateReels(reels: number, rows: number, symbols: Symbol[], gameType: string): Reel[] {
    const reelConfig: Reel[] = [];

    for (let i = 0; i < reels; i++) {
      const reelSymbols = gameType === 'megaways' ? this.shuffleSymbols(symbols, 8) : this.shuffleSymbols(symbols, 12);

      reelConfig.push({
        id: `reel_${i}`,
        symbols: reelSymbols,
        type: gameType === 'megaways' ? 'dynamic' : 'standard',
        minHeight: gameType === 'megaways' ? 2 : undefined,
        maxHeight: gameType === 'megaways' ? 7 : undefined,
      });
    }

    return reelConfig;
  }

  /**
   * Shuffle symbols for reel
   */
  static shuffleSymbols(symbols: Symbol[], count: number): Symbol[] {
    const shuffled: Symbol[] = [];
    for (let i = 0; i < count; i++) {
      shuffled.push(symbols[Math.floor(Math.random() * symbols.length)]);
    }
    return shuffled;
  }

  /**
   * Generate paylines for classic slots
   */
  static generatePaylines(reels: number, rows: number): Payline[] {
    const paylines: Payline[] = [];
    const paylineCount = Math.min(reels * rows, 25);

    for (let i = 0; i < paylineCount; i++) {
      const positions: number[] = [];
      for (let reelIndex = 0; reelIndex < reels; reelIndex++) {
        positions.push(Math.floor(Math.random() * rows));
      }

      paylines.push({
        id: `payline_${i}`,
        positions,
        multiplier: 1,
      });
    }

    return paylines;
  }

  /**
   * Generate bonus configuration
   */
  static generateBonusConfig(features: string[], symbols: Symbol[]) {
    const config: any = {};

    if (features.includes('free_spins')) {
      const scatterSymbol = symbols.find((s) => s.type === 'scatter');
      config.freeSpins = {
        triggerSymbol: scatterSymbol?.id || 'scatter',
        triggerCount: 3,
        baseSpins: 10,
        retrigger: true,
        multiplier: 1.5,
      };
    }

    if (features.includes('collector')) {
      config.collector = {
        triggerSymbol: 'collector',
        collectSymbols: ['coin', 'gem', 'treasure'],
        bonusPerSymbol: 10,
      };
    }

    if (features.includes('respin')) {
      config.respin = {
        triggerSymbol: 'respin_symbol',
        lockSymbols: ['wild_symbol', 'bonus'],
        maxRespins: 3,
      };
    }

    return Object.keys(config).length > 0 ? config : undefined;
  }

  /**
   * Generate preset games
   */
  static generatePresetGames(): GameConfig[] {
    return [
      this.generateGame({
        name: 'Fishing Fortune',
        type: 'video',
        reels: 5,
        rows: 3,
        rtp: 96.2,
        volatility: 'high',
        theme: 'fishing',
        features: ['free_spins', 'collector'],
      }),
      this.generateGame({
        name: "Dragon's Gold",
        type: 'megaways',
        reels: 6,
        rows: 4,
        rtp: 96.5,
        volatility: 'extreme',
        theme: 'dragon',
        features: ['free_spins', 'cascading_reels'],
      }),
      this.generateGame({
        name: 'Classic Sevens',
        type: 'classic',
        reels: 3,
        rows: 3,
        rtp: 94.5,
        volatility: 'low',
        theme: 'classic',
        features: ['free_spins'],
      }),
      this.generateGame({
        name: 'Space Odyssey',
        type: 'bonus_feature',
        reels: 5,
        rows: 4,
        rtp: 95.8,
        volatility: 'medium',
        theme: 'space',
        features: ['free_spins', 'bonus_rounds'],
      }),
      this.generateGame({
        name: 'Hold & Spin Adventure',
        type: 'hold_spin',
        reels: 5,
        rows: 3,
        rtp: 95.0,
        volatility: 'medium',
        theme: 'fishing',
        features: ['respin'],
      }),
    ];
  }
}
