/**
 * Seasonal Bonus Multiplier Service
 * Applies seasonal event multipliers to game spins
 */

import { getDb } from "../db.ts";

const SEASONAL_EVENTS = {
  halloween_2026: { multiplier: 2.0, startDate: new Date('2026-10-01'), endDate: new Date('2026-10-31') },
  christmas_2026: { multiplier: 3.0, startDate: new Date('2026-12-01'), endDate: new Date('2026-12-31') },
  new_year_2027: { multiplier: 2.5, startDate: new Date('2027-01-01'), endDate: new Date('2027-01-31') },
  summer_2026: { multiplier: 1.5, startDate: new Date('2026-06-21'), endDate: new Date('2026-09-22') },
};

/**
 * Get active seasonal event for current date
 */
export function getActiveSeasonalEvent(): { eventId: string; multiplier: number } | null {
  const now = new Date();

  for (const [eventId, event] of Object.entries(SEASONAL_EVENTS)) {
    if (now >= event.startDate && now <= event.endDate) {
      return { eventId, multiplier: event.multiplier };
    }
  }

  return null;
}

/**
 * Calculate win amount with seasonal multiplier
 */
export function calculateSeasonalWinAmount(baseWinAmount: number, userId: number): number {
  const activeEvent = getActiveSeasonalEvent();
  if (!activeEvent) {
    return baseWinAmount;
  }

  // Apply multiplier
  return baseWinAmount * activeEvent.multiplier;
}

/**
 * Get multiplier for specific event
 */
export function getEventMultiplier(eventId: string): number {
  const event = SEASONAL_EVENTS[eventId as keyof typeof SEASONAL_EVENTS];
  return event ? event.multiplier : 1.0;
}

/**
 * Check if event is currently active
 */
export function isEventActive(eventId: string): boolean {
  const event = SEASONAL_EVENTS[eventId as keyof typeof SEASONAL_EVENTS];
  if (!event) return false;

  const now = new Date();
  return now >= event.startDate && now <= event.endDate;
}

/**
 * Get all active events with multipliers
 */
export function getActiveEvents(): Array<{ eventId: string; multiplier: number }> {
  const now = new Date();
  const active: Array<{ eventId: string; multiplier: number }> = [];

  for (const [eventId, event] of Object.entries(SEASONAL_EVENTS)) {
    if (now >= event.startDate && now <= event.endDate) {
      active.push({ eventId, multiplier: event.multiplier });
    }
  }

  return active;
}

/**
 * Get multiplier breakdown for display
 */
export function getMultiplierBreakdown(baseWinAmount: number): {
  baseAmount: number;
  multiplier: number;
  finalAmount: number;
  eventId: string | null;
} {
  const activeEvent = getActiveSeasonalEvent();

  if (!activeEvent) {
    return {
      baseAmount: baseWinAmount,
      multiplier: 1.0,
      finalAmount: baseWinAmount,
      eventId: null,
    };
  }

  return {
    baseAmount: baseWinAmount,
    multiplier: activeEvent.multiplier,
    finalAmount: baseWinAmount * activeEvent.multiplier,
    eventId: activeEvent.eventId,
  };
}

/**
 * Format multiplier for display (e.g., "2x Bonus")
 */
export function formatMultiplier(multiplier: number): string {
  if (multiplier === 1.0) return 'No Bonus';
  return `${multiplier}x Bonus`;
}

/**
 * Get event name from ID
 */
export function getEventName(eventId: string): string {
  const names: Record<string, string> = {
    halloween_2026: 'Spooky Spin Spectacular',
    christmas_2026: 'Festive Fortune',
    new_year_2027: 'New Year New Luck',
    summer_2026: 'Summer Sizzle',
  };
  return names[eventId] || 'Unknown Event';
}

/**
 * Get event theme
 */
export function getEventTheme(eventId: string): string {
  const themes: Record<string, string> = {
    halloween_2026: 'halloween',
    christmas_2026: 'christmas',
    new_year_2027: 'new_year',
    summer_2026: 'summer',
  };
  return themes[eventId] || 'default';
}

/**
 * Calculate total bonus earned from multiplier
 */
export function calculateBonusEarned(baseWinAmount: number, eventId: string): number {
  const multiplier = getEventMultiplier(eventId);
  return baseWinAmount * (multiplier - 1);
}

/**
 * Log seasonal bonus to transaction history
 */
export async function logSeasonalBonus(
  userId: number,
  baseWinAmount: number,
  bonusAmount: number,
  eventId: string,
  gameId: number
): Promise<boolean> {
  try {
    const db = await getDb();
    if (!db) return false;

    await db.raw(
      `INSERT INTO transactions (userId, type, currency, amount, balanceBefore, balanceAfter, referenceId, referenceType, description, metadata, createdAt)
       VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())`,
      [
        userId,
        'promo_credit',
        'SC',
        bonusAmount,
        0, // Will be updated by game engine
        0, // Will be updated by game engine
        eventId,
        'seasonal_bonus',
        `Seasonal event bonus: ${getEventName(eventId)}`,
        JSON.stringify({
          eventId,
          gameId,
          baseWinAmount,
          bonusAmount,
          multiplier: getEventMultiplier(eventId),
        }),
      ]
    );

    return true;
  } catch (error) {
    console.error('Error logging seasonal bonus:', error);
    return false;
  }
}
