import { NextResponse } from "next/server";
import { auth } from "@clerk/nextjs/server";
import { db, users as usersTable, eq, sql } from "@fitai/database";
import log from "@/lib/logger";

/**
 * PATCH /api/users/gym
 * Body: { gymId: string | null }
 * - Updates the current authenticated user's gym selection.
 * - gymId can be null to proceed without a gym.
 * - If gymId is provided, it must exist and be active.
 */
export async function PATCH(req: Request) {
  try {
    const { userId } = await auth();
    log.debug("Updating user gym assignment", { userId });
    if (!userId) return new NextResponse("Unauthorized", { status: 401 });

    const body = await req.json().catch(() => null);
    if (!body || typeof body !== "object" || !("gymId" in body)) {
      return NextResponse.json(
        { error: "gymId is required in body (can be null)" },
        { status: 400 },
      );
    }

    const gymId = body.gymId === null ? null : String(body.gymId);
    log.debug("Parsed gym ID from request body", { gymId });

    // Ensure user exists
    log.debug("Fetching user by ID", { userId });
    const user = await db
      .select()
      .from(usersTable)
      .where(eq(usersTable.id, userId))
      .get();
    log.debug("User fetched", { user: user ? { id: user.id } : null });
    if (!user) return new NextResponse("User not found", { status: 404 });

    // Validate gym when provided
    if (gymId) {
      log.debug("Validating gym", { gymId });
      const rows = await db.all(
        sql`SELECT status FROM gyms WHERE id = ${gymId} LIMIT 1`,
      );
      log.debug("Gym validation query result", { rowCount: rows?.length });
      const gym = rows?.[0] as { status?: string } | undefined;
      if (!gym) {
        log.warn("Gym not found during validation", { gymId });
        return NextResponse.json({ error: "Gym not found" }, { status: 404 });
      }
      if (gym.status !== "active") {
        log.warn("Gym is not active", { gymId, status: gym.status });
        return NextResponse.json(
          { error: "Gym is not active" },
          { status: 400 },
        );
      }
    }

    // Update user's gym selection
    log.debug("Updating user gym assignment in database", { userId, gymId });
    await db.run(
      sql`UPDATE users SET gym_id = ${gymId ?? null}, updated_at = ${Date.now()} WHERE id = ${userId}`,
    );
    log.debug("User gym assignment updated");

    const updated = await db
      .select()
      .from(usersTable)
      .where(eq(usersTable.id, userId))
      .get();
    log.debug("Returning updated user", { userId });
    return NextResponse.json(updated);
  } catch (error) {
    log.error("Failed to update user gym assignment", error);
    return new NextResponse("Internal Server Error", { status: 500 });
  }
}
