/**
 * Badge Leaderboard Service
 * Manages badge collection leaderboards and rankings
 */

import { db } from './db.ts';

export interface BadgeLeaderboardEntry {
  rank: number;
  userId: string;
  username: string;
  totalBadges: number;
  totalBadgePoints: number;
  rareCount: number;
  epicCount: number;
  legendaryCount: number;
  lastBadgeEarned: Date;
  streak: number;
}

export interface PlayerBadgeStats {
  userId: string;
  totalBadges: number;
  totalBadgePoints: number;
  commonCount: number;
  uncommonCount: number;
  rareCount: number;
  epicCount: number;
  legendaryCount: number;
  completionPercentage: number;
  rank: number;
  nextMilestone: number;
}

/**
 * Get global badge leaderboard
 */
export async function getGlobalBadgeLeaderboard(limit: number = 100): Promise<BadgeLeaderboardEntry[]> {
  try {
    // Mock leaderboard data
    const leaderboard: BadgeLeaderboardEntry[] = Array.from({ length: Math.min(limit, 100) }, (_, i) => ({
      rank: i + 1,
      userId: `user-${i + 1}`,
      username: `Player${i + 1}`,
      totalBadges: Math.max(1, 15 - Math.floor(i / 10)),
      totalBadgePoints: (15 - Math.floor(i / 10)) * 100,
      rareCount: Math.max(0, 5 - Math.floor(i / 20)),
      epicCount: Math.max(0, 3 - Math.floor(i / 30)),
      legendaryCount: Math.max(0, 1 - Math.floor(i / 50)),
      lastBadgeEarned: new Date(Date.now() - Math.random() * 7 * 24 * 60 * 60 * 1000),
      streak: Math.max(1, 10 - Math.floor(i / 15)),
    }));

    console.log(`[BadgeLeaderboard] Retrieved global leaderboard with ${leaderboard.length} entries`);
    return leaderboard;
  } catch (error) {
    console.error('[BadgeLeaderboard] Error fetching global leaderboard:', error);
    return [];
  }
}

/**
 * Get category-specific leaderboard
 */
export async function getCategoryLeaderboard(
  category: 'gameplay' | 'social' | 'vip' | 'special',
  limit: number = 50
): Promise<BadgeLeaderboardEntry[]> {
  try {
    // Mock category leaderboard
    const leaderboard: BadgeLeaderboardEntry[] = Array.from({ length: Math.min(limit, 50) }, (_, i) => ({
      rank: i + 1,
      userId: `user-${i + 1}`,
      username: `Player${i + 1}`,
      totalBadges: Math.max(1, 5 - Math.floor(i / 10)),
      totalBadgePoints: (5 - Math.floor(i / 10)) * 50,
      rareCount: Math.max(0, 2 - Math.floor(i / 20)),
      epicCount: Math.max(0, 1 - Math.floor(i / 30)),
      legendaryCount: 0,
      lastBadgeEarned: new Date(Date.now() - Math.random() * 3 * 24 * 60 * 60 * 1000),
      streak: Math.max(1, 5 - Math.floor(i / 15)),
    }));

    console.log(`[BadgeLeaderboard] Retrieved ${category} leaderboard with ${leaderboard.length} entries`);
    return leaderboard;
  } catch (error) {
    console.error('[BadgeLeaderboard] Error fetching category leaderboard:', error);
    return [];
  }
}

/**
 * Get rarity-specific leaderboard
 */
export async function getRarityLeaderboard(
  rarity: 'rare' | 'epic' | 'legendary',
  limit: number = 50
): Promise<BadgeLeaderboardEntry[]> {
  try {
    // Mock rarity leaderboard
    const leaderboard: BadgeLeaderboardEntry[] = Array.from({ length: Math.min(limit, 50) }, (_, i) => {
      const rarityMultiplier = rarity === 'legendary' ? 3 : rarity === 'epic' ? 2 : 1;
      return {
        rank: i + 1,
        userId: `user-${i + 1}`,
        username: `Player${i + 1}`,
        totalBadges: Math.max(1, rarityMultiplier * (5 - Math.floor(i / 10))),
        totalBadgePoints: rarityMultiplier * (5 - Math.floor(i / 10)) * 100,
        rareCount: rarity === 'rare' ? Math.max(1, 5 - Math.floor(i / 10)) : 0,
        epicCount: rarity === 'epic' ? Math.max(1, 3 - Math.floor(i / 10)) : 0,
        legendaryCount: rarity === 'legendary' ? Math.max(1, 1 - Math.floor(i / 20)) : 0,
        lastBadgeEarned: new Date(Date.now() - Math.random() * 7 * 24 * 60 * 60 * 1000),
        streak: Math.max(1, 10 - Math.floor(i / 15)),
      };
    });

    console.log(`[BadgeLeaderboard] Retrieved ${rarity} leaderboard with ${leaderboard.length} entries`);
    return leaderboard;
  } catch (error) {
    console.error('[BadgeLeaderboard] Error fetching rarity leaderboard:', error);
    return [];
  }
}

/**
 * Get player badge statistics
 */
export async function getPlayerBadgeStats(userId: string): Promise<PlayerBadgeStats | null> {
  try {
    // Mock player stats
    const stats: PlayerBadgeStats = {
      userId,
      totalBadges: 12,
      totalBadgePoints: 1200,
      commonCount: 3,
      uncommonCount: 4,
      rareCount: 3,
      epicCount: 2,
      legendaryCount: 0,
      completionPercentage: 80,
      rank: 45,
      nextMilestone: 15,
    };

    console.log(`[BadgeLeaderboard] Retrieved badge stats for user ${userId}`);
    return stats;
  } catch (error) {
    console.error('[BadgeLeaderboard] Error fetching player badge stats:', error);
    return null;
  }
}

