import { BaseSlotGame, GameConfig, PayoutTable, generateStandardPaylines, checkMatches } from '../customGameEngine.ts';

/**
 * Game 1: Crystal Cascade
 * Cascading reels with multiplier system
 */
export class CrystalCascade extends BaseSlotGame {
  protected initializePayoutTable(): PayoutTable {
    return {
      '0-0-0-0-0': 500, // 5 crystals
      '1-1-1-1-1': 300,
      '2-2-2-2-2': 200,
      '3-3-3-3-3': 150,
      '0-0-0-0': 100,
      '1-1-1-1': 80,
      '2-2-2-2': 60,
      '3-3-3-3': 40,
    };
  }

  protected calculateWin(reels: number[][]): number {
    let totalWin = 0;
    let cascadeCount = 0;

    // Check for matches
    const middle = reels.map((reel) => reel[1]);
    for (let i = 0; i < middle.length - 2; i++) {
      if (middle[i] === middle[i + 1] && middle[i + 1] === middle[i + 2]) {
        const key = `${middle[i]}-${middle[i + 1]}-${middle[i + 2]}`;
        totalWin += this.payoutTable[key] || 10;
        cascadeCount++;
      }
    }

    // Cascade multiplier
    return totalWin * (1 + cascadeCount * 0.5);
  }

  protected checkBonus(reels: number[][]): { triggered: boolean; type?: string; data?: any } {
    const scatterCount = reels.filter((reel) => reel[1] === 7).length; // 7 is scatter

    if (scatterCount >= 3) {
      return {
        triggered: true,
        type: 'free_spins',
        data: { freeSpins: scatterCount * 5 },
      };
    }

    return { triggered: false };
  }
}

/**
 * Game 2: Dragon's Hoard
 * Hold & spin mechanic with sticky wilds
 */
export class DragonsHoard extends BaseSlotGame {
  protected initializePayoutTable(): PayoutTable {
    return {
      '0-0-0-0-0': 1000, // Dragon
      '1-1-1-1-1': 500, // Gold
      '2-2-2-2-2': 300,
      '3-3-3-3-3': 200,
      '0-0-0': 200,
      '1-1-1': 100,
      '2-2-2': 60,
      '3-3-3': 40,
    };
  }

  protected calculateWin(reels: number[][]): number {
    let totalWin = 0;

    // Check for dragon (wild)
    const dragonCount = reels.flat().filter((symbol) => symbol === 0).length;
    if (dragonCount >= 3) {
      totalWin += 100 * dragonCount;
    }

    // Check paylines
    const middle = reels.map((reel) => reel[1]);
    for (let i = 0; i < middle.length - 2; i++) {
      if (middle[i] === middle[i + 1] && middle[i + 1] === middle[i + 2]) {
        totalWin += this.payoutTable[`${middle[i]}-${middle[i + 1]}-${middle[i + 2]}`] || 10;
      }
    }

    return totalWin;
  }

  protected checkBonus(reels: number[][]): { triggered: boolean; type?: string; data?: any } {
    // Check for treasure chest (symbol 6)
    const treasureCount = reels.filter((reel) => reel[1] === 6).length;

    if (treasureCount >= 2) {
      return {
        triggered: true,
        type: 'pick_bonus',
        data: { picks: treasureCount },
      };
    }

    return { triggered: false };
  }
}

/**
 * Game 3: Neon Lights
 * Megaways mechanic with dynamic paylines
 */
export class NeonLights extends BaseSlotGame {
  protected initializePayoutTable(): PayoutTable {
    return {
      '0-0-0-0-0': 800,
      '1-1-1-1-1': 400,
      '2-2-2-2-2': 250,
      '3-3-3-3-3': 150,
      '4-4-4-4-4': 100,
      '0-0-0': 100,
      '1-1-1': 60,
      '2-2-2': 40,
      '3-3-3': 25,
    };
  }

  protected calculateWin(reels: number[][]): number {
    let totalWin = 0;
    const paylines = generateStandardPaylines();

    // Check each payline
    paylines.forEach((payline) => {
      const symbols = payline.map((pos, reelIndex) => reels[reelIndex][pos]);
      const key = symbols.join('-');

      if (this.payoutTable[key]) {
        totalWin += this.payoutTable[key];
      }
    });

    return totalWin;
  }

  protected checkBonus(reels: number[][]): { triggered: boolean; type?: string; data?: any } {
    // Neon light (symbol 5) triggers multiplier
    const neonCount = reels.flat().filter((symbol) => symbol === 5).length;

    if (neonCount >= 4) {
      return {
        triggered: true,
        type: 'multiplier',
        data: { multiplier: 2 + Math.floor(neonCount / 4) },
      };
    }

    return { triggered: false };
  }
}

/**
 * Game 4: Treasure Hunt
 * Scatter bonus with progressive multiplier
 */
export class TreasureHunt extends BaseSlotGame {
  protected initializePayoutTable(): PayoutTable {
    return {
      '0-0-0-0-0': 600,
      '1-1-1-1-1': 350,
      '2-2-2-2-2': 200,
      '3-3-3-3-3': 120,
      '0-0-0': 80,
      '1-1-1': 50,
      '2-2-2': 30,
      '3-3-3': 15,
    };
  }

  protected calculateWin(reels: number[][]): number {
    let totalWin = 0;

    // Check middle payline
    const middle = reels.map((reel) => reel[1]);
    for (let i = 0; i < middle.length - 2; i++) {
      if (middle[i] === middle[i + 1] && middle[i + 1] === middle[i + 2]) {
        const key = `${middle[i]}-${middle[i + 1]}-${middle[i + 2]}`;
        totalWin += this.payoutTable[key] || 10;
      }
    }

    return totalWin;
  }

