import { NextResponse } from "next/server";
import bcrypt from "bcryptjs";
import { prisma } from "@/lib/prisma";
import { requireRole, MEMBER_ROLES } from "@/lib/auth";

const MEMBER_ROLE_SET = new Set<string>(MEMBER_ROLES);

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

/** Update a member credential: password reset, and/or username, display
    name and enable/disable status (institution admin). */
export async function PATCH(req: Request, { params }: Params) {
  const session = await requireRole("INSTITUTION_ADMIN");
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const { id } = await params;
  const body = await req.json();

  const user = await prisma.user.findFirst({
    where: { id: Number(id), institutionId: session.institutionId },
    select: { id: true, role: true, username: true },
  });
  if (!user) return NextResponse.json({ error: "Not found" }, { status: 404 });
  if (!MEMBER_ROLE_SET.has(user.role)) {
    return NextResponse.json({ error: "FORBIDDEN" }, { status: 403 });
  }

  const data: {
    passwordHash?: string;
    username?: string;
    name?: string;
    status?: "ACTIVE" | "INACTIVE";
  } = {};

  if (body.password !== undefined) {
    const password = String(body.password);
    if (password.length < 6) {
      return NextResponse.json({ error: "PASSWORD_TOO_SHORT" }, { status: 400 });
    }
    data.passwordHash = await bcrypt.hash(password, 10);
  }

  if (body.username !== undefined) {
    const username = String(body.username).trim();
    if (!username) return NextResponse.json({ error: "USERNAME_REQUIRED" }, { status: 400 });
    if (username !== user.username) {
      const taken = await prisma.user.findFirst({
        where: { institutionId: session.institutionId, username, NOT: { id: user.id } },
        select: { id: true },
      });
      if (taken) return NextResponse.json({ error: "USERNAME_EXISTS" }, { status: 409 });
      data.username = username;
    }
  }

  if (body.name !== undefined) {
    const name = String(body.name).trim();
    if (!name) return NextResponse.json({ error: "NAME_REQUIRED" }, { status: 400 });
    data.name = name;
  }

  if (body.status !== undefined) {
    const status = String(body.status);
    if (status !== "ACTIVE" && status !== "INACTIVE") {
      return NextResponse.json({ error: "INVALID_STATUS" }, { status: 400 });
    }
    data.status = status;
  }

  if (Object.keys(data).length === 0) {
    return NextResponse.json({ error: "NOTHING_TO_UPDATE" }, { status: 400 });
  }

  const credential = await prisma.user.update({
    where: { id: user.id },
    data,
    select: { id: true, name: true, username: true, role: true, status: true },
  });

  return NextResponse.json({ credential });
}

/** Remove a member credential (never an admin account). */
export async function DELETE(_req: Request, { params }: Params) {
  const session = await requireRole("INSTITUTION_ADMIN");
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const { id } = await params;
  const user = await prisma.user.findFirst({
    where: { id: Number(id), institutionId: session.institutionId },
    select: { id: true, role: true },
  });
  if (!user) return NextResponse.json({ error: "Not found" }, { status: 404 });
  if (!MEMBER_ROLE_SET.has(user.role)) {
    return NextResponse.json({ error: "FORBIDDEN" }, { status: 403 });
  }

  await prisma.user.delete({ where: { id: user.id } });
  return NextResponse.json({ ok: true });
}
