/**
 * Seasonal Badge Events Service
 * Manages limited-time badge challenges and seasonal events
 */

import { db } from './db.ts';

export interface SeasonalEvent {
  id: string;
  name: string;
  description: string;
  badgeId: string;
  season: 'spring' | 'summer' | 'fall' | 'winter' | 'holiday' | 'special';
  startDate: Date;
  endDate: Date;
  challenge: {
    title: string;
    description: string;
    target: number;
    metric: 'games_played' | 'winnings' | 'shares' | 'referrals' | 'playtime';
  };
  rewards: {
    badgeReward: number;
    scReward: number;
    multiplier: number;
  };
  participants: number;
  completions: number;
  isActive: boolean;
}

export interface UserEventProgress {
  eventId: string;
  userId: string;
  progress: number;
  target: number;
  completed: boolean;
  completedAt?: Date;
  reward: number;
}

// Seasonal events
const SEASONAL_EVENTS: Record<string, SeasonalEvent> = {
  spring_bloom: {
    id: 'spring_bloom',
    name: 'Spring Bloom',
    description: 'Celebrate spring with special challenges',
    badgeId: 'spring_bloom',
    season: 'spring',
    startDate: new Date('2026-03-21'),
    endDate: new Date('2026-06-20'),
    challenge: {
      title: 'Spring Spinner',
      description: 'Play 500 games during spring',
      target: 500,
      metric: 'games_played',
    },
    rewards: {
      badgeReward: 150,
      scReward: 200,
      multiplier: 1.5,
    },
    participants: 1250,
    completions: 450,
    isActive: true,
  },
  summer_heat: {
    id: 'summer_heat',
    name: 'Summer Heat',
    description: 'Beat the summer heat with hot wins',
    badgeId: 'summer_heat',
    season: 'summer',
    startDate: new Date('2026-06-21'),
    endDate: new Date('2026-09-22'),
    challenge: {
      title: 'Summer Jackpot',
      description: 'Win 5000 SC during summer',
      target: 5000,
      metric: 'winnings',
    },
    rewards: {
      badgeReward: 200,
      scReward: 300,
      multiplier: 2.0,
    },
    participants: 1800,
    completions: 620,
    isActive: true,
  },
  fall_festival: {
    id: 'fall_festival',
    name: 'Fall Festival',
    description: 'Join the fall festival celebration',
    badgeId: 'fall_festival',
    season: 'fall',
    startDate: new Date('2026-09-23'),
    endDate: new Date('2026-12-20'),
    challenge: {
      title: 'Festival Sharer',
      description: 'Share your profile 20 times',
      target: 20,
      metric: 'shares',
    },
    rewards: {
      badgeReward: 175,
      scReward: 250,
      multiplier: 1.75,
    },
    participants: 950,
    completions: 380,
    isActive: true,
  },
  winter_wonderland: {
    id: 'winter_wonderland',
    name: 'Winter Wonderland',
    description: 'Experience winter magic and rewards',
    badgeId: 'winter_wonderland',
    season: 'winter',
    startDate: new Date('2026-12-21'),
    endDate: new Date('2027-03-20'),
    challenge: {
      title: 'Winter Warrior',
      description: 'Play 1000 games during winter',
      target: 1000,
      metric: 'games_played',
    },
    rewards: {
      badgeReward: 250,
      scReward: 400,
      multiplier: 2.5,
    },
    participants: 2100,
    completions: 850,
    isActive: false,
  },
  holiday_special: {
    id: 'holiday_special',
    name: 'Holiday Special',
    description: 'Limited-time holiday celebration',
    badgeId: 'holiday_special',
    season: 'holiday',
    startDate: new Date('2026-12-01'),
    endDate: new Date('2026-12-31'),
    challenge: {
      title: 'Holiday Hero',
      description: 'Refer 5 friends during holidays',
      target: 5,
      metric: 'referrals',
    },
    rewards: {
      badgeReward: 300,
      scReward: 500,
      multiplier: 3.0,
    },
    participants: 3200,
    completions: 1450,
    isActive: false,
  },
};

/**
 * Get all seasonal events
 */
export async function getAllSeasonalEvents(): Promise<SeasonalEvent[]> {
  try {
    return Object.values(SEASONAL_EVENTS);
  } catch (error) {
    console.error('[SeasonalEvents] Error fetching all events:', error);
    return [];
  }
}

/**
 * Get active seasonal events
 */
export async function getActiveSeasonalEvents(): Promise<SeasonalEvent[]> {
  try {
    const now = new Date();
    return Object.values(SEASONAL_EVENTS).filter(
      (event) => event.startDate <= now && event.endDate >= now && event.isActive
    );
  } catch (error) {
    console.error('[SeasonalEvents] Error fetching active events:', error);
    return [];
  }
}

/**
 * Get seasonal event by ID
 */
export async function getSeasonalEvent(eventId: string): Promise<SeasonalEvent | null> {
  try {
    return SEASONAL_EVENTS[eventId] || null;
  } catch (error) {
    console.error('[SeasonalEvents] Error fetching event:', error);
    return null;
  }
}

