/**
 * Game Integration Helper
 * Wires all 700+ casino games to the advanced game engine
 * Handles game-specific configurations, themes, and features
 */

import { createGameConfig, GameConfig, STANDARD_SYMBOLS } from "./gameEngine.ts";

// ─── GAME THEME DEFINITIONS ───────────────────────────────────────────────────

export enum GameTheme {
  CLASSIC = "classic",
  FRUIT = "fruit",
  ANCIENT_EGYPT = "ancient_egypt",
  ASIAN = "asian",
  LUXURY = "luxury",
  SPACE = "space",
  FANTASY = "fantasy",
  WESTERN = "western",
  UNDERWATER = "underwater",
  CHRISTMAS = "christmas",
}

export interface GameThemeConfig {
  theme: GameTheme;
  symbols: string[];
  backgroundColor: string;
  accentColor: string;
  soundTheme: string;
}

// ─── THEME SYMBOL SETS ────────────────────────────────────────────────────────

export const THEME_SYMBOLS: Record<GameTheme, string[]> = {
  [GameTheme.CLASSIC]: ["🍒", "🍋", "🍊", "🍇", "⭐", "💎", "7️⃣", "🔔", "🏷️", "🌟"],
  [GameTheme.FRUIT]: ["🍎", "🍌", "🍉", "🍓", "🥝", "🍑", "🍍", "🍊", "🍋", "🌟"],
  [GameTheme.ANCIENT_EGYPT]: ["🏺", "⚱️", "🦅", "🐍", "💎", "🪙", "🔱", "👑", "🏛️", "🌟"],
  [GameTheme.ASIAN]: ["🏮", "🎎", "🎋", "🐉", "🦁", "🏯", "⛩️", "🎌", "🧧", "🌟"],
  [GameTheme.LUXURY]: ["💎", "👑", "🏆", "💰", "🥂", "🎩", "🎭", "🎪", "🎨", "🌟"],
  [GameTheme.SPACE]: ["🚀", "🛸", "🌌", "⭐", "🌠", "🪐", "🌙", "☄️", "👽", "🌟"],
  [GameTheme.FANTASY]: ["🐉", "🧙", "⚔️", "🛡️", "🧝", "🦄", "🏰", "💀", "🔮", "🌟"],
  [GameTheme.WESTERN]: ["🤠", "🔫", "🐴", "🏜️", "⛏️", "🪙", "💣", "🎯", "🏆", "🌟"],
  [GameTheme.UNDERWATER]: ["🐠", "🐙", "🦈", "🐚", "🪸", "⚓", "🌊", "🦀", "🐢", "🌟"],
  [GameTheme.CHRISTMAS]: ["🎄", "🎅", "🤶", "🎁", "⛄", "🔔", "🕯️", "🦌", "❄️", "🌟"],
};

// ─── GAME PROVIDER CONFIGURATIONS ─────────────────────────────────────────────

export interface ProviderConfig {
  name: string;
  rtp: number; // Default RTP for this provider
  volatility: "low" | "medium" | "high" | "very_high";
  reels: number;
  rows: number;
  paylines: number;
  features: {
    freeSpins: boolean;
    bonusGame: boolean;
    wildExpand: boolean;
    progressiveJackpot: boolean;
  };
}

