import { getDb, creditWallet, writeAuditLog } from './db.ts';
import { eq } from 'drizzle-orm';

export type VIPTier = 'bronze' | 'silver' | 'gold' | 'platinum' | 'diamond';

export interface VIPTierInfo {
  tier: VIPTier;
  level: number;
  minWagered: number;
  maxWagered: number;
  betMultiplier: number;
  bonusMultiplier: number;
  tournamentFeeDiscount: number; // percentage
  dailyBonusAmount: number;
  weeklyBonusAmount: number;
  monthlyBonusAmount: number;
  exclusiveGames: boolean;
  prioritySupport: boolean;
  personalAccountManager: boolean;
  customBadge: string;
  color: string;
}

export interface PlayerVIPStatus {
  playerId: number;
  currentTier: VIPTier;
  totalWagered: number;
  currentMonthWagered: number;
  points: number;
  lastBonusClaimedAt?: Date;
  tierUpgradedAt?: Date;
  tierDowngradedAt?: Date;
}

/**
 * VIP Tier Configuration
 */
export const VIP_TIERS: Record<VIPTier, VIPTierInfo> = {
  bronze: {
    tier: 'bronze',
    level: 1,
    minWagered: 0,
    maxWagered: 10000,
    betMultiplier: 1.0,
    bonusMultiplier: 1.0,
    tournamentFeeDiscount: 0,
    dailyBonusAmount: 0,
    weeklyBonusAmount: 0,
    monthlyBonusAmount: 0,
    exclusiveGames: false,
    prioritySupport: false,
    personalAccountManager: false,
    customBadge: '🥉',
    color: '#CD7F32',
  },
  silver: {
    tier: 'silver',
    level: 2,
    minWagered: 10000,
    maxWagered: 50000,
    betMultiplier: 1.05,
    bonusMultiplier: 1.1,
    tournamentFeeDiscount: 5,
    dailyBonusAmount: 10,
    weeklyBonusAmount: 50,
    monthlyBonusAmount: 200,
    exclusiveGames: false,
    prioritySupport: true,
    personalAccountManager: false,
    customBadge: '🥈',
    color: '#C0C0C0',
  },
  gold: {
    tier: 'gold',
    level: 3,
    minWagered: 50000,
    maxWagered: 250000,
    betMultiplier: 1.1,
    bonusMultiplier: 1.25,
    tournamentFeeDiscount: 10,
    dailyBonusAmount: 25,
    weeklyBonusAmount: 150,
    monthlyBonusAmount: 600,
    exclusiveGames: true,
    prioritySupport: true,
    personalAccountManager: false,
    customBadge: '🥇',
    color: '#FFD700',
  },
  platinum: {
    tier: 'platinum',
    level: 4,
    minWagered: 250000,
    maxWagered: 1000000,
    betMultiplier: 1.15,
    bonusMultiplier: 1.5,
    tournamentFeeDiscount: 15,
    dailyBonusAmount: 50,
    weeklyBonusAmount: 350,
    monthlyBonusAmount: 1500,
    exclusiveGames: true,
    prioritySupport: true,
    personalAccountManager: true,
    customBadge: '💎',
    color: '#E5E4E2',
  },
  diamond: {
    tier: 'diamond',
    level: 5,
    minWagered: 1000000,
    maxWagered: Infinity,
    betMultiplier: 1.25,
    bonusMultiplier: 2.0,
    tournamentFeeDiscount: 25,
    dailyBonusAmount: 100,
    weeklyBonusAmount: 750,
    monthlyBonusAmount: 3000,
    exclusiveGames: true,
    prioritySupport: true,
    personalAccountManager: true,
    customBadge: '👑',
    color: '#00D9FF',
  },
};

/**
 * VIP Tier Manager
 */
export class VIPTierManager {
  private playerStatus: Map<number, PlayerVIPStatus> = new Map();

