/**
 * VIP Tier System
 * Manages player tiers and associated rewards
 */

export enum VIPTier {
  BRONZE = "bronze",
  SILVER = "silver",
  GOLD = "gold",
  PLATINUM = "platinum",
}

export interface VIPTierBenefits {
  tier: VIPTier;
  minPoints: number;
  maxPoints: number;
  bonusMultiplier: number; // e.g., 1.1 = 10% bonus
  dailyBonus: number; // GC
  weeklyBonus: number; // GC
  monthlyBonus: number; // GC
  exclusiveGames: boolean;
  dedicatedSupport: boolean;
  cashbackPercentage: number; // percentage
  tournamentDiscount: number; // percentage
  freeSpinsMonthly: number;
  vipBadge: string;
}

export interface PlayerVIPStatus {
  userId: number;
  userName: string;
  currentTier: VIPTier;
  totalPoints: number;
  pointsToNextTier: number;
  joinedDate: string;
  lastBonusClaimDate: string;
  totalBonusClaimed: number;
  totalCashback: number;
  freeSpinsRemaining: number;
}

// VIP Tier definitions
const tierBenefits: Map<VIPTier, VIPTierBenefits> = new Map([
  [
    VIPTier.BRONZE,
    {
      tier: VIPTier.BRONZE,
      minPoints: 0,
      maxPoints: 999,
      bonusMultiplier: 1.05,
      dailyBonus: 10,
      weeklyBonus: 50,
      monthlyBonus: 150,
      exclusiveGames: false,
      dedicatedSupport: false,
      cashbackPercentage: 1,
      tournamentDiscount: 5,
      freeSpinsMonthly: 5,
      vipBadge: "🥉 Bronze",
    },
  ],
  [
    VIPTier.SILVER,
    {
      tier: VIPTier.SILVER,
      minPoints: 1000,
      maxPoints: 4999,
      bonusMultiplier: 1.1,
      dailyBonus: 25,
      weeklyBonus: 100,
      monthlyBonus: 350,
      exclusiveGames: true,
      dedicatedSupport: false,
      cashbackPercentage: 2,
      tournamentDiscount: 10,
      freeSpinsMonthly: 15,
      vipBadge: "🥈 Silver",
    },
  ],
  [
    VIPTier.GOLD,
    {
      tier: VIPTier.GOLD,
      minPoints: 5000,
      maxPoints: 14999,
      bonusMultiplier: 1.15,
      dailyBonus: 50,
      weeklyBonus: 200,
      monthlyBonus: 750,
      exclusiveGames: true,
      dedicatedSupport: true,
      cashbackPercentage: 3,
      tournamentDiscount: 15,
      freeSpinsMonthly: 30,
      vipBadge: "🥇 Gold",
    },
  ],
  [
    VIPTier.PLATINUM,
    {
      tier: VIPTier.PLATINUM,
      minPoints: 15000,
      maxPoints: Infinity,
      bonusMultiplier: 1.25,
      dailyBonus: 100,
      weeklyBonus: 400,
      monthlyBonus: 1500,
      exclusiveGames: true,
      dedicatedSupport: true,
      cashbackPercentage: 5,
      tournamentDiscount: 25,
      freeSpinsMonthly: 50,
      vipBadge: "💎 Platinum",
    },
  ],
]);

// Player VIP status storage
const playerVIPStatus: Map<number, PlayerVIPStatus> = new Map();

/**
 * Get or create player VIP status
 */
export function getOrCreatePlayerVIPStatus(userId: number, userName: string): PlayerVIPStatus {
  let status = playerVIPStatus.get(userId);

  if (!status) {
    status = {
      userId,
      userName,
      currentTier: VIPTier.BRONZE,
      totalPoints: 0,
      pointsToNextTier: 1000,
      joinedDate: new Date().toISOString(),
      lastBonusClaimDate: new Date().toISOString(),
      totalBonusClaimed: 0,
      totalCashback: 0,
      freeSpinsRemaining: 5,
    };
    playerVIPStatus.set(userId, status);
  }

  return status;
}

/**
 * Add VIP points to player
 */
export function addVIPPoints(userId: number, points: number): PlayerVIPStatus | undefined {
  const status = playerVIPStatus.get(userId);

  if (!status) {
    return undefined;
  }

  status.totalPoints += points;

  // Check if tier upgrade is needed
  updatePlayerTier(userId);

  return status;
}

/**
 * Update player tier based on points
 */
