import bcrypt from "bcryptjs";
import { prisma } from "@/lib/prisma";
import { requireUser, requirePermission, withGuard } from "@/lib/guard";
import { parseBody, ok } from "@/lib/http";
import { createUserSchema } from "@/lib/validators";
import { isManagerTier } from "@/lib/rbac";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";

const SELECT = {
  id: true,
  name: true,
  email: true,
  role: true,
  position: true,
  departmentId: true,
  department: { select: { id: true, name: true } },
  active: true,
  createdAt: true,
} as const;

// GET /api/users — list users.
// Manager-tier sees everyone (needed for the admin staff-picker). Staff get
// only themselves (used to resolve their own profile).
export const GET = withGuard(async () => {
  const me = await requireUser();
  if (isManagerTier(me.role)) {
    const users = await prisma.user.findMany({
      select: SELECT,
      orderBy: [{ role: "asc" }, { name: "asc" }],
    });
    return ok(users);
  }
  const self = await prisma.user.findUnique({
    where: { id: me.id },
    select: SELECT,
  });
  return ok(self ? [self] : []);
});

// POST /api/users — create a user (Super Admin / Admin only).
export const POST = withGuard(async (req: Request) => {
  await requirePermission("users:manage");
  const data = await parseBody(req, createUserSchema);

  const email = data.email.trim().toLowerCase();
  const exists = await prisma.user.findUnique({ where: { email } });
  if (exists) return ok({ error: "Email already in use" }, 409);

  const user = await prisma.user.create({
    data: {
      name: data.name,
      email,
      role: data.role,
      position: data.role === "STAFF" ? data.position ?? null : data.position ?? null,
      departmentId: data.departmentId ?? null,
      passwordHash: await bcrypt.hash(data.password, 10),
    },
    select: SELECT,
  });
  return ok(user, 201);
});