export const PROVIDER_CONFIGS: Record<string, ProviderConfig> = {
  "Pragmatic Play": {
    name: "Pragmatic Play",
    rtp: 96.5,
    volatility: "medium",
    reels: 5,
    rows: 3,
    paylines: 25,
    features: {
      freeSpins: true,
      bonusGame: true,
      wildExpand: true,
      progressiveJackpot: false,
    },
  },
  "Microgaming": {
    name: "Microgaming",
    rtp: 96.0,
    volatility: "medium",
    reels: 5,
    rows: 3,
    paylines: 25,
    features: {
      freeSpins: true,
      bonusGame: true,
      wildExpand: false,
      progressiveJackpot: true,
    },
  },
  "NetEnt": {
    name: "NetEnt",
    rtp: 96.8,
    volatility: "high",
    reels: 5,
    rows: 3,
    paylines: 25,
    features: {
      freeSpins: true,
      bonusGame: true,
      wildExpand: true,
      progressiveJackpot: false,
    },
  },
  "Playtech": {
    name: "Playtech",
    rtp: 95.5,
    volatility: "medium",
    reels: 5,
    rows: 3,
    paylines: 25,
    features: {
      freeSpins: true,
      bonusGame: true,
      wildExpand: false,
      progressiveJackpot: true,
    },
  },
  "IGT": {
    name: "IGT",
    rtp: 94.0,
    volatility: "low",
    reels: 5,
    rows: 3,
    paylines: 20,
    features: {
      freeSpins: true,
      bonusGame: false,
      wildExpand: false,
      progressiveJackpot: false,
    },
  },
  "Novomatic": {
    name: "Novomatic",
    rtp: 95.0,
    volatility: "low",
    reels: 5,
    rows: 3,
    paylines: 9,
    features: {
      freeSpins: true,
      bonusGame: false,
      wildExpand: false,
      progressiveJackpot: false,
    },
  },
  "Betsoft": {
    name: "Betsoft",
    rtp: 97.0,
    volatility: "high",
    reels: 5,
    rows: 3,
    paylines: 30,
    features: {
      freeSpins: true,
      bonusGame: true,
      wildExpand: true,
      progressiveJackpot: false,
    },
  },
  "Yggdrasil": {
    name: "Yggdrasil",
    rtp: 96.2,
    volatility: "very_high",
    reels: 5,
    rows: 3,
    paylines: 25,
    features: {
      freeSpins: true,
      bonusGame: true,
      wildExpand: true,
      progressiveJackpot: true,
    },
  },
};

// ─── GAME CONFIGURATION FACTORY ────────────────────────────────────────────────

export function createGameConfigFromProvider(
  gameId: number,
  provider: string,
  theme: GameTheme = GameTheme.CLASSIC,
  customRtp?: number
): GameConfig {
  const providerConfig = PROVIDER_CONFIGS[provider] || PROVIDER_CONFIGS["Pragmatic Play"];

  const config = createGameConfig(
    gameId,
    providerConfig.reels,
    3,
    providerConfig.paylines,
    customRtp ?? providerConfig.rtp,
    providerConfig.volatility
  );

  // Apply theme-specific customization
  const themeSymbols = THEME_SYMBOLS[theme] || THEME_SYMBOLS[GameTheme.CLASSIC];
  config.symbols = config.symbols.map((sym, idx) => ({
    ...sym,
    emoji: themeSymbols[idx % themeSymbols.length],
  }));

  return config;
}

// ─── GAME CATEGORY CONFIGURATIONS ─────────────────────────────────────────────

export interface CategoryConfig {
  name: string;
  defaultVolatility: "low" | "medium" | "high" | "very_high";
  defaultRtp: number;
  theme: GameTheme;
}

export const CATEGORY_CONFIGS: Record<string, CategoryConfig> = {
  slots: {
    name: "Classic Slots",
    defaultVolatility: "medium",
    defaultRtp: 96.0,
    theme: GameTheme.CLASSIC,
  },
  table: {
    name: "Table Games",
    defaultVolatility: "low",
    defaultRtp: 98.0,
    theme: GameTheme.LUXURY,
  },
  live: {
    name: "Live Dealers",
    defaultVolatility: "low",
    defaultRtp: 97.5,
    theme: GameTheme.LUXURY,
  },
  jackpot: {
    name: "Jackpot Games",
    defaultVolatility: "very_high",
    defaultRtp: 95.0,
    theme: GameTheme.LUXURY,
  },
  new: {
    name: "New Releases",
    defaultVolatility: "high",
    defaultRtp: 96.5,
    theme: GameTheme.FANTASY,
  },
  popular: {
    name: "Popular Games",
    defaultVolatility: "medium",
    defaultRtp: 96.0,
    theme: GameTheme.CLASSIC,
  },
  crash: {
    name: "Crash Games",
    defaultVolatility: "very_high",
    defaultRtp: 94.0,
    theme: GameTheme.SPACE,
  },
  instant: {
    name: "Instant Games",
    defaultVolatility: "low",
    defaultRtp: 95.5,
    theme: GameTheme.CLASSIC,
  },
};

// ─── GAME INTEGRATION HELPER ──────────────────────────────────────────────────

