import bcrypt from "bcryptjs";
import { prisma } from "@/lib/prisma";
import { requirePermission, withGuard, HttpError } from "@/lib/guard";
import { parseBody, ok } from "@/lib/http";
import { updateUserSchema } from "@/lib/validators";

export const runtime = "nodejs";

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

type Ctx = { params: Promise<{ id: string }> };

// PATCH /api/users/[id] — update a user (Super Admin / Admin only).
export const PATCH = withGuard(async (req: Request, ctx: Ctx) => {
  await requirePermission("users:manage");
  const { id } = await ctx.params;
  const data = await parseBody(req, updateUserSchema);

  const patch: Record<string, unknown> = {};
  if (data.name !== undefined) patch.name = data.name;
  if (data.email !== undefined) patch.email = data.email.trim().toLowerCase();
  if (data.role !== undefined) patch.role = data.role;
  if (data.position !== undefined) patch.position = data.position || null;
  if (data.departmentId !== undefined) patch.departmentId = data.departmentId || null;
  if (data.active !== undefined) patch.active = data.active;
  if (data.password) patch.passwordHash = await bcrypt.hash(data.password, 10);

  const user = await prisma.user
    .update({ where: { id }, data: patch, select: SELECT })
    .catch(() => {
      throw new HttpError(404, "User not found");
    });
  return ok(user);
});

// DELETE /api/users/[id] — deactivate (soft delete) by default to preserve
// history. Pass ?hard=true for a permanent delete (Super Admin only): it is
// blocked when the user created tasks (that history can't be removed), and it
// cascades their assigned tasks, personal KPIs, authored posts and appraisals.
export const DELETE = withGuard(async (req: Request, ctx: Ctx) => {
  const me = await requirePermission("users:manage");
  const { id } = await ctx.params;
  const hard = new URL(req.url).searchParams.get("hard") === "true";

  if (!hard) {
    await prisma.user
      .update({ where: { id }, data: { active: false } })
      .catch(() => {
        throw new HttpError(404, "User not found");
      });
    return ok({ ok: true });
  }

  // Permanent delete — Super Admin only.
  if (me.role !== "SUPER_ADMIN") {
    throw new HttpError(403, "Only a Super Admin can permanently delete a user.");
  }
  if (id === me.id) {
    throw new HttpError(400, "You can't permanently delete your own account.");
  }

  const target = await prisma.user.findUnique({ where: { id }, select: { id: true } });
  if (!target) throw new HttpError(404, "User not found");

  // Tasks this user CREATED (e.g. assigned to others) block deletion — removing
  // them would erase other people's task history.
  const createdTasks = await prisma.task.count({ where: { createdById: id } });
  if (createdTasks > 0) {
    throw new HttpError(
      409,
      `This user created ${createdTasks} task(s) for the team, so they can't be permanently deleted without erasing that history. Deactivate them instead.`
    );
  }

  await prisma.user.delete({ where: { id } }).catch(() => {
    throw new HttpError(409, "Unable to permanently delete this user — they still have linked records. Deactivate them instead.");
  });
  return ok({ ok: true });
});
