import { Injectable, OnModuleInit, NotFoundException } from '@nestjs/common';
import * as fs from 'fs';
import * as path from 'path';

interface GameData {
  gameId: string;
  name: string;
  version: string;
  description: string;
  config: Record<string, unknown>;
}

@Injectable()
export class GameConfigService implements OnModuleInit {
  private games = new Map<string, GameData>();

  onModuleInit() {
    this.loadAllGames();
  }

  private loadAllGames() {
    const gamesDir = path.join(__dirname, '..', 'data', 'games');

    if (!fs.existsSync(gamesDir)) {
      console.warn(`Games directory not found: ${gamesDir}`);
      return;
    }

    const files = fs.readdirSync(gamesDir).filter((f) => f.endsWith('.json'));

    for (const file of files) {
      const gameName = file.replace('.json', '');
      const filePath = path.join(gamesDir, file);
      const raw = fs.readFileSync(filePath, 'utf-8');
      const data: GameData = JSON.parse(raw);
      this.games.set(gameName, data);
      console.log(`Loaded game: ${gameName} (${data.name})`);
    }

    console.log(`Total games loaded: ${this.games.size}`);
  }

  listGames() {
    return Array.from(this.games.entries()).map(([key, game]) => ({
      gameName: key,
      gameId: game.gameId,
      name: game.name,
      version: game.version,
      description: game.description,
    }));
  }

  private getGame(gameName: string): GameData {
    const game = this.games.get(gameName);
    if (!game) {
      const available = Array.from(this.games.keys());
      throw new NotFoundException(
        `Game "${gameName}" not found. Available: ${available.join(', ')}`,
      );
    }
    return game;
  }

  private getConfig(gameName: string): Record<string, unknown> {
    return this.getGame(gameName).config;
  }

  getFullConfig(gameName: string) {
    return this.getGame(gameName);
  }

  getGrid(gameName: string) {
    return (this.getConfig(gameName) as any).grid;
  }

  getSymbols(gameName: string) {
    return (this.getConfig(gameName) as any).symbols;
  }

  getPayTable(gameName: string) {
    return (this.getConfig(gameName) as any).payTable;
  }

  getRules(gameName: string) {
    return (this.getConfig(gameName) as any).rules;
  }

  getOptions(gameName: string) {
    return (this.getConfig(gameName) as any).options;
  }

  getStates(gameName: string) {
    return (this.getConfig(gameName) as any).states;
  }

  getWinTypes(gameName: string) {
    return (this.getConfig(gameName) as any).winTypes;
  }

  getMechanics(gameName: string) {
    return (this.getConfig(gameName) as any).mechanics;
  }

  getModes(gameName: string) {
    return (this.getConfig(gameName) as any).modes;
  }
}
