import { NextResponse } from "next/server";
import { getServerSession } from "next-auth";
import { DepartmentKey, RoleKey } from "@prisma/client";
import { authOptions } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { canUseElevatedAccess } from "@/lib/elevated-access";

type UpdateRoleBody = {
  role?: RoleKey;
};

function isRoleKey(value: string | undefined): value is RoleKey {
  return value === "owner" || value === "leader" || value === "employee";
}

export async function PATCH(request: Request, context: { params: { id: string } }) {
  const session = await getServerSession(authOptions);
  if (!session?.user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const canManageRoles = session.user.role === "owner" || canUseElevatedAccess(session.user.email);
  if (!canManageRoles) {
    return NextResponse.json({ error: "Only owners or elevated admins can edit roles." }, { status: 403 });
  }

  const userId = context.params.id;
  if (userId === session.user.id) {
    return NextResponse.json({ error: "No puedes cambiar tu propio rol desde esta vista." }, { status: 400 });
  }

  const body = (await request.json()) as UpdateRoleBody;
  const requestedRole = body.role;

  if (!isRoleKey(requestedRole)) {
    return NextResponse.json({ error: "Invalid role." }, { status: 400 });
  }

  const targetUser = await prisma.user.findUnique({
    where: { id: userId },
    select: {
      id: true,
      department: true,
      departmentRole: true,
      userRoles: {
        include: {
          role: true,
        },
      },
    },
  });

  if (!targetUser) {
    return NextResponse.json({ error: "User not found." }, { status: 404 });
  }

  const targetRoleRecord = await prisma.role.findUnique({
    where: { key: requestedRole },
    select: { id: true },
  });

  if (!targetRoleRecord) {
    return NextResponse.json({ error: "Role missing in database. Run seed." }, { status: 400 });
  }

  const isCurrentlyOwner = targetUser.userRoles.some((entry) => entry.role.key === "owner");
  if (isCurrentlyOwner && requestedRole !== "owner") {
    const ownerCount = await prisma.userRole.count({
      where: {
        role: {
          key: "owner",
        },
      },
    });

    if (ownerCount <= 1) {
      return NextResponse.json({ error: "Cannot remove the last owner." }, { status: 400 });
    }
  }

  await prisma.$transaction(async (tx) => {
    await tx.userRole.deleteMany({
      where: { userId: targetUser.id },
    });

    await tx.userRole.create({
      data: {
        userId: targetUser.id,
        roleId: targetRoleRecord.id,
      },
    });

    if (requestedRole !== "owner") {
      await tx.user.update({
        where: { id: targetUser.id },
        data: {
          department: {
            set: targetUser.department ?? DepartmentKey.marketing,
          },
          departmentRole: targetUser.departmentRole ?? "Miembro de equipo",
        },
      });
    }
  });

  return NextResponse.json({ ok: true });
}
