/**
 * Referral Rewards System
 * Manages referral tracking, commission calculation, and reward distribution
 */

import { eq, and, gte } from 'drizzle-orm';
import { getDb } from './db.ts';
import { users } from '../drizzle/schema.ts';

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

export interface ReferralTier {
  tier: CommissionTier;
  minReferrals: number;
  maxReferrals: number;
  commissionRate: number; // Percentage (e.g., 5 = 5%)
  bonusMultiplier: number;
  monthlyBonus: number;
}

export interface ReferralCode {
  code: string;
  userId: number;
  createdAt: Date;
  expiresAt?: Date;
  uses: number;
  totalCommission: number;
  active: boolean;
}

export interface ReferralReward {
  id: string;
  referrerId: number;
  referredId: number;
  amount: number;
  type: 'signup' | 'deposit' | 'wager' | 'bonus';
  status: 'pending' | 'approved' | 'paid';
  createdAt: Date;
  paidAt?: Date;
}

export interface PlayerReferralStats {
  totalReferrals: number;
  activeReferrals: number;
  totalCommission: number;
  pendingCommission: number;
  tier: CommissionTier;
  monthlyBonus: number;
  referralCode: string;
}

// Referral tier configuration
const REFERRAL_TIERS: ReferralTier[] = [
  {
    tier: 'bronze',
    minReferrals: 0,
    maxReferrals: 4,
    commissionRate: 2,
    bonusMultiplier: 1,
    monthlyBonus: 0,
  },
  {
    tier: 'silver',
    minReferrals: 5,
    maxReferrals: 9,
    commissionRate: 3,
    bonusMultiplier: 1.1,
    monthlyBonus: 50,
  },
  {
    tier: 'gold',
    minReferrals: 10,
    maxReferrals: 24,
    commissionRate: 4,
    bonusMultiplier: 1.2,
    monthlyBonus: 150,
  },
  {
    tier: 'platinum',
    minReferrals: 25,
    maxReferrals: 49,
    commissionRate: 5,
    bonusMultiplier: 1.3,
    monthlyBonus: 500,
  },
  {
    tier: 'diamond',
    minReferrals: 50,
    maxReferrals: Infinity,
    commissionRate: 7,
    bonusMultiplier: 1.5,
    monthlyBonus: 1500,
  },
];

/**
 * Generate unique referral code
 */
export function generateReferralCode(userId: number): string {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  let code = '';
  for (let i = 0; i < 8; i++) {
    code += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return `REF${code}`;
}

/**
 * Create referral code for user
 */
export async function createReferralCode(userId: number): Promise<ReferralCode> {
  const code = generateReferralCode(userId);

  const referralCode: ReferralCode = {
    code,
    userId,
    createdAt: new Date(),
    expiresAt: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000), // 1 year
    uses: 0,
    totalCommission: 0,
    active: true,
  };

  return referralCode;
}

/**
 * Get referral tier based on referral count
 */
export function getReferralTier(referralCount: number): ReferralTier {
  for (const tier of REFERRAL_TIERS) {
    if (referralCount >= tier.minReferrals && referralCount <= tier.maxReferrals) {
      return tier;
    }
  }
  return REFERRAL_TIERS[REFERRAL_TIERS.length - 1];
}

/**
 * Calculate commission for a referral
 */
export function calculateCommission(referrerReferralCount: number, amount: number, type: string): number {
  const tier = getReferralTier(referrerReferralCount);
  let commission = (amount * tier.commissionRate) / 100;

  // Apply bonus multiplier for certain types
  if (type === 'deposit' || type === 'wager') {
    commission *= tier.bonusMultiplier;
  }

  return Math.round(commission * 100) / 100;
}

/**
 * Record a referral reward
 */
