import { NextResponse } from "next/server";
import { requireAdminApiUser } from "@/lib/auth/admin";
import { prisma } from "@/lib/prisma";
import { DeliverableUpdateInputSchema } from "@/lib/contracts/types";

type RouteContext = {
  params: Promise<{ id: string }>;
};

function parseJsonBody(body: unknown) {
  return typeof body === "object" && body !== null ? (body as Record<string, unknown>) : {};
}

export async function PATCH(request: Request, context: RouteContext) {
  const user = await requireAdminApiUser();

  if (!user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const { id } = await context.params;

  try {
    const body = parseJsonBody(await request.json().catch(() => ({})));
    const parsed = DeliverableUpdateInputSchema.safeParse(body);

    if (!parsed.success) {
      return NextResponse.json({ error: "Datos de actualizacion invalidos." }, { status: 400 });
    }

    const deliverable = await prisma.contractDeliverable.findFirst({
      where: {
        id,
        contract: {
          userId: user.id,
        },
      },
      select: { id: true },
    });

    if (!deliverable) {
      return NextResponse.json({ error: "Entregable no encontrado." }, { status: 404 });
    }

    const input = parsed.data;

    const updated = await prisma.contractDeliverable.update({
      where: { id },
      data: {
        title: input.title,
        status: input.status,
        dueDate: input.dueDate === undefined ? undefined : input.dueDate ? new Date(input.dueDate) : null,
        deliveredAt: input.deliveredAt === undefined ? undefined : input.deliveredAt ? new Date(input.deliveredAt) : null,
        approvedAt: input.approvedAt === undefined ? undefined : input.approvedAt ? new Date(input.approvedAt) : null,
        notes: input.notes,
        amountLinked: input.amountLinked === undefined ? undefined : input.amountLinked ?? null,
      },
    });

    return NextResponse.json({
      ok: true,
      deliverable: {
        id: updated.id,
        contractId: updated.contractId,
        title: updated.title,
        dueDate: updated.dueDate ? updated.dueDate.toISOString() : null,
        amountLinked: updated.amountLinked ? Number(updated.amountLinked) : null,
        status: updated.status,
        deliveredAt: updated.deliveredAt ? updated.deliveredAt.toISOString() : null,
        approvedAt: updated.approvedAt ? updated.approvedAt.toISOString() : null,
        notes: updated.notes,
      },
    });
  } catch {
    return NextResponse.json({ error: "No fue posible actualizar el entregable." }, { status: 400 });
  }
}
