/**
 * VIP Monitoring Service
 * Real-time tracking of VIP tier progression, rewards, and player analytics
 */

import { db } from './db.ts';
import { users, wallets, vipTiers, vipRewards, playerSegments } from '../drizzle/schema.ts';
import { eq, gte, lte, desc, and } from 'drizzle-orm';

// VIP Tier Configuration
export const VIP_TIER_CONFIG = {
  bronze: {
    name: 'Bronze',
    minSpend: 0,
    maxSpend: 999,
    multiplier: 1.0,
    rewardRate: 0.5,
    monthlyBonus: 50,
    exclusiveGames: 2,
    color: '#CD7F32',
  },
  silver: {
    name: 'Silver',
    minSpend: 1000,
    maxSpend: 4999,
    multiplier: 1.25,
    rewardRate: 0.75,
    monthlyBonus: 150,
    exclusiveGames: 5,
    color: '#C0C0C0',
  },
  gold: {
    name: 'Gold',
    minSpend: 5000,
    maxSpend: 14999,
    multiplier: 1.5,
    rewardRate: 1.0,
    monthlyBonus: 500,
    exclusiveGames: 10,
    color: '#FFD700',
  },
  platinum: {
    name: 'Platinum',
    minSpend: 15000,
    maxSpend: Infinity,
    multiplier: 2.0,
    rewardRate: 1.5,
    monthlyBonus: 2000,
    exclusiveGames: 20,
    color: '#E5E4E2',
  },
};

/**
 * Get VIP tier based on total spend
 */
export async function getPlayerVIPTier(userId: string) {
  const user = await db.query.users.findFirst({
    where: eq(users.id, userId),
  });

  if (!user) return null;

  const totalSpend = user.totalSpend || 0;

  for (const [tier, config] of Object.entries(VIP_TIER_CONFIG)) {
    if (totalSpend >= config.minSpend && totalSpend <= config.maxSpend) {
      return {
        tier,
        ...config,
        currentSpend: totalSpend,
        progressToNext: calculateProgressToNextTier(totalSpend, tier),
      };
    }
  }

  return {
    tier: 'platinum',
    ...VIP_TIER_CONFIG.platinum,
    currentSpend: totalSpend,
    progressToNext: 100,
  };
}

/**
 * Calculate progress to next tier
 */
function calculateProgressToNextTier(spend: number, currentTier: string): number {
  const tiers = Object.entries(VIP_TIER_CONFIG);
  const currentIndex = tiers.findIndex(([tier]) => tier === currentTier);

  if (currentIndex === -1 || currentIndex === tiers.length - 1) {
    return 100; // Already at max tier
  }

  const nextTier = tiers[currentIndex + 1];
  const nextMinSpend = nextTier[1].minSpend;
  const currentMinSpend = tiers[currentIndex][1].minSpend;
  const tierSpend = nextMinSpend - currentMinSpend;
  const playerSpend = spend - currentMinSpend;

  return Math.min(100, Math.round((playerSpend / tierSpend) * 100));
}

/**
 * Get VIP tier statistics
 */
export async function getVIPTierStats() {
  const stats = {
    bronze: { count: 0, totalSpend: 0, avgSpend: 0, retention: 0 },
    silver: { count: 0, totalSpend: 0, avgSpend: 0, retention: 0 },
    gold: { count: 0, totalSpend: 0, avgSpend: 0, retention: 0 },
    platinum: { count: 0, totalSpend: 0, avgSpend: 0, retention: 0 },
  };

  const allUsers = await db.query.users.findMany();

  for (const user of allUsers) {
    const totalSpend = user.totalSpend || 0;
    let tier = 'bronze';

    if (totalSpend >= 15000) tier = 'platinum';
    else if (totalSpend >= 5000) tier = 'gold';
    else if (totalSpend >= 1000) tier = 'silver';

    stats[tier as keyof typeof stats].count++;
    stats[tier as keyof typeof stats].totalSpend += totalSpend;
  }

  // Calculate averages
  for (const tier of Object.keys(stats)) {
    const tierStats = stats[tier as keyof typeof stats];
    if (tierStats.count > 0) {
      tierStats.avgSpend = Math.round(tierStats.totalSpend / tierStats.count);
    }
  }

  return stats;
}

/**
 * Get VIP rewards for a player
 */
export async function getPlayerVIPRewards(userId: string) {
  const tier = await getPlayerVIPTier(userId);
  if (!tier) return null;

  const tierConfig = VIP_TIER_CONFIG[tier.tier as keyof typeof VIP_TIER_CONFIG];

  return {
    tier: tier.tier,
    monthlyBonus: tierConfig.monthlyBonus,
    rewardRate: tierConfig.rewardRate,
    multiplier: tierConfig.multiplier,
    exclusiveGames: tierConfig.exclusiveGames,
    nextTierSpend: calculateNextTierSpend(tier.currentSpend),
    estimatedMonthlyRewards: Math.round(tier.currentSpend * tierConfig.rewardRate * 0.1),
  };
}

