import { NextResponse } from "next/server";
import { DepartmentKey, MarketingMilestoneStatus } from "@prisma/client";
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { canManageMarketing, mapMarketingMilestone } from "@/lib/marketing/persistence";

type UpdateMilestoneBody = {
  title?: string;
  description?: string;
  dueDate?: string;
  status?: string;
  sortOrder?: number;
};

const ALLOWED_STATUS = new Set<MarketingMilestoneStatus>([
  MarketingMilestoneStatus.pending,
  MarketingMilestoneStatus.in_progress,
  MarketingMilestoneStatus.completed,
]);

function parseDate(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 PATCH(request: Request, context: { params: { id: string } }) {
  const session = await getServerSession(authOptions);
  if (!session?.user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

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

  const milestoneId = context.params.id;
  const milestone = await prisma.marketingMilestone.findFirst({
    where: {
      id: milestoneId,
      initiative: { department: DepartmentKey.marketing },
    },
    select: {
      id: true,
      initiativeId: true,
    },
  });

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

  const body = (await request.json()) as UpdateMilestoneBody;
  const title = body.title?.trim();
  const description = body.description?.trim();
  const dueDate = body.dueDate ? parseDate(body.dueDate) : undefined;
  const status = body.status;
  const sortOrder = Number.isFinite(body.sortOrder) ? Math.max(0, Math.round(body.sortOrder as number)) : undefined;

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

  if (status !== undefined && !ALLOWED_STATUS.has(status as MarketingMilestoneStatus)) {
    return NextResponse.json({ error: "Invalid milestone status." }, { status: 400 });
  }

  const updated = await prisma.marketingMilestone.update({
    where: { id: milestoneId },
    data: {
      title: title && title.length > 0 ? title : undefined,
      description: description ?? undefined,
      dueDate: dueDate ?? undefined,
      status: (status as MarketingMilestoneStatus | undefined) ?? undefined,
      sortOrder,
    },
    include: {
      checkpoints: {
        orderBy: { createdAt: "asc" },
      },
    },
  });

  await prisma.marketingInitiativeEdit.create({
    data: {
      initiativeId: milestone.initiativeId,
      editedById: session.user.id,
      editedByName: session.user.name ?? session.user.email ?? "Usuario",
      summary: `Milestone actualizado: ${updated.title}`,
    },
  });

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