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";
import { canAccessProjects, mapProjectMeeting } from "@/lib/projects/persistence";

type RespondBody = {
  responseStatus?: "accepted" | "declined";
};

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 });
  }

  if (!canAccessProjects(session.user.role, session.user.department)) {
    return NextResponse.json({ error: "Forbidden" }, { status: 403 });
  }

  const body = (await request.json()) as RespondBody;
  const responseStatus = body.responseStatus;

  if (!responseStatus || (responseStatus !== "accepted" && responseStatus !== "declined")) {
    return NextResponse.json({ error: "Invalid responseStatus." }, { status: 400 });
  }

  const meetingId = context.params.id;
  const meeting = await prisma.marketingMeeting.findFirst({
    where: {
      id: meetingId,
      department: DepartmentKey.proyectos,
    },
    include: {
      participants: {
        orderBy: [{ responseStatus: "asc" }, { displayName: "asc" }],
      },
    },
  });

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

  const ownParticipant = meeting.participants.find((participant) => participant.userId === session.user.id);
  if (!ownParticipant) {
    return NextResponse.json({ error: "Only invited participants can respond." }, { status: 403 });
  }

  await prisma.marketingMeetingParticipant.update({
    where: {
      id: ownParticipant.id,
    },
    data: {
      responseStatus,
      respondedAt: new Date(),
    },
  });

  const refreshed = await prisma.marketingMeeting.findUniqueOrThrow({
    where: { id: meetingId },
    include: {
      commitments: {
        orderBy: { createdAt: "asc" },
      },
      participants: {
        orderBy: [{ responseStatus: "asc" }, { displayName: "asc" }],
      },
      calendarEvent: {
        select: { id: true },
      },
    },
  });

  return NextResponse.json({
    ok: true,
    meeting: mapProjectMeeting(refreshed),
  });
}
