import { EventEmitter } from 'events';

export interface AIGameRegistration {
  id: string;
  gameId: string;
  title: string;
  genre: string;
  htmlCode: string;
  thumbnailUrl: string;
  previewUrl: string;
  status: 'draft' | 'testing' | 'active' | 'archived';
  walletIntegration: {
    supportsSC: boolean;
    supportsGC: boolean;
    minBet: number;
    maxBet: number;
  };
  stats: {
    totalPlays: number;
    totalPlayers: number;
    totalRevenue: number;
    avgPlaytime: number;
  };
  createdAt: Date;
  deployedAt?: Date;
  version: number;
}

export interface GameDeployment {
  id: string;
  gameId: string;
  version: number;
  deploymentUrl: string;
  status: 'deploying' | 'active' | 'rollback';
  deployedAt: Date;
  rollbackUrl?: string;
}

/**
 * AI Game Casino Integration Service
 * Manages integration of AI-generated games into the casino platform
 */
export class AIGameCasinoIntegrationService extends EventEmitter {
  private registrations: Map<string, AIGameRegistration> = new Map();
  private deployments: Map<string, GameDeployment> = new Map();
  private gameVersions: Map<string, AIGameRegistration[]> = new Map();

  constructor() {
    super();
    console.log('[AIGameCasino] Integration service initialized');
  }

  /**
   * Register AI-generated game for casino
   */
  registerGame(game: Partial<AIGameRegistration>): AIGameRegistration {
    const registration: AIGameRegistration = {
      id: `reg-${Date.now()}`,
      gameId: game.gameId || `game-${Date.now()}`,
      title: game.title || 'Untitled Game',
      genre: game.genre || 'slot',
      htmlCode: game.htmlCode || '',
      thumbnailUrl: game.thumbnailUrl || '',
      previewUrl: game.previewUrl || '',
      status: 'draft',
      walletIntegration: {
        supportsSC: true,
        supportsGC: true,
        minBet: game.walletIntegration?.minBet || 0.25,
        maxBet: game.walletIntegration?.maxBet || 100,
      },
      stats: {
        totalPlays: 0,
        totalPlayers: 0,
        totalRevenue: 0,
        avgPlaytime: 0,
      },
      createdAt: new Date(),
      version: 1,
    };

    this.registrations.set(registration.id, registration);

    // Track versions
    if (!this.gameVersions.has(registration.gameId)) {
      this.gameVersions.set(registration.gameId, []);
    }
    this.gameVersions.get(registration.gameId)!.push(registration);

    this.emit('gameRegistered', registration);
    console.log(`[AIGameCasino] Game registered: ${registration.id}`);

    return registration;
  }

  /**
   * Get registered game
   */
  getGame(registrationId: string): AIGameRegistration | undefined {
    return this.registrations.get(registrationId);
  }

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

  /**
   * Get games by genre
   */
  getGamesByGenre(genre: string): AIGameRegistration[] {
    return Array.from(this.registrations.values()).filter((g) => g.genre === genre && g.status === 'active');
  }

  /**
   * Deploy game to casino
   */
  async deployGame(registrationId: string): Promise<GameDeployment> {
    const registration = this.registrations.get(registrationId);
    if (!registration) {
      throw new Error('Game registration not found');
    }

    const deployment: GameDeployment = {
      id: `deploy-${Date.now()}`,
      gameId: registration.gameId,
      version: registration.version,
      deploymentUrl: `https://games.coinkrazy.com/${registration.gameId}/v${registration.version}`,
      status: 'deploying',
      deployedAt: new Date(),
    };

    this.deployments.set(deployment.id, deployment);

    // Simulate deployment
    setTimeout(() => {
      deployment.status = 'active';
      registration.status = 'active';
      registration.deployedAt = new Date();

      this.emit('gameDeployed', deployment);
      console.log(`[AIGameCasino] Game deployed: ${deployment.deploymentUrl}`);
    }, 2000);

    this.emit('deploymentStarted', deployment);

    return deployment;
  }

  /**
   * Update game version
   */
  updateGameVersion(registrationId: string, newHtmlCode: string): AIGameRegistration {
    const registration = this.registrations.get(registrationId);
    if (!registration) {
      throw new Error('Game registration not found');
    }

    // Create new version
    const newVersion: AIGameRegistration = {
      ...registration,
      id: `reg-${Date.now()}`,
      htmlCode: newHtmlCode,
      version: registration.version + 1,
      status: 'testing',
      createdAt: new Date(),
      deployedAt: undefined,
    };

    this.registrations.set(newVersion.id, newVersion);

    // Track version
    if (!this.gameVersions.has(registration.gameId)) {
      this.gameVersions.set(registration.gameId, []);
    }
    this.gameVersions.get(registration.gameId)!.push(newVersion);

    this.emit('gameVersionCreated', newVersion);
    console.log(`[AIGameCasino] Game version created: ${newVersion.id} (v${newVersion.version})`);

    return newVersion;
  }