function updatePlayerTier(userId: number): void {
  const status = playerVIPStatus.get(userId);

  if (!status) {
    return;
  }

  let newTier = VIPTier.BRONZE;

  if (status.totalPoints >= 15000) {
    newTier = VIPTier.PLATINUM;
  } else if (status.totalPoints >= 5000) {
    newTier = VIPTier.GOLD;
  } else if (status.totalPoints >= 1000) {
    newTier = VIPTier.SILVER;
  }

  if (newTier !== status.currentTier) {
    console.log(`[VIPTierService] Player ${userId} upgraded to ${newTier}`);
    status.currentTier = newTier;
  }

  // Calculate points to next tier
  const currentTierBenefits = tierBenefits.get(status.currentTier);
  const nextTierPoints = currentTierBenefits?.maxPoints || Infinity;

  status.pointsToNextTier = Math.max(0, nextTierPoints - status.totalPoints + 1);
}

/**
 * Get player VIP status
 */
export function getPlayerVIPStatus(userId: number): PlayerVIPStatus | undefined {
  return playerVIPStatus.get(userId);
}

/**
 * Get VIP tier benefits
 */
export function getVIPTierBenefits(tier: VIPTier): VIPTierBenefits | undefined {
  return tierBenefits.get(tier);
}

/**
 * Claim daily bonus
 */
export function claimDailyBonus(userId: number): { success: boolean; bonus: number } {
  const status = playerVIPStatus.get(userId);

  if (!status) {
    return { success: false, bonus: 0 };
  }

  const lastClaim = new Date(status.lastBonusClaimDate);
  const now = new Date();

  // Check if 24 hours have passed
  const hoursPassed = (now.getTime() - lastClaim.getTime()) / (1000 * 60 * 60);

  if (hoursPassed < 24) {
    return { success: false, bonus: 0 };
  }

  const benefits = tierBenefits.get(status.currentTier);
  const bonus = benefits?.dailyBonus || 0;

  status.lastBonusClaimDate = now.toISOString();
  status.totalBonusClaimed += bonus;

  return { success: true, bonus };
}

/**
 * Calculate cashback for a transaction
 */
export function calculateCashback(userId: number, amount: number): number {
  const status = playerVIPStatus.get(userId);

  if (!status) {
    return 0;
  }

  const benefits = tierBenefits.get(status.currentTier);
  const cashbackPercentage = benefits?.cashbackPercentage || 0;

  const cashback = (amount * cashbackPercentage) / 100;
  status.totalCashback += cashback;

  return cashback;
}

/**
 * Get tournament discount
 */
export function getTournamentDiscount(userId: number): number {
  const status = playerVIPStatus.get(userId);

  if (!status) {
    return 0;
  }

  const benefits = tierBenefits.get(status.currentTier);
  return benefits?.tournamentDiscount || 0;
}

/**
 * Add free spins
 */
export function addFreeSpins(userId: number, spins: number): number {
  const status = playerVIPStatus.get(userId);

  if (!status) {
    return 0;
  }

  status.freeSpinsRemaining += spins;
  return status.freeSpinsRemaining;
}

/**
 * Use free spins
 */
export function useFreeSpins(userId: number, spins: number): { success: boolean; remaining: number } {
  const status = playerVIPStatus.get(userId);

  if (!status) {
    return { success: false, remaining: 0 };
  }

  if (status.freeSpinsRemaining < spins) {
    return { success: false, remaining: status.freeSpinsRemaining };
  }

  status.freeSpinsRemaining -= spins;
  return { success: true, remaining: status.freeSpinsRemaining };
}

/**
 * Get all VIP tier benefits
 */
export function getAllVIPTierBenefits(): VIPTierBenefits[] {
  return Array.from(tierBenefits.values());
}

/**
 * Get VIP tier progression
 */
export function getVIPTierProgression(userId: number): {
  currentTier: VIPTier;
  currentPoints: number;
  pointsToNextTier: number;
  progressPercentage: number;
  nextTier: VIPTier | null;
} {
  const status = playerVIPStatus.get(userId);

  if (!status) {
    return {
      currentTier: VIPTier.BRONZE,
      currentPoints: 0,
      pointsToNextTier: 1000,
      progressPercentage: 0,
      nextTier: VIPTier.SILVER,
    };
  }

  const currentBenefits = tierBenefits.get(status.currentTier);
  const nextTierPoints = currentBenefits?.maxPoints || Infinity;
  const currentTierPoints = currentBenefits?.minPoints || 0;

  const pointsInTier = status.totalPoints - currentTierPoints;
  const pointsNeededForTier = nextTierPoints - currentTierPoints;
  const progressPercentage = (pointsInTier / pointsNeededForTier) * 100;

  let nextTier: VIPTier | null = null;
  if (status.currentTier === VIPTier.BRONZE) nextTier = VIPTier.SILVER;
  else if (status.currentTier === VIPTier.SILVER) nextTier = VIPTier.GOLD;
  else if (status.currentTier === VIPTier.GOLD) nextTier = VIPTier.PLATINUM;

  return {
    currentTier: status.currentTier,
    currentPoints: status.totalPoints,
    pointsToNextTier: status.pointsToNextTier,
    progressPercentage: Math.min(100, progressPercentage),
    nextTier,
  };
}
