import { NextResponse } from "next/server";
import {
  getSessionCustomer,
  getCustomerOrderDetail,
  requestOrderStatusChange,
  customerOrderAction,
  type CustomerOrderItem,
} from "../../../../lib/customerAuth";

// The real security boundary is Orders.ts's beforeChange hook in Payload
// (only `status`/`returnReason`/items' `returnQuantity` can change, only
// via an allowed transition) — the checks here are just for a friendlier
// error message than a bare 403 when the request is malformed or stale
// (e.g. two tabs open, order shipped in the meantime, a quantity that no
// longer fits).
export async function PATCH(request: Request, { params }: { params: Promise<{ orderNumber: string }> }) {
  const session = await getSessionCustomer();
  if (!session) return NextResponse.json({ ok: false, reason: "Bitte zuerst einloggen." }, { status: 401 });

  const { orderNumber } = await params;
  const body = await request.json().catch(() => null);
  const action = body?.action;
  if (action !== "cancel" && action !== "request-return") {
    return NextResponse.json({ ok: false, reason: "Ungültige Aktion." }, { status: 400 });
  }

  const order = await getCustomerOrderDetail(session.token, session.customer.id, decodeURIComponent(orderNumber));
  if (!order) return NextResponse.json({ ok: false, reason: "Bestellung nicht gefunden." }, { status: 404 });
  if (customerOrderAction(order.status) !== action) {
    return NextResponse.json({ ok: false, reason: "Diese Aktion ist für diese Bestellung gerade nicht möglich." }, { status: 400 });
  }

  if (action === "cancel") {
    const result = await requestOrderStatusChange(session.token, order.id, "cancel");
    return NextResponse.json(result, { status: result.ok ? 200 : 400 });
  }

  // request-return: partial returns supported — the client sends
  // { product, returnQuantity } per line it wants to return (0 or
  // omitted for lines being kept). Reconstruct the order's FULL items
  // array here (see requestOrderStatusChange's own comment on why a
  // sparse patch doesn't work), validating each requested quantity
  // against what was actually ordered.
  const returnReason = typeof body?.returnReason === "string" ? body.returnReason.trim() : "";
  if (!returnReason) {
    return NextResponse.json({ ok: false, reason: "Bitte kurz angeben, warum du zurücksenden möchtest." }, { status: 400 });
  }
  const requestedQuantities = new Map<number, number>();
  if (Array.isArray(body?.returnItems)) {
    for (const line of body.returnItems) {
      const product = Number(line?.product);
      const returnQuantity = Number(line?.returnQuantity);
      if (Number.isFinite(product) && Number.isFinite(returnQuantity) && returnQuantity > 0) {
        requestedQuantities.set(product, returnQuantity);
      }
    }
  }
  if (requestedQuantities.size === 0) {
    return NextResponse.json({ ok: false, reason: "Bitte mindestens einen Artikel mit Menge auswählen." }, { status: 400 });
  }

  const items: CustomerOrderItem[] = order.items.map((item) => {
    const requested = requestedQuantities.get(item.product) ?? 0;
    if (requested > item.quantity) {
      throw Object.assign(new Error("returnQuantity exceeds ordered quantity"), { status: 400 });
    }
    return { ...item, returnQuantity: requested };
  });

  try {
    const result = await requestOrderStatusChange(session.token, order.id, "request-return", { returnReason, items });
    return NextResponse.json(result, { status: result.ok ? 200 : 400 });
  } catch {
    return NextResponse.json({ ok: false, reason: "Eine der Mengen übersteigt die bestellte Menge." }, { status: 400 });
  }
}
