import { NextResponse } from "next/server";
import { DepartmentKey } from "@prisma/client";
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth";
import { prisma } from "@/lib/prisma";

type UpdateProfileBody = {
  name?: string;
  image?: string;
  department?: DepartmentKey;
  departmentRole?: string;
};

function isDepartmentKey(value: string | undefined): value is DepartmentKey {
  return (
    value === DepartmentKey.marketing ||
    value === DepartmentKey.administracion ||
    value === DepartmentKey.capital_humano ||
    value === DepartmentKey.operaciones ||
    value === DepartmentKey.proyectos
  );
}

function isValidImageUrl(value: string): boolean {
  if (value.startsWith("/api/account/avatar/")) {
    return true;
  }

  if (value.startsWith("/uploads/avatars/")) {
    return true;
  }

  try {
    const url = new URL(value);
    return url.protocol === "http:" || url.protocol === "https:";
  } catch {
    return false;
  }
}

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

  const body = (await request.json()) as UpdateProfileBody;
  const name = body.name?.trim() ?? "";
  const image = body.image?.trim() ?? "";
  const department = body.department;
  const departmentRole = body.departmentRole?.trim() ?? "";

  if (name.length < 2 || name.length > 120) {
    return NextResponse.json({ error: "Name must be between 2 and 120 characters." }, { status: 400 });
  }

  if (image.length > 0 && !isValidImageUrl(image)) {
    return NextResponse.json({ error: "Profile image must be a valid URL." }, { status: 400 });
  }

  if (department && !isDepartmentKey(department)) {
    return NextResponse.json({ error: "Invalid department." }, { status: 400 });
  }

  if (departmentRole.length > 120) {
    return NextResponse.json({ error: "Department role must be 120 characters or fewer." }, { status: 400 });
  }

  const updated = await prisma.user.update({
    where: { id: session.user.id },
    data: {
      name,
      image: image || null,
      department: department ?? undefined,
      departmentRole: departmentRole || null,
    },
    select: {
      id: true,
      name: true,
      email: true,
      image: true,
      department: true,
      departmentRole: true,
    },
  });

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