/**
 * Calculate spend needed for next tier
 */
function calculateNextTierSpend(currentSpend: number): number {
  const tiers = Object.values(VIP_TIER_CONFIG);
  for (let i = 0; i < tiers.length - 1; i++) {
    if (currentSpend >= tiers[i].minSpend && currentSpend < tiers[i + 1].minSpend) {
      return tiers[i + 1].minSpend - currentSpend;
    }
  }
  return 0;
}

/**
 * Track tier progression event
 */
export async function trackTierProgression(userId: string, previousTier: string, newTier: string) {
  const timestamp = new Date();

  // Log the tier upgrade
  console.log(`[VIP] User ${userId} upgraded from ${previousTier} to ${newTier} at ${timestamp}`);

  // Award bonus for tier upgrade
  const bonusAmount = VIP_TIER_CONFIG[newTier as keyof typeof VIP_TIER_CONFIG].monthlyBonus;

  // Update user wallet
  const userWallet = await db.query.wallets.findFirst({
    where: eq(wallets.userId, userId),
  });

  if (userWallet) {
    await db
      .update(wallets)
      .set({
        balance: userWallet.balance + bonusAmount,
        updatedAt: timestamp,
      })
      .where(eq(wallets.id, userWallet.id));
  }

  return {
    userId,
    previousTier,
    newTier,
    bonusAwarded: bonusAmount,
    timestamp,
  };
}

/**
 * Get VIP leaderboard
 */
export async function getVIPLeaderboard(limit: number = 100) {
  const topPlayers = await db.query.users.findMany({
    orderBy: [desc(users.totalSpend)],
    limit,
  });

  return topPlayers.map((user, index) => ({
    rank: index + 1,
    userId: user.id,
    username: user.username,
    totalSpend: user.totalSpend || 0,
    tier: getTierFromSpend(user.totalSpend || 0),
    joinDate: user.createdAt,
  }));
}

/**
 * Helper to get tier from spend
 */
function getTierFromSpend(spend: number): string {
  if (spend >= 15000) return 'platinum';
  if (spend >= 5000) return 'gold';
  if (spend >= 1000) return 'silver';
  return 'bronze';
}

/**
 * Get VIP analytics
 */
export async function getVIPAnalytics() {
  const stats = await getVIPTierStats();
  const leaderboard = await getVIPLeaderboard(10);

  const totalVIPPlayers = Object.values(stats).reduce((sum, s) => sum + s.count, 0);
  const totalVIPSpend = Object.values(stats).reduce((sum, s) => sum + s.totalSpend, 0);

  return {
    totalVIPPlayers,
    totalVIPSpend,
    avgVIPSpend: Math.round(totalVIPSpend / (totalVIPPlayers || 1)),
    tierDistribution: stats,
    topPlayers: leaderboard,
    timestamp: new Date(),
  };
}

/**
 * Get reward redemption history
 */
export async function getRewardRedemptionHistory(userId: string, limit: number = 50) {
  // Mock reward history
  return [
    {
      id: '1',
      userId,
      type: 'monthly_bonus',
      amount: 500,
      tier: 'gold',
      redeemedAt: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
      status: 'completed',
    },
    {
      id: '2',
      userId,
      type: 'tier_upgrade_bonus',
      amount: 500,
      tier: 'gold',
      redeemedAt: new Date(Date.now() - 14 * 24 * 60 * 60 * 1000),
      status: 'completed',
    },
    {
      id: '3',
      userId,
      type: 'referral_reward',
      amount: 100,
      tier: 'gold',
      redeemedAt: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000),
      status: 'completed',
    },
  ];
}

/**
 * Get VIP tier comparison
 */
export async function getVIPTierComparison() {
  return Object.entries(VIP_TIER_CONFIG).map(([tier, config]) => ({
    tier,
    name: config.name,
    minSpend: config.minSpend,
    maxSpend: config.maxSpend === Infinity ? 'Unlimited' : config.maxSpend,
    multiplier: config.multiplier,
    rewardRate: config.rewardRate,
    monthlyBonus: config.monthlyBonus,
    exclusiveGames: config.exclusiveGames,
    color: config.color,
  }));
}

/**
 * Get player VIP history
 */
export async function getPlayerVIPHistory(userId: string) {
  const user = await db.query.users.findFirst({
    where: eq(users.id, userId),
  });

  if (!user) return null;

  const currentTier = await getPlayerVIPTier(userId);
  const rewards = await getPlayerVIPRewards(userId);

  return {
    userId,
    username: user.username,
    currentTier: currentTier?.tier,
    totalSpend: user.totalSpend || 0,
    joinDate: user.createdAt,
    rewards,
    progressToNextTier: currentTier?.progressToNext,
  };
}
