import { NextRequest, NextResponse } from "next/server";
import { getStripe } from "stripe/client";
import { inngest } from "app/api/inngest/client";
import { handleCheckoutCompleted } from "./handle_checkout_completed";
import { handleSubscriptionUpdated } from "./handle_subscription_updated";
import { handleSubscriptionDeleted } from "./handle_subscription_deleted";
import { handleInvoicePaymentFailed } from "./handle_invoice_payment_failed";

export async function POST(req: NextRequest) {
  const body = await req.text();
  const signature = req.headers.get("stripe-signature");
  if (!signature) {
    return NextResponse.json({ error: "Missing signature" }, { status: 400 });
  }

  let event;
  try {
    event = getStripe().webhooks.constructEvent(
      body,
      signature,
      process.env.STRIPE_WEBHOOK_SECRET as string,
    );
  } catch (err) {
    console.error("Stripe webhook signature verification failed:", err);
    return NextResponse.json({ error: "Invalid signature" }, { status: 400 });
  }

  switch (event.type) {
    case "checkout.session.completed": {
      const sessionId = event.data.object.id;
      await inngest.send({
        name: "stripe/checkout.session.completed",
        data: { sessionId },
      });
      await handleCheckoutCompleted(sessionId);
      break;
    }

    case "customer.subscription.created":
    case "customer.subscription.updated": {
      const subscriptionId = event.data.object.id;
      await inngest.send({
        name: "stripe/customer.subscription.updated",
        data: { subscriptionId },
      });
      await handleSubscriptionUpdated(subscriptionId);
      break;
    }

    case "customer.subscription.deleted": {
      const subscriptionId = event.data.object.id;
      await inngest.send({
        name: "stripe/customer.subscription.deleted",
        data: { subscriptionId },
      });
      await handleSubscriptionDeleted(subscriptionId);
      break;
    }

    case "invoice.payment_succeeded": {
      const invoice = event.data.object;
      const sub = invoice.parent?.subscription_details?.subscription;
      const subId =
        typeof sub === "string"
          ? sub
          : typeof sub === "object" && sub
            ? sub.id
            : "";
      if (subId) {
        await inngest.send({
          name: "stripe/invoice.payment.succeeded",
          data: {
            invoiceId: invoice.id,
            subscriptionId: subId,
            customerId: invoice.customer as string,
          },
        });
        await handleSubscriptionUpdated(subId);
      }
      break;
    }

    case "invoice.payment_failed": {
      const invoice = event.data.object;
      const sub = invoice.parent?.subscription_details?.subscription;
      const subId =
        typeof sub === "string"
          ? sub
          : typeof sub === "object" && sub
            ? sub.id
            : "";
      await inngest.send({
        name: "stripe/invoice.payment.failed",
        data: {
          invoiceId: invoice.id,
          subscriptionId: subId,
          customerId: invoice.customer as string,
        },
      });
      await handleInvoicePaymentFailed(subId);
      break;
    }
  }

  return NextResponse.json({ received: true });
}
