import { NextRequest, NextResponse } from 'next/server';
import { headers } from 'next/headers';
import { stripe } from '@/lib/stripe';
import { db } from '@/lib/db';
import Stripe from 'stripe';

export async function POST(request: NextRequest) {
  const body = await request.text();
  const signature = headers().get('stripe-signature');

  if (!signature) {
    return NextResponse.json(
      { error: 'No signature' },
      { status: 400 }
    );
  }

  let event: Stripe.Event;

  try {
    event = stripe.webhooks.constructEvent(
      body,
      signature,
      process.env.STRIPE_WEBHOOK_SECRET!
    );
  } catch (error) {
    console.error('Webhook signature verification failed:', error);
    return NextResponse.json(
      { error: 'Invalid signature' },
      { status: 400 }
    );
  }

  try {
    switch (event.type) {
      case 'checkout.session.completed': {
        const session = event.data.object as Stripe.Checkout.Session;

        if (session.mode === 'subscription') {
          const subscription: any = await stripe.subscriptions.retrieve(
            session.subscription as string
          );

          const periodEndTimestamp = subscription.current_period_end
            || subscription.currentPeriodEnd
            || subscription.billing_cycle_anchor;

          const currentPeriodEnd = periodEndTimestamp
            ? new Date(periodEndTimestamp * 1000)
            : new Date(Date.now() + 30 * 24 * 60 * 60 * 1000);

          await db.user.update({
            where: {
              stripeCustomerId: session.customer as string,
            },
            data: {
              stripeSubscriptionId: subscription.id,
              stripePriceId: subscription.items.data[0].price.id,
              stripeCurrentPeriodEnd: currentPeriodEnd,
              plan: (session.metadata?.plan || 'FREE') as any,
            },
          });
        }
        break;
      }

      case 'customer.subscription.updated': {
        const subscription: any = event.data.object as Stripe.Subscription;

        const periodEndTimestamp = subscription.current_period_end
          || subscription.currentPeriodEnd
          || subscription.billing_cycle_anchor;

        const currentPeriodEnd = periodEndTimestamp
          ? new Date(periodEndTimestamp * 1000)
          : new Date(Date.now() + 30 * 24 * 60 * 60 * 1000);

        await db.user.update({
          where: {
            stripeSubscriptionId: subscription.id,
          },
          data: {
            stripePriceId: subscription.items.data[0].price.id,
            stripeCurrentPeriodEnd: currentPeriodEnd,
          },
        });
        break;
      }

      case 'customer.subscription.deleted': {
        const subscription = event.data.object as Stripe.Subscription;

        await db.user.update({
          where: {
            stripeSubscriptionId: subscription.id,
          },
          data: {
            stripeSubscriptionId: null,
            stripePriceId: null,
            stripeCurrentPeriodEnd: null,
            plan: 'FREE',
          },
        });
        break;
      }
    }

    return NextResponse.json({ received: true });
  } catch (error) {
    console.error('Error processing webhook:', error);
    return NextResponse.json(
      { error: 'Webhook processing failed' },
      { status: 500 }
    );
  }
}