  /**
   * Initialize player VIP status
   */
  async initializePlayer(playerId: number): Promise<PlayerVIPStatus> {
    const status: PlayerVIPStatus = {
      playerId,
      currentTier: 'bronze',
      totalWagered: 0,
      currentMonthWagered: 0,
      points: 0,
    };

    this.playerStatus.set(playerId, status);
    return status;
  }

  /**
   * Get player VIP status
   */
  async getPlayerStatus(playerId: number): Promise<PlayerVIPStatus> {
    let status = this.playerStatus.get(playerId);
    if (!status) {
      status = await this.initializePlayer(playerId);
    }
    return status;
  }

  /**
   * Add wager to player's total
   */
  async addWager(playerId: number, amount: number): Promise<void> {
    const status = await this.getPlayerStatus(playerId);
    status.totalWagered += amount;
    status.currentMonthWagered += amount;
    status.points += Math.floor(amount / 100); // 1 point per 100 wagered

    // Check for tier upgrade
    await this.checkTierUpgrade(playerId);
  }

  /**
   * Check if player should be upgraded to next tier
   */
  private async checkTierUpgrade(playerId: number): Promise<void> {
    const status = await this.getPlayerStatus(playerId);
    const currentTierInfo = VIP_TIERS[status.currentTier];

    // Find the highest tier the player qualifies for
    let newTier = status.currentTier;
    for (const [tier, tierInfo] of Object.entries(VIP_TIERS)) {
      if (status.totalWagered >= tierInfo.minWagered) {
        newTier = tier as VIPTier;
      }
    }

    if (newTier !== status.currentTier) {
      status.currentTier = newTier;
      status.tierUpgradedAt = new Date();

      // Log tier upgrade
      await writeAuditLog({
        actorId: playerId,
        actorRole: 'user',
        action: 'vip_tier_upgraded',
        category: 'game',
        details: {
          previousTier: status.currentTier,
          newTier,
          totalWagered: status.totalWagered,
        },
      });

      // Award tier upgrade bonus
      const tierInfo = VIP_TIERS[newTier];
      const bonusAmount = 100 * (tierInfo.level - 1); // 0 for bronze, 100 for silver, etc.

      if (bonusAmount > 0) {
        await creditWallet(
          playerId,
          'SC',
          bonusAmount,
          'vip_tier_upgrade_bonus',
          `VIP Tier Upgrade to ${newTier}`,
          String(playerId)
        );
      }
    }
  }

  /**
   * Claim daily bonus
   */
  async claimDailyBonus(playerId: number): Promise<{ success: boolean; amount: number }> {
    const status = await this.getPlayerStatus(playerId);
    const tierInfo = VIP_TIERS[status.currentTier];

    if (tierInfo.dailyBonusAmount === 0) {
      return { success: false, amount: 0 };
    }

    // Check if already claimed today
    if (status.lastBonusClaimedAt) {
      const lastClaimDate = new Date(status.lastBonusClaimedAt);
      const today = new Date();

      if (
        lastClaimDate.getDate() === today.getDate() &&
        lastClaimDate.getMonth() === today.getMonth() &&
        lastClaimDate.getFullYear() === today.getFullYear()
      ) {
        return { success: false, amount: 0 };
      }
    }

    // Credit bonus
    await creditWallet(
      playerId,
      'SC',
      tierInfo.dailyBonusAmount,
      'vip_daily_bonus',
      `Daily VIP Bonus (${status.currentTier})`,
      String(playerId)
    );

    status.lastBonusClaimedAt = new Date();

    return { success: true, amount: tierInfo.dailyBonusAmount };
  }

  /**
   * Claim weekly bonus
   */
  async claimWeeklyBonus(playerId: number): Promise<{ success: boolean; amount: number }> {
    const status = await this.getPlayerStatus(playerId);
    const tierInfo = VIP_TIERS[status.currentTier];

    if (tierInfo.weeklyBonusAmount === 0) {
      return { success: false, amount: 0 };
    }

    // Credit bonus
    await creditWallet(
      playerId,
      'SC',
      tierInfo.weeklyBonusAmount,
      'vip_weekly_bonus',
      `Weekly VIP Bonus (${status.currentTier})`,
      String(playerId)
    );

    return { success: true, amount: tierInfo.weeklyBonusAmount };
  }

