/**
 * Seasonal Leaderboard Events System
 * Limited-time leaderboard competitions with bonus multipliers and rewards
 */

export interface SeasonalEvent {
  id: string;
  name: string;
  description: string;
  type: 'competition' | 'tournament' | 'challenge';
  startDate: Date;
  endDate: Date;
  gameIds: string[];
  bonusMultiplier: number;
  prizePool: number;
  maxParticipants?: number;
  rewards: {
    rank: number;
    prize: number;
    cosmetic?: string;
  }[];
  rules: string[];
  active: boolean;
}

export class SeasonalLeaderboardEvents {
  private static events: Map<string, SeasonalEvent> = new Map();

  /**
   * Create seasonal event
   */
  static createEvent(event: Omit<SeasonalEvent, 'id'>): SeasonalEvent {
    const id = `event_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    const fullEvent: SeasonalEvent = { ...event, id };
    this.events.set(id, fullEvent);
    return fullEvent;
  }

  /**
   * Get active events
   */
  static getActiveEvents(): SeasonalEvent[] {
    const now = new Date();
    return Array.from(this.events.values()).filter(
      (event) => event.active && event.startDate <= now && event.endDate > now
    );
  }

  /**
   * Get upcoming events
   */
  static getUpcomingEvents(limit: number = 10): SeasonalEvent[] {
    const now = new Date();
    return Array.from(this.events.values())
      .filter((event) => event.startDate > now)
      .sort((a, b) => a.startDate.getTime() - b.startDate.getTime())
      .slice(0, limit);
  }

  /**
   * Get event by ID
   */
  static getEvent(eventId: string): SeasonalEvent | null {
    return this.events.get(eventId) || null;
  }

  /**
   * Get events for specific game
   */
  static getGameEvents(gameId: string): SeasonalEvent[] {
    return Array.from(this.events.values()).filter((event) => event.gameIds.includes(gameId));
  }

  /**
   * Calculate bonus multiplier for player
   */
  static getBonusMultiplier(userId: string, eventId: string): number {
    const event = this.getEvent(eventId);
    if (!event || !event.active) return 1;

    const now = new Date();
    if (now < event.startDate || now > event.endDate) return 1;

    return event.bonusMultiplier;
  }

  /**
   * Get event leaderboard
   */
  static getEventLeaderboard(eventId: string, limit: number = 100): any[] {
    const event = this.getEvent(eventId);
    if (!event) return [];

    // In production, query event_leaderboard table
    return [
      { rank: 1, playerName: 'TopPlayer', score: 50000, eventId },
      { rank: 2, playerName: 'SecondPlace', score: 45000, eventId },
      { rank: 3, playerName: 'ThirdPlace', score: 40000, eventId },
    ].slice(0, limit);
  }

  /**
   * Get player event stats
   */
  static getPlayerEventStats(userId: string, eventId: string): any {
    return {
      userId,
      eventId,
      totalWagered: 10000,
      totalWon: 5000,
      rank: 25,
      prizeEarned: 0,
      bonusEarned: 2500,
    };
  }

  /**
   * Calculate prize for rank
   */
  static getPrizeForRank(eventId: string, rank: number): number {
    const event = this.getEvent(eventId);
    if (!event) return 0;

    const reward = event.rewards.find((r) => r.rank === rank);
    return reward?.prize || 0;
  }

  /**
   * Initialize preset seasonal events
   */
  static initializePresetEvents(): void {
    // Summer Spin Challenge
    this.createEvent({
      name: 'Summer Spin Challenge',
      description: 'Spin your way to victory this summer! Extra 2x multiplier on all wins.',
      type: 'competition',
      startDate: new Date('2026-06-01'),
      endDate: new Date('2026-08-31'),
      gameIds: ['all'],
      bonusMultiplier: 2,
      prizePool: 50000,
      maxParticipants: 10000,
      rewards: [
        { rank: 1, prize: 5000, cosmetic: 'gold_trophy' },
        { rank: 2, prize: 3000, cosmetic: 'silver_trophy' },
        { rank: 3, prize: 2000, cosmetic: 'bronze_trophy' },
        { rank: 4, prize: 1000 },
        { rank: 5, prize: 500 },
      ],
      rules: [
        'Play any slot game',
        'Earn points based on wins',
        'Top 5 players win prizes',
        'Event ends August 31st',
      ],
      active: false,
    });

    // Holiday Jackpot Blitz
    this.createEvent({
      name: 'Holiday Jackpot Blitz',
      description: 'December special! 3x multiplier and exclusive holiday cosmetics.',
      type: 'tournament',
      startDate: new Date('2026-12-01'),
      endDate: new Date('2026-12-31'),
      gameIds: ['all'],
      bonusMultiplier: 3,
      prizePool: 100000,
      maxParticipants: 50000,
      rewards: [
        { rank: 1, prize: 10000, cosmetic: 'holiday_crown' },
        { rank: 2, prize: 5000, cosmetic: 'holiday_badge' },
        { rank: 3, prize: 3000 },
        { rank: 4, prize: 2000 },
        { rank: 5, prize: 1000 },
      ],
      rules: [
        'Play any slot game',
        'Earn holiday points',
        'Top 5 players win major prizes',
        'Bonus cosmetics for top 10',
      ],
      active: false,
    });

    // Spring Mega Spin
    this.createEvent({
      name: 'Spring Mega Spin',
      description: 'Spring into action! 1.5x multiplier on all spins.',
      type: 'challenge',
      startDate: new Date('2026-03-01'),
      endDate: new Date('2026-05-31'),
      gameIds: ['all'],
      bonusMultiplier: 1.5,
      prizePool: 25000,
      rewards: [
        { rank: 1, prize: 2500 },
        { rank: 2, prize: 1500 },
        { rank: 3, prize: 1000 },
      ],
      rules: [
        'Spin to accumulate points',
        'Bigger wins = more points',
        'Top 3 win prizes',
      ],
      active: false,
    });

    // Fall Festival
    this.createEvent({
      name: 'Fall Festival',
      description: 'Autumn celebration! 2x multiplier and exclusive fall cosmetics.',
      type: 'competition',
      startDate: new Date('2026-09-01'),
      endDate: new Date('2026-11-30'),
      gameIds: ['all'],
      bonusMultiplier: 2,
      prizePool: 40000,
      rewards: [
        { rank: 1, prize: 4000, cosmetic: 'fall_crown' },
        { rank: 2, prize: 2500 },
        { rank: 3, prize: 1500 },
      ],
      rules: [
        'Compete in fall-themed games',
        'Earn festival points',
        'Win exclusive cosmetics',
      ],
      active: false,
    });
  }

  /**
   * Get event rewards for player
   */
  static getEventRewards(userId: string, eventId: string): any {
    const stats = this.getPlayerEventStats(userId, eventId);
    const prize = this.getPrizeForRank(eventId, stats.rank);

    return {
      userId,
      eventId,
      prizeWon: prize,
      bonusMultiplierEarnings: stats.bonusEarned,
      totalRewards: prize + stats.bonusEarned,
      cosmetics: [],
    };
  }

  /**
   * Distribute event prizes
   */
  static async distributeEventPrizes(eventId: string): Promise<void> {
    const event = this.getEvent(eventId);
    if (!event) return;

    const leaderboard = this.getEventLeaderboard(eventId, 100);

    for (const entry of leaderboard) {
      const prize = this.getPrizeForRank(eventId, entry.rank);
      if (prize > 0) {
        // In production, credit wallet and send notification
        console.log(`[Event] Distributing $${prize} to player ${entry.playerName}`);
      }
    }

    // Mark event as completed
    event.active = false;
  }

  /**
   * Get event statistics
   */
  static getEventStats(eventId: string): any {
    const event = this.getEvent(eventId);
    if (!event) return null;

    const leaderboard = this.getEventLeaderboard(eventId, 1000);

    return {
      eventId,
      name: event.name,
      totalParticipants: leaderboard.length,
      totalPrizePool: event.prizePool,
      averageWin: leaderboard.reduce((sum, e) => sum + e.score, 0) / leaderboard.length,
      topScore: leaderboard[0]?.score || 0,
      daysRemaining: Math.ceil((event.endDate.getTime() - Date.now()) / (1000 * 60 * 60 * 24)),
    };
  }
}

// Initialize preset events on module load
SeasonalLeaderboardEvents.initializePresetEvents();
