import { router, publicProcedure, protectedProcedure } from "../_core/trpc.ts";
import { z } from "zod";
import { TRPCError } from "@trpc/server";

/**
 * Tournaments Router
 * Manages tournament creation, registration, and leaderboards
 */

interface Tournament {
  id: string;
  name: string;
  description: string;
  startDate: Date;
  endDate: Date;
  entryFee: number;
  prizePool: number;
  maxParticipants: number;
  currentParticipants: number;
  status: "upcoming" | "active" | "completed";
  prizes: Array<{ rank: number; amount: number }>;
}

interface TournamentParticipant {
  userId: number;
  username: string;
  score: number;
  rank: number;
  prizeWon?: number;
}

// Mock tournament data
const mockTournaments: Tournament[] = [
  {
    id: "tournament_1",
    name: "March Madness Slots",
    description: "Compete with other players for a $10,000 prize pool",
    startDate: new Date("2026-03-25"),
    endDate: new Date("2026-03-31"),
    entryFee: 50,
    prizePool: 10000,
    maxParticipants: 100,
    currentParticipants: 47,
    status: "upcoming",
    prizes: [
      { rank: 1, amount: 5000 },
      { rank: 2, amount: 2500 },
      { rank: 3, amount: 1500 },
      { rank: 4, amount: 750 },
      { rank: 5, amount: 250 },
    ],
  },
  {
    id: "tournament_2",
    name: "Daily High Roller",
    description: "Fast-paced tournament with instant results",
    startDate: new Date("2026-03-24"),
    endDate: new Date("2026-03-24T23:59:59"),
    entryFee: 25,
    prizePool: 2500,
    maxParticipants: 50,
    currentParticipants: 38,
    status: "active",
    prizes: [
      { rank: 1, amount: 1000 },
      { rank: 2, amount: 750 },
      { rank: 3, amount: 500 },
      { rank: 4, amount: 250 },
    ],
  },
];

const mockParticipants: Record<string, TournamentParticipant[]> = {
  tournament_1: [
    { userId: 1, username: "Player1", score: 5500, rank: 1 },
    { userId: 2, username: "Player2", score: 4800, rank: 2 },
    { userId: 3, username: "Player3", score: 4200, rank: 3 },
  ],
  tournament_2: [
    { userId: 4, username: "HighRoller", score: 8900, rank: 1, prizeWon: 1000 },
    { userId: 5, username: "LuckyStrike", score: 7600, rank: 2, prizeWon: 750 },
    { userId: 6, username: "SpinMaster", score: 6800, rank: 3, prizeWon: 500 },
  ],
};

