import { z } from "zod";
import { router, protectedProcedure } from "../_core/trpc.ts";
import { TRPCError } from "@trpc/server";
import { getDb } from "../db.ts";
import { userFavorites, casinoGames } from "../../drizzle/schema.ts";
import { eq, and, desc, inArray } from "drizzle-orm";

export const favoritesRouter = router({
  // Get user's favorite games
  list: protectedProcedure.query(async ({ ctx }) => {
    const database = await getDb();
    if (!database) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: "Database unavailable" });

    const favorites = await database
      .select({
        id: userFavorites.id,
        gameId: userFavorites.gameId,
        createdAt: userFavorites.createdAt,
        gameTitle: casinoGames.title,
        gameSlug: casinoGames.slug,
        gameProvider: casinoGames.provider,
        gameCategory: casinoGames.category,
        gameThumbnail: casinoGames.thumbnailUrl,
        gameRtp: casinoGames.rtp,
        gameVolatility: casinoGames.volatility,
        gameIsActive: casinoGames.isActive,
      })
      .from(userFavorites)
      .innerJoin(casinoGames, eq(userFavorites.gameId, casinoGames.id))
      .where(eq(userFavorites.userId, ctx.user.id))
      .orderBy(desc(userFavorites.createdAt));

    return favorites;
  }),

  // Get favorite game IDs only (for quick lookup)
  getIds: protectedProcedure.query(async ({ ctx }) => {
    const database = await getDb();
    if (!database) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: "Database unavailable" });

    const favorites = await database
      .select({ gameId: userFavorites.gameId })
      .from(userFavorites)
      .where(eq(userFavorites.userId, ctx.user.id));

    return favorites.map((f) => f.gameId);
  }),

  // Toggle favorite (add if not exists, remove if exists)
  toggle: protectedProcedure
    .input(z.object({ gameId: z.number().int() }))
    .mutation(async ({ ctx, input }) => {
      const database = await getDb();
      if (!database) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: "Database unavailable" });

      // Check if already favorited
      const existing = await database
        .select({ id: userFavorites.id })
        .from(userFavorites)
        .where(
          and(
            eq(userFavorites.userId, ctx.user.id),
            eq(userFavorites.gameId, input.gameId)
          )
        );

      if (existing.length > 0) {
        // Remove favorite
        await database
          .delete(userFavorites)
          .where(
            and(
              eq(userFavorites.userId, ctx.user.id),
              eq(userFavorites.gameId, input.gameId)
            )
          );
        return { favorited: false };
      } else {
        // Add favorite
        await database.insert(userFavorites).values({
          userId: ctx.user.id,
          gameId: input.gameId,
        });
        return { favorited: true };
      }
    }),

  // Check if a specific game is favorited
  isFavorited: protectedProcedure
    .input(z.object({ gameId: z.number().int() }))
    .query(async ({ ctx, input }) => {
      const database = await getDb();
      if (!database) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: "Database unavailable" });

      const existing = await database
        .select({ id: userFavorites.id })
        .from(userFavorites)
        .where(
          and(
            eq(userFavorites.userId, ctx.user.id),
            eq(userFavorites.gameId, input.gameId)
          )
        );

      return { favorited: existing.length > 0 };
    }),

  // Get favorite count
  count: protectedProcedure.query(async ({ ctx }) => {
    const database = await getDb();
    if (!database) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: "Database unavailable" });

    const favorites = await database
      .select({ id: userFavorites.id })
      .from(userFavorites)
      .where(eq(userFavorites.userId, ctx.user.id));

    return { count: favorites.length };
  }),
});