/**
 * Get player rank
 */
export async function getPlayerRank(userId: string): Promise<number | null> {
  try {
    // Mock rank calculation
    const rank = Math.floor(Math.random() * 1000) + 1;
    console.log(`[BadgeLeaderboard] Retrieved rank for user ${userId}: ${rank}`);
    return rank;
  } catch (error) {
    console.error('[BadgeLeaderboard] Error fetching player rank:', error);
    return null;
  }
}

/**
 * Get player percentile
 */
export async function getPlayerPercentile(userId: string): Promise<number | null> {
  try {
    const rank = await getPlayerRank(userId);
    if (!rank) return null;

    // Assuming 10000 total players
    const percentile = Math.round(((10000 - rank) / 10000) * 100);
    console.log(`[BadgeLeaderboard] Retrieved percentile for user ${userId}: ${percentile}%`);
    return percentile;
  } catch (error) {
    console.error('[BadgeLeaderboard] Error fetching player percentile:', error);
    return null;
  }
}

/**
 * Get friends leaderboard
 */
export async function getFriendsLeaderboard(userId: string): Promise<BadgeLeaderboardEntry[]> {
  try {
    // Mock friends leaderboard
    const friendsLeaderboard: BadgeLeaderboardEntry[] = [
      {
        rank: 1,
        userId,
        username: 'You',
        totalBadges: 12,
        totalBadgePoints: 1200,
        rareCount: 3,
        epicCount: 2,
        legendaryCount: 0,
        lastBadgeEarned: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000),
        streak: 5,
      },
      {
        rank: 2,
        userId: 'friend-1',
        username: 'Friend1',
        totalBadges: 10,
        totalBadgePoints: 1000,
        rareCount: 2,
        epicCount: 1,
        legendaryCount: 0,
        lastBadgeEarned: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000),
        streak: 3,
      },
      {
        rank: 3,
        userId: 'friend-2',
        username: 'Friend2',
        totalBadges: 8,
        totalBadgePoints: 800,
        rareCount: 1,
        epicCount: 1,
        legendaryCount: 0,
        lastBadgeEarned: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000),
        streak: 2,
      },
    ];

    console.log(`[BadgeLeaderboard] Retrieved friends leaderboard for user ${userId}`);
    return friendsLeaderboard;
  } catch (error) {
    console.error('[BadgeLeaderboard] Error fetching friends leaderboard:', error);
    return [];
  }
}

/**
 * Get weekly badge leaderboard
 */
export async function getWeeklyBadgeLeaderboard(limit: number = 50): Promise<BadgeLeaderboardEntry[]> {
  try {
    // Mock weekly leaderboard
    const leaderboard: BadgeLeaderboardEntry[] = Array.from({ length: Math.min(limit, 50) }, (_, i) => ({
      rank: i + 1,
      userId: `user-${i + 1}`,
      username: `Player${i + 1}`,
      totalBadges: Math.max(1, 5 - Math.floor(i / 10)),
      totalBadgePoints: (5 - Math.floor(i / 10)) * 100,
      rareCount: Math.max(0, 2 - Math.floor(i / 20)),
      epicCount: Math.max(0, 1 - Math.floor(i / 30)),
      legendaryCount: 0,
      lastBadgeEarned: new Date(Date.now() - Math.random() * 7 * 24 * 60 * 60 * 1000),
      streak: Math.max(1, 7 - Math.floor(i / 10)),
    }));

    console.log(`[BadgeLeaderboard] Retrieved weekly leaderboard with ${leaderboard.length} entries`);
    return leaderboard;
  } catch (error) {
    console.error('[BadgeLeaderboard] Error fetching weekly leaderboard:', error);
    return [];
  }
}

/**
 * Get monthly badge leaderboard
 */
export async function getMonthlyBadgeLeaderboard(limit: number = 50): Promise<BadgeLeaderboardEntry[]> {
  try {
    // Mock monthly leaderboard
    const leaderboard: BadgeLeaderboardEntry[] = Array.from({ length: Math.min(limit, 50) }, (_, i) => ({
      rank: i + 1,
      userId: `user-${i + 1}`,
      username: `Player${i + 1}`,
      totalBadges: Math.max(1, 10 - Math.floor(i / 10)),
      totalBadgePoints: (10 - Math.floor(i / 10)) * 100,
      rareCount: Math.max(0, 3 - Math.floor(i / 20)),
      epicCount: Math.max(0, 2 - Math.floor(i / 30)),
      legendaryCount: Math.max(0, 1 - Math.floor(i / 50)),
      lastBadgeEarned: new Date(Date.now() - Math.random() * 30 * 24 * 60 * 60 * 1000),
      streak: Math.max(1, 15 - Math.floor(i / 10)),
    }));

    console.log(`[BadgeLeaderboard] Retrieved monthly leaderboard with ${leaderboard.length} entries`);
    return leaderboard;
  } catch (error) {
    console.error('[BadgeLeaderboard] Error fetching monthly leaderboard:', error);
    return [];
  }
}

/**
 * Calculate badge collection completion
 */
export function calculateCollectionCompletion(playerStats: PlayerBadgeStats): number {
  const totalPossibleBadges = 15; // Total badges in system
  return Math.round((playerStats.totalBadges / totalPossibleBadges) * 100);
}

/**
 * Get next badge milestone
 */
export function getNextBadgeMilestone(totalBadges: number): { milestone: number; reward: number } {
  const milestones = [
    { milestone: 5, reward: 100 },
    { milestone: 10, reward: 250 },
    { milestone: 15, reward: 500 },
  ];

  for (const m of milestones) {
    if (totalBadges < m.milestone) {
      return m;
    }
  }

  return { milestone: 15, reward: 500 };
}