export const tournamentsRouter = router({
  /**
   * Get all active tournaments
   */
  getActive: publicProcedure.query(async () => {
    return mockTournaments.filter((t) => t.status === "active");
  }),

  /**
   * Get upcoming tournaments
   */
  getUpcoming: publicProcedure.query(async () => {
    return mockTournaments.filter((t) => t.status === "upcoming");
  }),

  /**
   * Get tournament details
   */
  getDetails: publicProcedure
    .input(z.object({ tournamentId: z.string() }))
    .query(async ({ input }) => {
      const tournament = mockTournaments.find((t) => t.id === input.tournamentId);
      if (!tournament) {
        throw new TRPCError({
          code: "NOT_FOUND",
          message: "Tournament not found",
        });
      }
      return tournament;
    }),

  /**
   * Get tournament leaderboard
   */
  getLeaderboard: publicProcedure
    .input(z.object({ tournamentId: z.string(), limit: z.number().default(100) }))
    .query(async ({ input }) => {
      const participants = mockParticipants[input.tournamentId] || [];
      return participants.slice(0, input.limit).sort((a, b) => a.rank - b.rank);
    }),

  /**
   * Get user's tournament participation
   */
  getUserTournaments: protectedProcedure.query(async ({ ctx }) => {
    const userTournaments = [];

    for (const tournament of mockTournaments) {
      const participants = mockParticipants[tournament.id] || [];
      const userParticipant = participants.find((p) => p.userId === ctx.user.id);

      if (userParticipant) {
        userTournaments.push({
          tournament,
          participation: userParticipant,
        });
      }
    }

    return userTournaments;
  }),

  /**
   * Register for tournament
   */
  register: protectedProcedure
    .input(z.object({ tournamentId: z.string() }))
    .mutation(async ({ ctx, input }) => {
      const tournament = mockTournaments.find((t) => t.id === input.tournamentId);
      if (!tournament) {
        throw new TRPCError({
          code: "NOT_FOUND",
          message: "Tournament not found",
        });
      }

      if (tournament.currentParticipants >= tournament.maxParticipants) {
        throw new TRPCError({
          code: "BAD_REQUEST",
          message: "Tournament is full",
        });
      }

      if (tournament.status !== "upcoming" && tournament.status !== "active") {
        throw new TRPCError({
          code: "BAD_REQUEST",
          message: "Tournament is not accepting registrations",
        });
      }

      // Check if already registered
      const participants = mockParticipants[tournament.id] || [];
      if (participants.some((p) => p.userId === ctx.user.id)) {
        throw new TRPCError({
          code: "BAD_REQUEST",
          message: "Already registered for this tournament",
        });
      }

      // Add participant
      const newParticipant: TournamentParticipant = {
        userId: ctx.user.id,
        username: ctx.user.username || `User${ctx.user.id}`,
        score: 0,
        rank: participants.length + 1,
      };

      if (!mockParticipants[tournament.id]) {
        mockParticipants[tournament.id] = [];
      }
      mockParticipants[tournament.id].push(newParticipant);

      // Increment participant count
      tournament.currentParticipants += 1;

      return {
        success: true,
        message: `Successfully registered for ${tournament.name}`,
        entryFee: tournament.entryFee,
      };
    }),

  /**
   * Submit tournament score
   */
  submitScore: protectedProcedure
    .input(z.object({ tournamentId: z.string(), score: z.number() }))
    .mutation(async ({ ctx, input }) => {
      const tournament = mockTournaments.find((t) => t.id === input.tournamentId);
      if (!tournament) {
        throw new TRPCError({
          code: "NOT_FOUND",
          message: "Tournament not found",
        });
      }

      const participants = mockParticipants[tournament.id] || [];
      const participant = participants.find((p) => p.userId === ctx.user.id);

      if (!participant) {
        throw new TRPCError({
          code: "BAD_REQUEST",
          message: "Not registered for this tournament",
        });
      }

      // Update score
      participant.score = Math.max(participant.score, input.score);

      // Recalculate ranks
      participants.sort((a, b) => b.score - a.score);
      participants.forEach((p, index) => {
        p.rank = index + 1;
      });

      return {
        success: true,
        newRank: participant.rank,
        score: participant.score,
      };
    }),

  /**
   * Get tournament prizes
   */
  getPrizes: publicProcedure
    .input(z.object({ tournamentId: z.string() }))
    .query(async ({ input }) => {
      const tournament = mockTournaments.find((t) => t.id === input.tournamentId);
      if (!tournament) {
        throw new TRPCError({
          code: "NOT_FOUND",
          message: "Tournament not found",
        });
      }

      return {
        prizePool: tournament.prizePool,
        prizes: tournament.prizes,
        totalPrizes: tournament.prizes.reduce((sum, p) => sum + p.amount, 0),
      };
    }),

  /**
   * Get completed tournaments
   */
  getCompleted: publicProcedure
    .input(z.object({ limit: z.number().default(10), offset: z.number().default(0) }))
    .query(async ({ input }) => {
      const completed = mockTournaments
        .filter((t) => t.status === "completed")
        .slice(input.offset, input.offset + input.limit);

      return completed;
    }),
});
