import { NextResponse } from "next/server";
import { getServerSession } from "next-auth";
import { DepartmentKey } from "@prisma/client";
import { authOptions } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { mapMeeting, parseStringArray } from "@/lib/marketing/meetings";
import { canAccessMarketing, canManageMarketing } from "@/lib/marketing/persistence";

type CreateMeetingRequestBody = {
  kind?: "request" | "schedule";
  title?: string;
  agenda?: string;
  participantNames?: unknown;
  suggestedTimes?: unknown;
  scheduledFor?: string;
};

function parseIsoDate(value: string | undefined): Date | null {
  if (!value) {
    return null;
  }

  const parsed = new Date(value);
  if (Number.isNaN(parsed.getTime())) {
    return null;
  }

  return parsed;
}

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

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

  const meetings = await prisma.marketingMeeting.findMany({
    where: {
      department: DepartmentKey.marketing,
    },
    include: {
      commitments: {
        orderBy: { createdAt: "asc" },
      },
    },
    orderBy: [{ scheduledFor: "asc" }, { createdAt: "desc" }],
  });

  return NextResponse.json({
    ok: true,
    meetings: meetings.map(mapMeeting),
  });
}

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

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

  const body = (await request.json()) as CreateMeetingRequestBody;
  const kind = body.kind;
  const title = body.title?.trim() ?? "";
  const agenda = body.agenda?.trim() ?? "";

  if (!kind || (kind !== "request" && kind !== "schedule")) {
    return NextResponse.json({ error: "Invalid kind." }, { status: 400 });
  }

  if (!agenda) {
    return NextResponse.json({ error: "Agenda is required." }, { status: 400 });
  }

  const participantNames = parseStringArray(body.participantNames);
  if (participantNames.length === 0) {
    return NextResponse.json({ error: "At least one participant is required." }, { status: 400 });
  }

  const requestedByName = session.user.name?.trim() || session.user.email || "Usuario";

  if (kind === "request") {
    const suggestedTimes = parseStringArray(body.suggestedTimes);
    if (suggestedTimes.length === 0) {
      return NextResponse.json({ error: "At least one suggested time is required." }, { status: 400 });
    }

    const meeting = await prisma.marketingMeeting.create({
      data: {
        department: DepartmentKey.marketing,
        title: title || "Solicitud de reunión",
        agenda,
        status: "requested",
        requestedById: session.user.id,
        requestedByName,
        participantNames,
        suggestedTimes,
      },
      include: {
        commitments: {
          orderBy: { createdAt: "asc" },
        },
      },
    });

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

  if (!canManageMarketing(session.user.role, session.user.department)) {
    return NextResponse.json({ error: "Only owners or leaders can schedule meetings." }, { status: 403 });
  }

  const scheduledFor = parseIsoDate(body.scheduledFor);
  if (!scheduledFor) {
    return NextResponse.json({ error: "Invalid scheduledFor." }, { status: 400 });
  }

  const meeting = await prisma.marketingMeeting.create({
    data: {
      department: DepartmentKey.marketing,
      title: title || "Reunión de marketing",
      agenda,
      status: "scheduled",
      requestedById: session.user.id,
      requestedByName,
      participantNames,
      suggestedTimes: [],
      scheduledFor,
    },
    include: {
      commitments: {
        orderBy: { createdAt: "asc" },
      },
    },
  });

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