export class GameIntegrationService {
  /**
   * Get game configuration for any game ID
   * Automatically determines provider, category, theme, and RTP
   */
  static getGameConfig(
    gameId: number,
    provider: string,
    category: string,
    customRtp?: number
  ): GameConfig {
    const categoryConfig = CATEGORY_CONFIGS[category] || CATEGORY_CONFIGS.slots;
    const providerConfig = PROVIDER_CONFIGS[provider] || PROVIDER_CONFIGS["Pragmatic Play"];

    // Merge configurations
    const finalRtp = customRtp ?? providerConfig.rtp ?? categoryConfig.defaultRtp;
    const finalVolatility = providerConfig.volatility ?? categoryConfig.defaultVolatility;
    const finalTheme = categoryConfig.theme;

    const config = createGameConfig(
      gameId,
      providerConfig.reels,
      3,
      providerConfig.paylines,
      finalRtp,
      finalVolatility
    );

    // Apply theme
    const themeSymbols = THEME_SYMBOLS[finalTheme];
    config.symbols = config.symbols.map((sym, idx) => ({
      ...sym,
      emoji: themeSymbols[idx % themeSymbols.length],
    }));

    // Apply provider features
    config.features = {
      freeSpinsOnScatter: providerConfig.features.freeSpins
        ? { scatterCount: 3, freeSpins: 10, multiplier: 2 }
        : undefined,
      wildExpand: providerConfig.features.wildExpand,
      wildSticky: false,
      bonusGame: providerConfig.features.bonusGame,
      progressiveJackpot: providerConfig.features.progressiveJackpot,
    };

    return config;
  }

  /**
   * Get all available providers
   */
  static getProviders(): string[] {
    return Object.keys(PROVIDER_CONFIGS);
  }

  /**
   * Get all available themes
   */
  static getThemes(): GameTheme[] {
    return Object.values(GameTheme);
  }

  /**
   * Get all available categories
   */
  static getCategories(): string[] {
    return Object.keys(CATEGORY_CONFIGS);
  }

  /**
   * Validate game configuration
   */
  static validateGameConfig(config: GameConfig): { valid: boolean; errors: string[] } {
    const errors: string[] = [];

    if (config.reels < 3 || config.reels > 7) {
      errors.push("Reels must be between 3 and 7");
    }

    if (config.rows < 1 || config.rows > 5) {
      errors.push("Rows must be between 1 and 5");
    }

    if (config.paylines < 1 || config.paylines > 100) {
      errors.push("Paylines must be between 1 and 100");
    }

    if (config.rtp < 85 || config.rtp > 99) {
      errors.push("RTP must be between 85% and 99%");
    }

    if (config.symbols.length < 8) {
      errors.push("Must have at least 8 symbols");
    }

    return {
      valid: errors.length === 0,
      errors,
    };
  }
}

// ─── GAME STATISTICS TRACKER ──────────────────────────────────────────────────

export interface GameStats {
  gameId: number;
  totalPlays: number;
  totalBetAmount: number;
  totalWinAmount: number;
  averageMultiplier: number;
  winRate: number;
  lastPlayedAt: Date;
}

export class GameStatsTracker {
  private stats = new Map<number, GameStats>();

  recordPlay(
    gameId: number,
    betAmount: number,
    winAmount: number,
    multiplier: number
  ): void {
    const stat = this.stats.get(gameId) || {
      gameId,
      totalPlays: 0,
      totalBetAmount: 0,
      totalWinAmount: 0,
      averageMultiplier: 0,
      winRate: 0,
      lastPlayedAt: new Date(),
    };

    stat.totalPlays++;
    stat.totalBetAmount += betAmount;
    stat.totalWinAmount += winAmount;
    stat.averageMultiplier = (stat.averageMultiplier * (stat.totalPlays - 1) + multiplier) / stat.totalPlays;
    stat.winRate = stat.totalWinAmount / stat.totalBetAmount;
    stat.lastPlayedAt = new Date();

    this.stats.set(gameId, stat);
  }

  getStats(gameId: number): GameStats | undefined {
    return this.stats.get(gameId);
  }

  getAllStats(): GameStats[] {
    return Array.from(this.stats.values());
  }

  getTopGames(limit: number = 10): GameStats[] {
    return this.getAllStats()
      .sort((a, b) => b.totalPlays - a.totalPlays)
      .slice(0, limit);
  }

  getMostProfitableGames(limit: number = 10): GameStats[] {
    return this.getAllStats()
      .sort((a, b) => b.totalWinAmount - a.totalWinAmount)
      .slice(0, limit);
  }
}
