import { getDb } from "../db.ts";
import { userFavorites, allGames } from "../../drizzle/schema.ts";
import { eq, and } from "drizzle-orm";

export async function addFavorite(userId: number, gameId: number): Promise<boolean> {
  const db = await getDb();
  if (!db) return false;

  try {
    await db.insert(userFavorites).values({
      userId,
      gameId,
      addedAt: new Date(),
    });
    return true;
  } catch (error) {
    console.error("Error adding favorite:", error);
    return false;
  }
}

export async function removeFavorite(userId: number, gameId: number): Promise<boolean> {
  const db = await getDb();
  if (!db) return false;

  try {
    await db.delete(userFavorites).where(and(eq(userFavorites.userId, userId), eq(userFavorites.gameId, gameId)));
    return true;
  } catch (error) {
    console.error("Error removing favorite:", error);
    return false;
  }
}

export async function isFavorite(userId: number, gameId: number): Promise<boolean> {
  const db = await getDb();
  if (!db) return false;

  try {
    const result = await db
      .select()
      .from(userFavorites)
      .where(and(eq(userFavorites.userId, userId), eq(userFavorites.gameId, gameId)))
      .limit(1);

    return result.length > 0;
  } catch (error) {
    console.error("Error checking favorite:", error);
    return false;
  }
}

export async function getUserFavorites(userId: number, limit: number = 50) {
  const db = await getDb();
  if (!db) return [];

  try {
    const favorites = await db
      .select({
        gameId: userFavorites.gameId,
        addedAt: userFavorites.addedAt,
        game: {
          id: allGames.id,
          title: allGames.title,
          provider: allGames.provider,
          thumbnail: allGames.thumbnail,
          category: allGames.category,
          rtp: allGames.rtp,
          volatility: allGames.volatility,
        },
      })
      .from(userFavorites)
      .innerJoin(allGames, eq(userFavorites.gameId, allGames.id))
      .where(eq(userFavorites.userId, userId))
      .orderBy(userFavorites.addedAt)
      .limit(limit);

    return favorites;
  } catch (error) {
    console.error("Error getting user favorites:", error);
    return [];
  }
}

export async function getFavoriteCount(userId: number): Promise<number> {
  const db = await getDb();
  if (!db) return 0;

  try {
    const result = await db
      .select({ count: userFavorites.id })
      .from(userFavorites)
      .where(eq(userFavorites.userId, userId));

    return result[0]?.count || 0;
  } catch (error) {
    console.error("Error getting favorite count:", error);
    return 0;
  }
}

export async function clearFavorites(userId: number): Promise<boolean> {
  const db = await getDb();
  if (!db) return false;

  try {
    await db.delete(userFavorites).where(eq(userFavorites.userId, userId));
    return true;
  } catch (error) {
    console.error("Error clearing favorites:", error);
    return false;
  }
}

export async function getFavoritesByCategory(userId: number, category: string, limit: number = 50) {
  const db = await getDb();
  if (!db) return [];

  try {
    const favorites = await db
      .select({
        gameId: userFavorites.gameId,
        addedAt: userFavorites.addedAt,
        game: {
          id: allGames.id,
          title: allGames.title,
          provider: allGames.provider,
          thumbnail: allGames.thumbnail,
          category: allGames.category,
          rtp: allGames.rtp,
          volatility: allGames.volatility,
        },
      })
      .from(userFavorites)
      .innerJoin(allGames, eq(userFavorites.gameId, allGames.id))
      .where(and(eq(userFavorites.userId, userId), eq(allGames.category, category)))
      .orderBy(userFavorites.addedAt)
      .limit(limit);

    return favorites;
  } catch (error) {
    console.error("Error getting favorites by category:", error);
    return [];
  }
}

export async function getMostFavoritedGames(limit: number = 20) {
  const db = await getDb();
  if (!db) return [];

  try {
    const mostFavorited = await db
      .select({
        gameId: userFavorites.gameId,
        favoriteCount: userFavorites.id,
        game: {
          id: allGames.id,
          title: allGames.title,
          provider: allGames.provider,
          thumbnail: allGames.thumbnail,
          category: allGames.category,
          rtp: allGames.rtp,
        },
      })
      .from(userFavorites)
      .innerJoin(allGames, eq(userFavorites.gameId, allGames.id))
      .groupBy(userFavorites.gameId)
      .orderBy(userFavorites.id)
      .limit(limit);

    return mostFavorited;
  } catch (error) {
    console.error("Error getting most favorited games:", error);
    return [];
  }
}
