/**
 * Tournament Service
 * Manages tournaments with entry fees, scoring, and rewards
 */

export interface Tournament {
  id: string;
  name: string;
  description: string;
  startDate: string;
  endDate: string;
  entryFee: number; // in GC
  maxPlayers: number;
  currentPlayers: number;
  prizePool: number;
  status: "upcoming" | "active" | "completed";
  gameType: string;
  scoringType: "highest_score" | "most_wins" | "fastest_time";
  rewards: {
    position: number;
    percentage: number; // percentage of prize pool
  }[];
}

export interface TournamentEntry {
  tournamentId: string;
  userId: number;
  userName: string;
  entryTime: string;
  score: number;
  wins: number;
  finalPosition: number;
  prizeWon: number;
}

// In-memory tournament storage
const tournaments: Map<string, Tournament> = new Map();
const tournamentEntries: Map<string, TournamentEntry[]> = new Map();

/**
 * Create a new tournament
 */
export function createTournament(
  name: string,
  description: string,
  startDate: string,
  endDate: string,
  entryFee: number,
  maxPlayers: number,
  gameType: string,
  scoringType: "highest_score" | "most_wins" | "fastest_time"
): Tournament {
  const id = `tournament_${Date.now()}`;

  const tournament: Tournament = {
    id,
    name,
    description,
    startDate,
    endDate,
    entryFee,
    maxPlayers,
    currentPlayers: 0,
    prizePool: 0,
    status: "upcoming",
    gameType,
    scoringType,
    rewards: [
      { position: 1, percentage: 40 },
      { position: 2, percentage: 25 },
      { position: 3, percentage: 15 },
      { position: 4, percentage: 10 },
      { position: 5, percentage: 10 },
    ],
  };

  tournaments.set(id, tournament);
  tournamentEntries.set(id, []);

  console.log(`[TournamentService] Tournament created: ${id}`);
  return tournament;
}

/**
 * Get tournament by ID
 */
export function getTournament(tournamentId: string): Tournament | undefined {
  return tournaments.get(tournamentId);
}

/**
 * Get all tournaments
 */
export function getAllTournaments(): Tournament[] {
  return Array.from(tournaments.values());
}

/**
 * Get active tournaments
 */
export function getActiveTournaments(): Tournament[] {
  return Array.from(tournaments.values()).filter((t) => t.status === "active");
}

/**
 * Get upcoming tournaments
 */
export function getUpcomingTournaments(): Tournament[] {
  return Array.from(tournaments.values()).filter((t) => t.status === "upcoming");
}

/**
 * Enter tournament
 */
export function enterTournament(
  tournamentId: string,
  userId: number,
  userName: string,
  entryFee: number
): { success: boolean; message: string; entry?: TournamentEntry } {
  const tournament = tournaments.get(tournamentId);

  if (!tournament) {
    return { success: false, message: "Tournament not found" };
  }

  if (tournament.currentPlayers >= tournament.maxPlayers) {
    return { success: false, message: "Tournament is full" };
  }

  if (tournament.status !== "active" && tournament.status !== "upcoming") {
    return { success: false, message: "Tournament is not accepting entries" };
  }

  const entries = tournamentEntries.get(tournamentId) || [];
  const alreadyEntered = entries.some((e) => e.userId === userId);

  if (alreadyEntered) {
    return { success: false, message: "Already entered this tournament" };
  }

  const entry: TournamentEntry = {
    tournamentId,
    userId,
    userName,
    entryTime: new Date().toISOString(),
    score: 0,
    wins: 0,
    finalPosition: 0,
    prizeWon: 0,
  };

  entries.push(entry);
  tournamentEntries.set(tournamentId, entries);

  tournament.currentPlayers++;
  tournament.prizePool += entryFee;

  return { success: true, message: "Successfully entered tournament", entry };
}

/**
 * Update player score in tournament
 */
export function updateTournamentScore(
  tournamentId: string,
  userId: number,
  score: number,
  wins: number
): boolean {
  const entries = tournamentEntries.get(tournamentId);

  if (!entries) {
    return false;
  }

  const entry = entries.find((e) => e.userId === userId);

  if (!entry) {
    return false;
  }

  entry.score = Math.max(entry.score, score);
  entry.wins = Math.max(entry.wins, wins);

  return true;
}

/**
 * Finalize tournament and calculate winners
 */
export function finalizeTournament(tournamentId: string): {
  success: boolean;
  winners?: TournamentEntry[];
} {
  const tournament = tournaments.get(tournamentId);
  const entries = tournamentEntries.get(tournamentId) || [];

  if (!tournament) {
    return { success: false };
  }

  // Sort entries based on scoring type
  if (tournament.scoringType === "highest_score") {
    entries.sort((a, b) => b.score - a.score);
  } else if (tournament.scoringType === "most_wins") {
    entries.sort((a, b) => b.wins - a.wins);
  }

  // Calculate prizes
  entries.forEach((entry, index) => {
    entry.finalPosition = index + 1;

    const reward = tournament.rewards.find((r) => r.position === entry.finalPosition);
    if (reward) {
      entry.prizeWon = (tournament.prizePool * reward.percentage) / 100;
    }
  });

  tournament.status = "completed";

  return { success: true, winners: entries.slice(0, 5) };
}

/**
 * Get tournament leaderboard
 */
export function getTournamentLeaderboard(tournamentId: string): TournamentEntry[] {
  const entries = tournamentEntries.get(tournamentId) || [];
  return entries.sort((a, b) => {
    if (a.finalPosition === 0 && b.finalPosition === 0) {
      return b.score - a.score;
    }
    return a.finalPosition - b.finalPosition;
  });
}

/**
 * Get player tournament entries
 */
export function getPlayerTournamentEntries(userId: number): TournamentEntry[] {
  const allEntries: TournamentEntry[] = [];

  tournamentEntries.forEach((entries) => {
    const playerEntry = entries.find((e) => e.userId === userId);
    if (playerEntry) {
      allEntries.push(playerEntry);
    }
  });

  return allEntries;
}

/**
 * Get tournament statistics
 */
export function getTournamentStats(tournamentId: string): {
  totalEntries: number;
  totalPrizePool: number;
  averageScore: number;
  topScore: number;
} {
  const entries = tournamentEntries.get(tournamentId) || [];
  const tournament = tournaments.get(tournamentId);

  if (entries.length === 0) {
    return {
      totalEntries: 0,
      totalPrizePool: tournament?.prizePool || 0,
      averageScore: 0,
      topScore: 0,
    };
  }

  const scores = entries.map((e) => e.score);
  const averageScore = scores.reduce((a, b) => a + b, 0) / scores.length;
  const topScore = Math.max(...scores);

  return {
    totalEntries: entries.length,
    totalPrizePool: tournament?.prizePool || 0,
    averageScore,
    topScore,
  };
}

/**
 * Cancel tournament
 */
export function cancelTournament(tournamentId: string): boolean {
  const tournament = tournaments.get(tournamentId);

  if (!tournament) {
    return false;
  }

  tournament.status = "completed";
  console.log(`[TournamentService] Tournament cancelled: ${tournamentId}`);

  return true;
}
