import { protectedProcedure, publicProcedure, router } from "../_core/trpc.ts";
import { z } from "zod";
import { TournamentManager, TournamentType, TOURNAMENT_TEMPLATES } from "../tournaments.ts";

const tournamentManager = new TournamentManager();

export const tournamentRouter = router({
  // Create tournament (admin only)
  create: protectedProcedure
    .input(
      z.object({
        name: z.string(),
        gameId: z.number(),
        entryFee: z.number(),
        prizePool: z.number(),
        startTime: z.date(),
        endTime: z.date(),
        maxParticipants: z.number().optional(),
        description: z.string().optional(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      if (ctx.user.role !== "admin") {
        throw new Error("Only admins can create tournaments");
      }

      const tournament = await tournamentManager.createTournament(
        input.name,
        input.gameId,
        input.entryFee,
        input.prizePool,
        input.startTime,
        input.endTime,
        input.maxParticipants,
        input.description
      );

      return tournament;
    }),

  // Join tournament
  join: protectedProcedure
    .input(z.object({ tournamentId: z.number() }))
    .mutation(async ({ ctx, input }) => {
      // Get tournament to get entry fee
      const entryFee = 10; // Mock - should fetch from DB

      const result = await tournamentManager.joinTournament(
        input.tournamentId,
        ctx.user.id,
        entryFee
      );

      return result;
    }),

  // Get active tournaments
  getActive: publicProcedure.query(async () => {
    // Query active tournaments from database
    return [
      {
        id: 1,
        name: "Daily Spin Battle",
        gameId: 1,
        status: "active",
        entryFee: 10,
        prizePool: 1000,
        currentParticipants: 250,
        maxParticipants: 1000,
        startTime: new Date(),
        endTime: new Date(Date.now() + 24 * 60 * 60 * 1000),
      },
    ];
  }),

  // Get upcoming tournaments
  getUpcoming: publicProcedure.query(async () => {
    // Query upcoming tournaments from database
    return [];
  }),

  // Get completed tournaments
  getCompleted: publicProcedure
    .input(z.object({ limit: z.number().default(10) }))
    .query(async ({ input }) => {
      // Query completed tournaments from database
      return [];
    }),

  // Get tournament details
  getDetails: publicProcedure
    .input(z.object({ tournamentId: z.number() }))
    .query(async ({ input }) => {
      // Query tournament details from database
      return {
        id: input.tournamentId,
        name: "Daily Spin Battle",
        gameId: 1,
        status: "active",
        entryFee: 10,
        prizePool: 1000,
        currentParticipants: 250,
        maxParticipants: 1000,
        startTime: new Date(),
        endTime: new Date(),
      };
    }),

  // Get tournament leaderboard
  getLeaderboard: publicProcedure
    .input(z.object({ tournamentId: z.number(), limit: z.number().default(100) }))
    .query(async ({ input }) => {
      const leaderboard = await tournamentManager.getTournamentLeaderboard(
        input.tournamentId,
        input.limit
      );
      return leaderboard;
    }),

  // Update tournament score
  updateScore: protectedProcedure
    .input(
      z.object({
        tournamentId: z.number(),
        spinWinAmount: z.number(),
        betAmount: z.number(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      await tournamentManager.updateTournamentScore(
        input.tournamentId,
        ctx.user.id,
        input.spinWinAmount,
        input.betAmount
      );

      return { success: true };
    }),

  // Get player tournament stats
  getPlayerStats: protectedProcedure.query(async ({ ctx }) => {
    const stats = await tournamentManager.getPlayerTournamentStats(ctx.user.id);
    return stats;
  }),

  // Get player's tournament entries
  getPlayerEntries: protectedProcedure
    .input(z.object({ limit: z.number().default(20) }))
    .query(async ({ ctx, input }) => {
      // Query player's tournament entries from database
      return [
        {
          id: 1,
          tournamentId: 1,
          tournamentName: "Daily Spin Battle",
          score: 5000,
          rank: 15,
          prizeWon: 250,
          enteredAt: new Date(),
        },
      ];
    }),

  // Complete tournament (admin only)
  complete: protectedProcedure
    .input(z.object({ tournamentId: z.number() }))
    .mutation(async ({ ctx, input }) => {
      if (ctx.user.role !== "admin") {
        throw new Error("Only admins can complete tournaments");
      }

      await tournamentManager.completeTournament(input.tournamentId);
      return { success: true };
    }),

  // Get tournament templates
  getTemplates: publicProcedure.query(() => {
    return Object.entries(TOURNAMENT_TEMPLATES).map(([type, template]) => ({
      type,
      ...template,
    }));
  }),

  // Get user's tournament position
  getUserPosition: protectedProcedure
    .input(z.object({ tournamentId: z.number() }))
    .query(async ({ ctx, input }) => {
      // Query user's position in tournament leaderboard
      return {
        rank: 42,
        score: 2500,
        spins: 150,
        totalWagered: 1500,
        totalWon: 4000,
      };
    }),
});