/**
 * Get events by season
 */
export async function getEventsBySeason(season: string): Promise<SeasonalEvent[]> {
  try {
    return Object.values(SEASONAL_EVENTS).filter((event) => event.season === season);
  } catch (error) {
    console.error('[SeasonalEvents] Error fetching events by season:', error);
    return [];
  }
}

/**
 * Get user event progress
 */
export async function getUserEventProgress(
  userId: string,
  eventId: string
): Promise<UserEventProgress | null> {
  try {
    const event = SEASONAL_EVENTS[eventId];
    if (!event) return null;

    // Mock progress data
    const progress: UserEventProgress = {
      eventId,
      userId,
      progress: Math.floor(Math.random() * event.challenge.target),
      target: event.challenge.target,
      completed: false,
      reward: 0,
    };

    console.log(`[SeasonalEvents] Retrieved progress for user ${userId} in event ${eventId}`);
    return progress;
  } catch (error) {
    console.error('[SeasonalEvents] Error getting user event progress:', error);
    return null;
  }
}

/**
 * Update user event progress
 */
export async function updateUserEventProgress(
  userId: string,
  eventId: string,
  progressDelta: number
): Promise<UserEventProgress | null> {
  try {
    const event = SEASONAL_EVENTS[eventId];
    if (!event) return null;

    const currentProgress = await getUserEventProgress(userId, eventId);
    if (!currentProgress) return null;

    const newProgress = Math.min(currentProgress.progress + progressDelta, event.challenge.target);
    const completed = newProgress >= event.challenge.target;

    const updatedProgress: UserEventProgress = {
      ...currentProgress,
      progress: newProgress,
      completed,
      completedAt: completed ? new Date() : undefined,
      reward: completed ? event.rewards.scReward : 0,
    };

    console.log(`[SeasonalEvents] Updated progress for user ${userId} in event ${eventId}`);
    return updatedProgress;
  } catch (error) {
    console.error('[SeasonalEvents] Error updating user event progress:', error);
    return null;
  }
}

/**
 * Get event leaderboard
 */
export async function getEventLeaderboard(eventId: string, limit: number = 100): Promise<any[]> {
  try {
    const event = SEASONAL_EVENTS[eventId];
    if (!event) return [];

    // Mock leaderboard data
    const leaderboard = Array.from({ length: Math.min(limit, 50) }, (_, i) => ({
      rank: i + 1,
      userId: `user-${i + 1}`,
      username: `Player${i + 1}`,
      progress: Math.max(0, event.challenge.target - Math.random() * 200),
      completed: i < 20,
      completedAt: i < 20 ? new Date(Date.now() - Math.random() * 7 * 24 * 60 * 60 * 1000) : null,
      reward: i < 20 ? event.rewards.scReward : 0,
    }));

    console.log(`[SeasonalEvents] Retrieved leaderboard for event ${eventId}`);
    return leaderboard;
  } catch (error) {
    console.error('[SeasonalEvents] Error getting event leaderboard:', error);
    return [];
  }
}

/**
 * Get user's event completions
 */
export async function getUserEventCompletions(userId: string): Promise<string[]> {
  try {
    // Mock data - in production, query from database
    const completions: string[] = [];

    for (const [eventId, event] of Object.entries(SEASONAL_EVENTS)) {
      if (Math.random() > 0.5) {
        completions.push(eventId);
      }
    }

    console.log(`[SeasonalEvents] Retrieved ${completions.length} event completions for user ${userId}`);
    return completions;
  } catch (error) {
    console.error('[SeasonalEvents] Error getting user event completions:', error);
    return [];
  }
}

/**
 * Get upcoming events
 */
export async function getUpcomingEvents(): Promise<SeasonalEvent[]> {
  try {
    const now = new Date();
    return Object.values(SEASONAL_EVENTS)
      .filter((event) => event.startDate > now)
      .sort((a, b) => a.startDate.getTime() - b.startDate.getTime())
      .slice(0, 5);
  } catch (error) {
    console.error('[SeasonalEvents] Error fetching upcoming events:', error);
    return [];
  }
}

/**
 * Calculate event completion percentage
 */
export function calculateEventCompletion(event: SeasonalEvent): number {
  if (event.participants === 0) return 0;
  return Math.round((event.completions / event.participants) * 100);
}

/**
 * Get event time remaining
 */
export function getEventTimeRemaining(event: SeasonalEvent): {
  days: number;
  hours: number;
  minutes: number;
  isEnded: boolean;
} {
  const now = new Date();
  const endTime = event.endDate.getTime();
  const currentTime = now.getTime();
  const timeRemaining = endTime - currentTime;

  if (timeRemaining <= 0) {
    return { days: 0, hours: 0, minutes: 0, isEnded: true };
  }

  const days = Math.floor(timeRemaining / (1000 * 60 * 60 * 24));
  const hours = Math.floor((timeRemaining % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
  const minutes = Math.floor((timeRemaining % (1000 * 60 * 60)) / (1000 * 60));

  return { days, hours, minutes, isEnded: false };
}
