import { Router, type IRouter } from "express";
import { db, favoritesTable, profilesTable } from "@workspace/db";
import { eq, and, inArray } from "drizzle-orm";
import { requireRole } from "../middlewares/auth";
import { AddFavoriteBody, RemoveFavoriteParams } from "@workspace/api-zod";
import { serializeProfile } from "../lib/profile";

const router: IRouter = Router();

// Favorites are a public-user feature — restrict to user accounts.
const requireUser = requireRole("user");

router.get("/favorites", requireUser, async (req, res): Promise<void> => {
  const favs = await db.select().from(favoritesTable).where(eq(favoritesTable.userId, req.user!.id));
  if (favs.length === 0) {
    res.json([]);
    return;
  }
  const profileIds = favs.map((f) => f.profileId);
  const profiles = await db.select().from(profilesTable).where(inArray(profilesTable.id, profileIds));
  res.json(profiles.map(serializeProfile));
});

router.post("/favorites", requireUser, async (req, res): Promise<void> => {
  const parsed = AddFavoriteBody.safeParse(req.body);
  if (!parsed.success) {
    res.status(400).json({ error: parsed.error.message });
    return;
  }
  const { profileId } = parsed.data;

  const [profile] = await db.select().from(profilesTable).where(eq(profilesTable.id, profileId));
  if (!profile) {
    res.status(404).json({ error: "Profile not found" });
    return;
  }

  const [existing] = await db
    .select()
    .from(favoritesTable)
    .where(and(eq(favoritesTable.userId, req.user!.id), eq(favoritesTable.profileId, profileId)));
  if (existing) {
    res.status(409).json({ error: "Already favorited" });
    return;
  }

  await db.insert(favoritesTable).values({ userId: req.user!.id, profileId });
  res.sendStatus(201);
});

router.delete("/favorites/:profileId", requireUser, async (req, res): Promise<void> => {
  const parsed = RemoveFavoriteParams.safeParse({ profileId: req.params.profileId });
  if (!parsed.success) {
    res.status(400).json({ error: "Invalid ID" });
    return;
  }
  await db
    .delete(favoritesTable)
    .where(and(eq(favoritesTable.userId, req.user!.id), eq(favoritesTable.profileId, parsed.data.profileId)));
  res.sendStatus(204);
});

export default router;