  /**
   * Rollback to previous version
   */
  rollbackVersion(gameId: string, targetVersion: number): GameDeployment | null {
    const versions = this.gameVersions.get(gameId) || [];
    const targetReg = versions.find((v) => v.version === targetVersion);

    if (!targetReg) {
      console.error(`[AIGameCasino] Version ${targetVersion} not found for game ${gameId}`);
      return null;
    }

    const rollback: GameDeployment = {
      id: `rollback-${Date.now()}`,
      gameId,
      version: targetVersion,
      deploymentUrl: `https://games.coinkrazy.com/${gameId}/v${targetVersion}`,
      status: 'rollback',
      deployedAt: new Date(),
    };

    this.deployments.set(rollback.id, rollback);

    this.emit('gameRolledBack', rollback);
    console.log(`[AIGameCasino] Game rolled back to v${targetVersion}`);

    return rollback;
  }

  /**
   * Update game statistics
   */
  updateGameStats(registrationId: string, stats: Partial<AIGameRegistration['stats']>): AIGameRegistration | undefined {
    const registration = this.registrations.get(registrationId);
    if (!registration) return undefined;

    if (stats.totalPlays !== undefined) registration.stats.totalPlays = stats.totalPlays;
    if (stats.totalPlayers !== undefined) registration.stats.totalPlayers = stats.totalPlayers;
    if (stats.totalRevenue !== undefined) registration.stats.totalRevenue = stats.totalRevenue;
    if (stats.avgPlaytime !== undefined) registration.stats.avgPlaytime = stats.avgPlaytime;

    this.emit('gameStatsUpdated', registration);

    return registration;
  }

  /**
   * Record game play
   */
  recordGamePlay(registrationId: string, playData: { playerId: string; betAmount: number; winAmount: number; duration: number }): void {
    const registration = this.registrations.get(registrationId);
    if (!registration) return;

    registration.stats.totalPlays++;
    registration.stats.totalRevenue += playData.betAmount - playData.winAmount;
    registration.stats.avgPlaytime = (registration.stats.avgPlaytime * (registration.stats.totalPlays - 1) + playData.duration) / registration.stats.totalPlays;

    this.emit('gamePlayRecorded', { registrationId, playData });
  }

  /**
   * Get game versions
   */
  getGameVersions(gameId: string): AIGameRegistration[] {
    return this.gameVersions.get(gameId) || [];
  }

  /**
   * Get deployment history
   */
  getDeploymentHistory(gameId: string): GameDeployment[] {
    return Array.from(this.deployments.values()).filter((d) => d.gameId === gameId);
  }

  /**
   * Get integration statistics
   */
  getIntegrationStats() {
    const allGames = Array.from(this.registrations.values());
    const activeGames = allGames.filter((g) => g.status === 'active');
    const totalRevenue = activeGames.reduce((sum, g) => sum + g.stats.totalRevenue, 0);
    const totalPlays = activeGames.reduce((sum, g) => sum + g.stats.totalPlays, 0);

    return {
      totalRegistered: this.registrations.size,
      activeGames: activeGames.length,
      totalDeployments: this.deployments.size,
      totalRevenue,
      totalPlays,
      avgRevenuePerGame: activeGames.length > 0 ? totalRevenue / activeGames.length : 0,
      topGame: activeGames.sort((a, b) => b.stats.totalRevenue - a.stats.totalRevenue)[0],
    };
  }

  /**
   * Validate game for casino
   */
  validateGameForCasino(registration: AIGameRegistration): { valid: boolean; errors: string[] } {
    const errors: string[] = [];

    if (!registration.htmlCode) errors.push('Missing game code');
    if (!registration.title) errors.push('Missing game title');
    if (!registration.thumbnailUrl) errors.push('Missing thumbnail');
    if (!registration.walletIntegration.supportsSC && !registration.walletIntegration.supportsGC) {
      errors.push('Game must support at least one currency');
    }
    if (registration.walletIntegration.minBet < 0) errors.push('Invalid minimum bet');
    if (registration.walletIntegration.maxBet <= registration.walletIntegration.minBet) {
      errors.push('Max bet must be greater than min bet');
    }

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

  /**
   * Clear all data
   */
  clear(): void {
    this.registrations.clear();
    this.deployments.clear();
    this.gameVersions.clear();
    console.log('[AIGameCasino] Service cleared');
  }
}

export const aiGameCasinoIntegrationService = new AIGameCasinoIntegrationService();