export async function recordReferralReward(
  referrerId: number,
  referredId: number,
  amount: number,
  type: 'signup' | 'deposit' | 'wager' | 'bonus'
): Promise<ReferralReward> {
  const db = getDb();

  // Get referrer's current referral count
  const referrerData = await db.query.users.findFirst({
    where: eq(users.id, referrerId),
  });

  const referralCount = referrerData?.referralCount || 0;
  const commission = calculateCommission(referralCount, amount, type);

  const reward: ReferralReward = {
    id: `reward_${referrerId}_${referredId}_${Date.now()}`,
    referrerId,
    referredId,
    amount: commission,
    type,
    status: 'pending',
    createdAt: new Date(),
  };

  // In production, this would be stored in database
  // For now, returning the reward object

  return reward;
}

/**
 * Get player referral statistics
 */
export async function getPlayerReferralStats(userId: number): Promise<PlayerReferralStats> {
  const db = getDb();

  // Get user data
  const userData = await db.query.users.findFirst({
    where: eq(users.id, userId),
  });

  if (!userData) {
    throw new Error('User not found');
  }

  const referralCount = userData.referralCount || 0;
  const tier = getReferralTier(referralCount);

  // In production, would query rewards table
  const totalCommission = 0; // userData.totalReferralCommission || 0;
  const pendingCommission = 0; // userData.pendingReferralCommission || 0;

  return {
    totalReferrals: referralCount,
    activeReferrals: referralCount, // Would filter by active status
    totalCommission,
    pendingCommission,
    tier: tier.tier,
    monthlyBonus: tier.monthlyBonus,
    referralCode: userData.referralCode || '',
  };
}

/**
 * Get referral leaderboard
 */
export async function getReferralLeaderboard(limit: number = 100): Promise<any[]> {
  const db = getDb();

  // Get all users sorted by referral count
  const topReferrers = await db.query.users.findMany({
    limit,
    orderBy: (users) => users.referralCount,
  });

  return topReferrers.map((user, index) => ({
    rank: index + 1,
    userId: user.id,
    userName: user.name,
    referralCount: user.referralCount || 0,
    tier: getReferralTier(user.referralCount || 0).tier,
    totalCommission: 0, // Would come from rewards table
  }));
}

/**
 * Get referred users for a referrer
 */
export async function getReferredUsers(referrerId: number): Promise<any[]> {
  const db = getDb();

  // Get all users referred by this user
  const referredUsers = await db.query.users.findMany({
    where: eq(users.referredById, referrerId),
  });

  return referredUsers.map((user) => ({
    userId: user.id,
    userName: user.name,
    email: user.email,
    referredAt: user.createdAt,
    totalWagered: 0, // Would come from transactions
    totalWon: 0, // Would come from transactions
  }));
}

/**
 * Claim monthly referral bonus
 */
export async function claimMonthlyBonus(userId: number): Promise<number> {
  const db = getDb();

  // Get user's referral stats
  const stats = await getPlayerReferralStats(userId);
  const bonus = stats.monthlyBonus;

  // In production, would:
  // 1. Check if bonus already claimed this month
  // 2. Add bonus to user's wallet
  // 3. Record transaction

  return bonus;
}

/**
 * Get referral rewards history
 */
export async function getReferralRewardsHistory(
  userId: number,
  limit: number = 50,
  offset: number = 0
): Promise<ReferralReward[]> {
  // In production, would query rewards table
  return [];
}

/**
 * Calculate referral bonus for tier upgrade
 */
export function calculateTierUpgradeBonus(newTier: CommissionTier): number {
  const bonuses: Record<CommissionTier, number> = {
    bronze: 0,
    silver: 100,
    gold: 500,
    platinum: 2000,
    diamond: 5000,
  };

  return bonuses[newTier] || 0;
}

/**
 * Get referral tier requirements
 */
export function getReferralTierRequirements(): ReferralTier[] {
  return REFERRAL_TIERS;
}

/**
 * Validate referral code
 */
export async function validateReferralCode(code: string): Promise<{ valid: boolean; userId?: number }> {
  // In production, would query referral codes table
  // For now, basic validation
  if (!code || code.length < 8) {
    return { valid: false };
  }

  return { valid: true, userId: 0 };
}
