import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { capturePayPalOrder } from "@/lib/payments";

function orderRedirect(request: Request, path: string, orderNumber?: string) {
  const url = new URL(path, request.url);
  if (orderNumber) url.searchParams.set("order", orderNumber);
  return NextResponse.redirect(url);
}

export async function GET(request: Request) {
  const url = new URL(request.url);
  const localOrderId = url.searchParams.get("orderId");
  const paypalOrderId = url.searchParams.get("token");

  if (!localOrderId || !paypalOrderId) {
    return orderRedirect(request, "/payment-failed");
  }

  const order = await prisma.order.findUnique({
    where: { id: localOrderId },
    include: {
      items: { include: { product: true } },
      paymentLogs: { orderBy: { createdAt: "desc" } }
    }
  });

  if (!order || order.paymentMethod !== "PAYPAL") {
    return orderRedirect(request, "/payment-failed");
  }

  if (order.paymentStatus === "PAID") {
    return orderRedirect(request, "/payment-success", order.orderNumber);
  }

  const paymentLogId = order.paymentLogs.find((log) => log.provider === "PAYPAL")?.id || order.paymentLogs[0]?.id;

  for (const item of order.items) {
    if (item.product.stockQuantity < item.quantity || item.product.stockStatus === "OUT_OF_STOCK" || item.product.inventoryStatus === "OUT_OF_STOCK") {
      await prisma.order.update({
        where: { id: order.id },
        data: {
          paymentStatus: "FAILED",
          paymentLogs: paymentLogId
            ? {
                update: {
                  where: { id: paymentLogId },
                  data: {
                    provider: "PAYPAL",
                    status: "FAILED",
                    rawResponse: JSON.stringify({
                      paypalOrderId,
                      error: { message: `${item.productNameSnapshot} is no longer available in the requested quantity.` }
                    })
                  }
                }
              }
            : undefined
        }
      });
      return orderRedirect(request, "/payment-failed", order.orderNumber);
    }
  }

  const payment = await capturePayPalOrder(paypalOrderId);

  if (payment.status !== "PAID") {
    await prisma.order.update({
      where: { id: order.id },
      data: {
        paymentStatus: "FAILED",
        paymentLogs: paymentLogId
          ? {
              update: {
                where: { id: paymentLogId },
                data: {
                  provider: payment.provider,
                  status: "FAILED",
                  rawResponse: JSON.stringify(payment.rawResponse)
                }
              }
            }
          : undefined
      }
    });
    return orderRedirect(request, "/payment-failed", order.orderNumber);
  }

  try {
    await prisma.$transaction(async (tx) => {
      const currentOrder = await tx.order.findUnique({
        where: { id: order.id },
        include: { items: { include: { product: true } } }
      });

      if (!currentOrder || currentOrder.paymentStatus === "PAID") return;

      for (const item of currentOrder.items) {
        const result = await tx.product.updateMany({
          where: { id: item.productId, itemKind: "PHYSICAL_BULLION", stockQuantity: { gte: item.quantity } },
          data: { stockQuantity: { decrement: item.quantity } }
        });
        if (result.count !== 1) throw new Error(`${item.productNameSnapshot} no longer has enough stock.`);

        const remainingStock = item.product.stockQuantity - item.quantity;
        if (remainingStock <= 0) {
          await tx.product.update({
            where: { id: item.productId },
            data: { stockStatus: "OUT_OF_STOCK", inventoryStatus: "OUT_OF_STOCK" }
          });
        }
      }

      await tx.order.update({
        where: { id: order.id },
        data: {
          paymentStatus: "PAID",
          paymentLogs: paymentLogId
            ? {
                update: {
                  where: { id: paymentLogId },
                  data: {
                    provider: payment.provider,
                    status: "PAID",
                    rawResponse: JSON.stringify(payment.rawResponse)
                  }
                }
              }
            : undefined
        }
      });
    });
  } catch (error) {
    const message = error instanceof Error ? error.message : "PayPal payment captured, but order fulfillment could not be finalized.";
    await prisma.order.update({
      where: { id: order.id },
      data: {
        paymentStatus: "PENDING",
        adminNotes: message,
        paymentLogs: paymentLogId
          ? {
              update: {
                where: { id: paymentLogId },
                data: {
                  provider: payment.provider,
                  status: "PAID",
                  rawResponse: JSON.stringify({ ...payment.rawResponse, fulfillmentWarning: message })
                }
              }
            }
          : undefined
      }
    });
  }

  return orderRedirect(request, "/payment-success", order.orderNumber);
}
