import { NextResponse } from "next/server";
import { stripe } from "@/lib/stripe";
import { prisma } from "@/lib/prisma";
import Stripe from "stripe";

const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET || "";

async function handler(request: Request) {
  if (request.method !== "POST") {
    return NextResponse.json({ error: "Method not allowed" }, { status: 405 });
  }

  const body = await request.text();
  const signature = request.headers.get("stripe-signature") || "";

  let event: Stripe.Event;
  try {
    event = stripe.webhooks.constructEvent(body, signature, webhookSecret);
  } catch (error) {
    console.error("[webhook] signature verification failed", error);
    return NextResponse.json({ error: "Invalid signature" }, { status: 400 });
  }

  try {
    console.log(`[webhook] received event: ${event.type}`);

    switch (event.type) {
      case "customer.subscription.created":
      case "customer.subscription.updated": {
        const subscription = event.data.object as Stripe.Subscription;
        const userId = subscription.metadata?.userId;
        console.log(`[webhook] subscription event - userId: ${userId}, status: ${subscription.status}`);
        if (!userId) {
          console.warn("[webhook] missing userId in metadata");
          break;
        }

        const active = subscription.status === "active";
        const currentPeriodEnd = new Date((subscription as any).current_period_end * 1000);
        const cancelAtPeriodEnd = (subscription as any).cancel_at_period_end || false;

        const existing = await prisma.subscription.findUnique({
          where: { userId },
        });

        if (existing) {
          await prisma.subscription.update({
            where: { userId },
            data: {
              status: subscription.status,
              currentPeriodEnd,
              canceledAt: (subscription as any).canceled_at
                ? new Date((subscription as any).canceled_at * 1000)
                : null,
            },
          });
        } else {
          await prisma.subscription.create({
            data: {
              userId,
              stripeId: subscription.id,
              stripePriceId: subscription.items.data[0]?.price.id || "",
              stripeCustomerId: subscription.customer as string,
              status: subscription.status,
              currentPeriodEnd,
            },
          });
        }

        const keepPremium = active && !cancelAtPeriodEnd;
        await prisma.user.update({
          where: { id: userId },
          data: { plan: keepPremium ? "PREMIUM" : "FREE" },
        });
        console.log(`[webhook] user ${userId} plan updated to: ${active ? "PREMIUM" : "FREE"}`);
        break;
      }

      case "customer.subscription.deleted": {
        const subscription = event.data.object as Stripe.Subscription;
        const userId = subscription.metadata?.userId;
        if (!userId) break;

        await prisma.subscription.deleteMany({ where: { userId } });
        await prisma.user.update({
          where: { id: userId },
          data: { plan: "FREE" },
        });
        break;
      }

      case "invoice.payment_failed": {
        const invoice = event.data.object as Stripe.Invoice;
        const userId = invoice.metadata?.userId;
        if (!userId) break;

        await prisma.subscription.update({
          where: { userId },
          data: { status: "unpaid" },
        });
        break;
      }
    }
  } catch (error) {
    console.error("[webhook] processing error", error);
    return NextResponse.json(
      { error: "Failed to process webhook" },
      { status: 500 }
    );
  }

  console.log(`[webhook] event ${event.type} processed successfully`);
  return NextResponse.json({ received: true });
}

export { handler as POST };
