import { protectedProcedure, router } from "../_core/trpc.ts";
import { TRPCError } from "@trpc/server";
import { getDb, writeAuditLog } from "../db.ts";
import { eq, and } from "drizzle-orm";
import z from "zod";
import { generateAllGames, getGameById, getGamesByTheme, getGamesByVolatility, getRandomGames, getGameStats } from "../gameGenerator.ts";

// Generate all games once
const allGames = generateAllGames(700);

export const adminGamesRouter = router({
  /**
   * Get all games with pagination
   */
  getAllGames: protectedProcedure
    .input(
      z.object({
        limit: z.number().default(50),
        offset: z.number().default(0),
        search: z.string().optional(),
        theme: z.string().optional(),
        volatility: z.enum(["low", "medium", "high"]).optional(),
      })
    )
    .query(async ({ ctx, input }) => {
      // Only admins can access
      if (ctx.user.role !== "admin") {
        throw new TRPCError({ code: "FORBIDDEN", message: "Admin only" });
      }

      let filtered = [...allGames];

      // Filter by search
      if (input.search) {
        const search = input.search.toLowerCase();
        filtered = filtered.filter(
          (g) =>
            g.name.toLowerCase().includes(search) ||
            g.theme.toLowerCase().includes(search) ||
            g.id.toLowerCase().includes(search)
        );
      }

      // Filter by theme
      if (input.theme) {
        filtered = filtered.filter((g) => g.theme === input.theme);
      }

      // Filter by volatility
      if (input.volatility) {
        filtered = filtered.filter((g) => g.volatility === input.volatility);
      }

      // Paginate
      const total = filtered.length;
      const games = filtered.slice(input.offset, input.offset + input.limit);

      return { games, total };
    }),

  /**
   * Get game by ID
   */
  getGameById: protectedProcedure
    .input(z.object({ gameId: z.string() }))
    .query(async ({ ctx, input }) => {
      if (ctx.user.role !== "admin") {
        throw new TRPCError({ code: "FORBIDDEN", message: "Admin only" });
      }

      const game = getGameById(input.gameId, allGames);
      if (!game) {
        throw new TRPCError({ code: "NOT_FOUND", message: "Game not found" });
      }

      return game;
    }),

  /**
   * Get games by theme
   */
  getGamesByTheme: protectedProcedure
    .input(z.object({ theme: z.string() }))
    .query(async ({ ctx, input }) => {
      if (ctx.user.role !== "admin") {
        throw new TRPCError({ code: "FORBIDDEN", message: "Admin only" });
      }

      return getGamesByTheme(input.theme, allGames);
    }),

  /**
   * Get games by volatility
   */
  getGamesByVolatility: protectedProcedure
    .input(z.object({ volatility: z.enum(["low", "medium", "high"]) }))
    .query(async ({ ctx, input }) => {
      if (ctx.user.role !== "admin") {
        throw new TRPCError({ code: "FORBIDDEN", message: "Admin only" });
      }

      return getGamesByVolatility(input.volatility, allGames);
    }),

  /**
   * Get game statistics
   */
  getGameStats: protectedProcedure.query(async ({ ctx }) => {
    if (ctx.user.role !== "admin") {
      throw new TRPCError({ code: "FORBIDDEN", message: "Admin only" });
    }

    return getGameStats(allGames);
  }),

  /**
   * Update game settings (max win, enabled/disabled)
   */
  updateGameSettings: protectedProcedure
    .input(
      z.object({
        gameId: z.string(),
        maxWin: z.number().min(0.01).max(20).optional(),
        enabled: z.boolean().optional(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      if (ctx.user.role !== "admin") {
        throw new TRPCError({ code: "FORBIDDEN", message: "Admin only" });
      }

      const game = getGameById(input.gameId, allGames);
      if (!game) {
        throw new TRPCError({ code: "NOT_FOUND", message: "Game not found" });
      }

      // Update game settings in memory (in production, store in database)
      if (input.maxWin !== undefined) {
        game.maxWin = input.maxWin;
      }

      // Log the action
      await writeAuditLog({
        actorId: ctx.user.id,
        action: "game_settings_updated",
        category: "admin",
        details: {
          gameId: input.gameId,
          gameName: game.name,
          maxWin: input.maxWin,
          enabled: input.enabled,
        },
      });

      return { success: true, game };
    }),

  /**
   * Get all unique themes
   */
  getThemes: protectedProcedure.query(async ({ ctx }) => {
    if (ctx.user.role !== "admin") {
      throw new TRPCError({ code: "FORBIDDEN", message: "Admin only" });
    }

    const themeSet = new Set(allGames.map((g) => g.theme));
    const themes = Array.from(themeSet).sort();
    return themes;
  }),

  /**
   * Get random featured games
   */
  getFeaturedGames: protectedProcedure
    .input(z.object({ count: z.number().default(10) }))
    .query(async ({ ctx, input }) => {
      if (ctx.user.role !== "admin") {
        throw new TRPCError({ code: "FORBIDDEN", message: "Admin only" });
      }

      return getRandomGames(input.count, allGames);
    }),
});