  /**
   * Claim monthly bonus
   */
  async claimMonthlyBonus(playerId: number): Promise<{ success: boolean; amount: number }> {
    const status = await this.getPlayerStatus(playerId);
    const tierInfo = VIP_TIERS[status.currentTier];

    if (tierInfo.monthlyBonusAmount === 0) {
      return { success: false, amount: 0 };
    }

    // Credit bonus
    await creditWallet(
      playerId,
      'SC',
      tierInfo.monthlyBonusAmount,
      'vip_monthly_bonus',
      `Monthly VIP Bonus (${status.currentTier})`,
      String(playerId)
    );

    return { success: true, amount: tierInfo.monthlyBonusAmount };
  }

  /**
   * Get tier progression info
   */
  async getTierProgression(playerId: number): Promise<{
    currentTier: VIPTier;
    currentTierInfo: VIPTierInfo;
    nextTier?: VIPTier;
    nextTierInfo?: VIPTierInfo;
    progressToNextTier: number; // percentage
    wagerUntilNextTier: number;
  }> {
    const status = await this.getPlayerStatus(playerId);
    const currentTierInfo = VIP_TIERS[status.currentTier];

    // Find next tier
    const tiers: VIPTier[] = ['bronze', 'silver', 'gold', 'platinum', 'diamond'];
    const currentTierIndex = tiers.indexOf(status.currentTier);
    const nextTier = currentTierIndex < tiers.length - 1 ? tiers[currentTierIndex + 1] : undefined;
    const nextTierInfo = nextTier ? VIP_TIERS[nextTier] : undefined;

    let progressToNextTier = 100;
    let wagerUntilNextTier = 0;

    if (nextTierInfo) {
      const wagerRange = nextTierInfo.minWagered - currentTierInfo.minWagered;
      const wagerInRange = status.totalWagered - currentTierInfo.minWagered;
      progressToNextTier = Math.min((wagerInRange / wagerRange) * 100, 100);
      wagerUntilNextTier = Math.max(nextTierInfo.minWagered - status.totalWagered, 0);
    }

    return {
      currentTier: status.currentTier,
      currentTierInfo,
      nextTier,
      nextTierInfo,
      progressToNextTier,
      wagerUntilNextTier,
    };
  }

  /**
   * Get VIP benefits for tier
   */
  getTierBenefits(tier: VIPTier): VIPTierInfo {
    return VIP_TIERS[tier];
  }

  /**
   * Get tournament fee discount
   */
  async getTournamentFeeDiscount(playerId: number): Promise<number> {
    const status = await this.getPlayerStatus(playerId);
    const tierInfo = VIP_TIERS[status.currentTier];
    return tierInfo.tournamentFeeDiscount;
  }

  /**
   * Get bet multiplier
   */
  async getBetMultiplier(playerId: number): Promise<number> {
    const status = await this.getPlayerStatus(playerId);
    const tierInfo = VIP_TIERS[status.currentTier];
    return tierInfo.betMultiplier;
  }

  /**
   * Get bonus multiplier
   */
  async getBonusMultiplier(playerId: number): Promise<number> {
    const status = await this.getPlayerStatus(playerId);
    const tierInfo = VIP_TIERS[status.currentTier];
    return tierInfo.bonusMultiplier;
  }

  /**
   * Reset monthly wager count
   */
  async resetMonthlyWager(playerId: number): Promise<void> {
    const status = await this.getPlayerStatus(playerId);
    status.currentMonthWagered = 0;
  }

  /**
   * Get all tier info
   */
  getAllTiers(): VIPTierInfo[] {
    return Object.values(VIP_TIERS);
  }
}

export const vipTierManager = new VIPTierManager();
