/**
 * Leaderboards tRPC Router
 * Exposes leaderboard data and operations
 */

import { router, protectedProcedure } from '../_core/trpc.ts';
import { z } from 'zod';
import { GameLeaderboards } from '../gameLeaderboards.ts';

export const leaderboardsRouter = router({
  /**
   * Get game-specific leaderboard
   */
  getGameLeaderboard: protectedProcedure
    .input(
      z.object({
        gameId: z.string(),
        period: z.enum(['daily', 'weekly', 'monthly', 'alltime']).default('weekly'),
        limit: z.number().min(10).max(500).default(100),
      })
    )
    .query(async ({ input }) => {
      return await GameLeaderboards.getGameLeaderboard(input.gameId, input.period, input.limit);
    }),

  /**
   * Get global leaderboard
   */
  getGlobalLeaderboard: protectedProcedure
    .input(
      z.object({
        period: z.enum(['daily', 'weekly', 'monthly', 'alltime']).default('weekly'),
        limit: z.number().min(10).max(500).default(100),
      })
    )
    .query(async ({ input }) => {
      return await GameLeaderboards.getGlobalLeaderboard(input.period, input.limit);
    }),

  /**
   * Get player rank in specific game
   */
  getPlayerGameRank: protectedProcedure
    .input(
      z.object({
        gameId: z.string(),
        period: z.enum(['daily', 'weekly', 'monthly', 'alltime']).default('weekly'),
      })
    )
    .query(async ({ input, ctx }) => {
      const rank = await GameLeaderboards.getPlayerGameRank(ctx.user.id.toString(), input.gameId, input.period);
      return { rank, userId: ctx.user.id };
    }),

  /**
   * Get player global rank
   */
  getPlayerGlobalRank: protectedProcedure
    .input(
      z.object({
        period: z.enum(['daily', 'weekly', 'monthly', 'alltime']).default('weekly'),
      })
    )
    .query(async ({ input, ctx }) => {
      const rank = await GameLeaderboards.getPlayerGlobalRank(ctx.user.id.toString(), input.period);
      return { rank, userId: ctx.user.id };
    }),

  /**
   * Get top winners
   */
  getTopWinners: protectedProcedure
    .input(
      z.object({
        period: z.enum(['daily', 'weekly', 'monthly', 'alltime']).default('weekly'),
        limit: z.number().min(10).max(500).default(50),
      })
    )
    .query(async ({ input }) => {
      return await GameLeaderboards.getTopWinners(input.period, input.limit);
    }),

  /**
   * Get top spinners
   */
  getTopSpinners: protectedProcedure
    .input(
      z.object({
        period: z.enum(['daily', 'weekly', 'monthly', 'alltime']).default('weekly'),
        limit: z.number().min(10).max(500).default(50),
      })
    )
    .query(async ({ input }) => {
      return await GameLeaderboards.getTopSpinners(input.period, input.limit);
    }),

  /**
   * Get top wagerers
   */
  getTopWagerers: protectedProcedure
    .input(
      z.object({
        period: z.enum(['daily', 'weekly', 'monthly', 'alltime']).default('weekly'),
        limit: z.number().min(10).max(500).default(50),
      })
    )
    .query(async ({ input }) => {
      return await GameLeaderboards.getTopWagerers(input.period, input.limit);
    }),

  /**
   * Get trending players
   */
  getTrendingPlayers: protectedProcedure
    .input(
      z.object({
        period: z.enum(['daily', 'weekly', 'monthly']).default('weekly'),
        limit: z.number().min(10).max(500).default(20),
      })
    )
    .query(async ({ input }) => {
      return await GameLeaderboards.getTrendingPlayers(input.period, input.limit);
    }),

  /**
   * Get leaderboard around player
   */
  getLeaderboardAroundPlayer: protectedProcedure
    .input(
      z.object({
        gameId: z.string().optional(),
        period: z.enum(['daily', 'weekly', 'monthly', 'alltime']).default('weekly'),
        range: z.number().min(1).max(20).default(5),
      })
    )
    .query(async ({ input, ctx }) => {
      return await GameLeaderboards.getLeaderboardAroundPlayer(
        ctx.user.id.toString(),
        input.gameId,
        input.period,
        input.range
      );
    }),

  /**
   * Get player stats
   */
  getPlayerStats: protectedProcedure.query(async ({ ctx }) => {
    return await GameLeaderboards.getPlayerStats(ctx.user.id.toString());
  }),

  /**
   * Record game play
   */
  recordGamePlay: protectedProcedure
    .input(
      z.object({
        gameId: z.string(),
        wagered: z.number().positive(),
        won: z.number().nonnegative(),
        spins: z.number().positive(),
      })
    )
    .mutation(async ({ input, ctx }) => {
      await GameLeaderboards.recordGamePlay(ctx.user.id.toString(), input.gameId, input.wagered, input.won, input.spins);
      return { success: true };
    }),
});
