import { NextResponse } from "next/server";
import { getSessionCustomer, getCustomerOrderDetail } from "../../../../../lib/customerAuth";
import { getPaymentMethods, groupPaymentMethodsForCheckout } from "../../../../../lib/payload";
import { paymentProvider, isPaymentTestMode } from "../../../../../lib/payments";

const PAYLOAD_URL = process.env.PAYLOAD_URL || "https://payload.mk360.de";
const PAYMENT_WEBHOOK_SECRET = process.env.PAYMENT_WEBHOOK_SECRET || "";

// Lets a logged-in customer move an existing, still-unpaid Überweisung
// order onto a Stripe PaymentIntent instead of waiting on their own bank
// transfer — see the backend's switchPaymentToStripe.ts for the matching
// endpoint and why this needs a dedicated backend route rather than the
// generic customer-JWT order-PATCH path (paymentProvider/paymentStatus
// are system fields a customer JWT can never touch).
export async function POST(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 order = await getCustomerOrderDetail(session.token, session.customer.id, decodeURIComponent(orderNumber));
  if (!order) return NextResponse.json({ ok: false, reason: "Bestellung nicht gefunden." }, { status: 404 });

  // Same eligibility the backend endpoint re-checks authoritatively —
  // checked here too for a friendly error instead of a bare 409. An
  // explicit allowlist ('pending'/'not_applicable'), not a
  // paymentStatus !== "paid" blocklist — see switchPaymentToStripe.ts's
  // own comment on why 'failed'/'refunded'/'partially_refunded' aren't
  // meaningful states to switch from either.
  const eligiblePaymentStatus = order.paymentStatus === "pending" || order.paymentStatus === "not_applicable";
  if (order.paymentProvider !== "manual" || order.status !== "received" || !eligiblePaymentStatus) {
    return NextResponse.json({ ok: false, reason: "Die Zahlungsart kann für diese Bestellung gerade nicht geändert werden." }, { status: 400 });
  }

  // Only offer this when a real Stripe payment method is actually active
  // — same "Online-Zahlung" grouping the checkout itself uses, so this
  // never presents an option that checkout wouldn't currently accept either.
  const methods = groupPaymentMethodsForCheckout(await getPaymentMethods());
  const hasStripeOption = methods.some((m) => m.provider === "stripe");
  if (!hasStripeOption) {
    return NextResponse.json({ ok: false, reason: "Aktuell steht keine Online-Zahlung zur Verfügung." }, { status: 400 });
  }

  let intent: { clientSecret: string; providerReference: string };
  try {
    intent = await paymentProvider.createPaymentIntent({
      amountCents: Math.round(order.total * 100),
      currency: "eur",
      customerEmail: order.customerEmail,
      description: `Bestellung ${order.orderNumber}`,
    });
  } catch (err) {
    return NextResponse.json({ ok: false, reason: "Zahlung konnte nicht vorbereitet werden." }, { status: 500 });
  }

  const res = await fetch(`${PAYLOAD_URL}/api/orders/${order.id}/switch-payment-to-stripe`, {
    method: "POST",
    headers: { "Content-Type": "application/json", "x-payment-webhook-secret": PAYMENT_WEBHOOK_SECRET },
    body: JSON.stringify({ providerReference: intent.providerReference }),
  });
  if (!res.ok) {
    const data = await res.json().catch(() => null);
    return NextResponse.json({ ok: false, reason: data?.reason ?? "Umstellung fehlgeschlagen." }, { status: 400 });
  }

  // Best-effort, same as checkout's own call — a failure here doesn't
  // block the payment itself, only the confirm-payment webhook's metadata
  // lookup, which the frontend's own webhook route already alerts on.
  await paymentProvider.attachOrderMetadata(intent.providerReference, { orderId: String(order.id), orderNumber: order.orderNumber }).catch(() => {});

  return NextResponse.json({
    ok: true,
    clientSecret: intent.clientSecret,
    orderId: order.id,
    orderNumber: order.orderNumber,
    testMode: isPaymentTestMode,
    ...(isPaymentTestMode ? { providerReference: intent.providerReference } : {}),
  });
}