  protected checkBonus(reels: number[][]): { triggered: boolean; type?: string; data?: any } {
    // Map symbol (symbol 4) triggers treasure hunt
    const mapCount = reels.filter((reel) => reel[1] === 4).length;

    if (mapCount >= 3) {
      return {
        triggered: true,
        type: 'treasure_hunt',
        data: { treasures: mapCount * 2 },
      };
    }

    return { triggered: false };
  }
}

/**
 * Game 5: Cosmic Reels
 * Expanding symbols with galaxy bonus
 */
export class CosmicReels extends BaseSlotGame {
  protected initializePayoutTable(): PayoutTable {
    return {
      '0-0-0-0-0': 700,
      '1-1-1-1-1': 400,
      '2-2-2-2-2': 250,
      '3-3-3-3-3': 150,
      '4-4-4-4-4': 100,
      '0-0-0': 120,
      '1-1-1': 70,
      '2-2-2': 45,
      '3-3-3': 30,
    };
  }

  protected calculateWin(reels: number[][]): number {
    let totalWin = 0;

    // Check for expanding symbols (symbol 6)
    const expandingCount = reels.flat().filter((symbol) => symbol === 6).length;
    if (expandingCount > 0) {
      totalWin += 50 * expandingCount;
    }

    // Check paylines
    const middle = reels.map((reel) => reel[1]);
    for (let i = 0; i < middle.length - 2; i++) {
      if (middle[i] === middle[i + 1] && middle[i + 1] === middle[i + 2]) {
        totalWin += this.payoutTable[`${middle[i]}-${middle[i + 1]}-${middle[i + 2]}`] || 10;
      }
    }

    return totalWin;
  }

  protected checkBonus(reels: number[][]): { triggered: boolean; type?: string; data?: any } {
    // Planet symbol (symbol 7) triggers galaxy bonus
    const planetCount = reels.filter((reel) => reel[1] === 7).length;

    if (planetCount >= 3) {
      return {
        triggered: true,
        type: 'galaxy_spins',
        data: { galaxySpins: planetCount * 3 },
      };
    }

    return { triggered: false };
  }
}

/**
 * Game Factory
 */
export function createGame(gameId: string, serverSeed: string): BaseSlotGame {
  const gameConfigs: { [key: string]: GameConfig } = {
    'crystal-cascade': {
      id: 'crystal-cascade',
      name: 'Crystal Cascade',
      reels: 5,
      symbols: ['💎', '💠', '🔷', '🔹', '⭐', '✨', '🌟', '💫'],
      paylines: 10,
      rtp: 96.5,
      volatility: 'high',
      minBet: 0.1,
      maxBet: 100,
      maxWin: 5000,
      bonusFeatures: ['cascading', 'multiplier', 'free_spins'],
    },
    'dragons-hoard': {
      id: 'dragons-hoard',
      name: "Dragon's Hoard",
      reels: 5,
      symbols: ['🐉', '🏆', '💰', '👑', '💎', '🔥', '⚔️', '🗺️'],
      paylines: 10,
      rtp: 95.8,
      volatility: 'medium',
      minBet: 0.1,
      maxBet: 100,
      maxWin: 3000,
      bonusFeatures: ['hold_spin', 'sticky_wilds', 'pick_bonus'],
    },
    'neon-lights': {
      id: 'neon-lights',
      name: 'Neon Lights',
      reels: 5,
      symbols: ['🌃', '💡', '🔌', '⚡', '🌈', '🎆', '🎇', '✨'],
      paylines: 25,
      rtp: 97.2,
      volatility: 'high',
      minBet: 0.1,
      maxBet: 100,
      maxWin: 8000,
      bonusFeatures: ['megaways', 'dynamic_paylines', 'multiplier'],
    },
    'treasure-hunt': {
      id: 'treasure-hunt',
      name: 'Treasure Hunt',
      reels: 5,
      symbols: ['🗺️', '💎', '🏴‍☠️', '⚓', '🪙', '🏺', '🗝️', '🧭'],
      paylines: 15,
      rtp: 96.0,
      volatility: 'medium',
      minBet: 0.1,
      maxBet: 100,
      maxWin: 4000,
      bonusFeatures: ['scatter_bonus', 'progressive_multiplier', 'treasure_hunt'],
    },
    'cosmic-reels': {
      id: 'cosmic-reels',
      name: 'Cosmic Reels',
      reels: 5,
      symbols: ['🌌', '🪐', '⭐', '🌠', '🚀', '🛸', '👽', '🌟'],
      paylines: 20,
      rtp: 96.8,
      volatility: 'medium',
      minBet: 0.1,
      maxBet: 100,
      maxWin: 6000,
      bonusFeatures: ['expanding_symbols', 'galaxy_bonus', 'free_spins'],
    },
  };

  const config = gameConfigs[gameId];
  if (!config) {
    throw new Error(`Unknown game: ${gameId}`);
  }

  switch (gameId) {
    case 'crystal-cascade':
      return new CrystalCascade(config, serverSeed);
    case 'dragons-hoard':
      return new DragonsHoard(config, serverSeed);
    case 'neon-lights':
      return new NeonLights(config, serverSeed);
    case 'treasure-hunt':
      return new TreasureHunt(config, serverSeed);
    case 'cosmic-reels':
      return new CosmicReels(config, serverSeed);
    default:
      throw new Error(`Unknown game: ${gameId}`);
  }
}

export default {
  CrystalCascade,
  DragonsHoard,
  NeonLights,
  TreasureHunt,
  CosmicReels,
  createGame,
};
