import { NextRequest, NextResponse } from 'next/server';
import { stripe } from '@/lib/stripe';
import { db, schema } from '@/lib/db';
import { eq } from 'drizzle-orm';
import { suspendCompany, reactivateCompany } from '@/lib/companies';
import type Stripe from 'stripe';

export const runtime = 'nodejs';

/**
 * POST /api/billing/webhook
 * Receives Stripe events and updates billing record statuses.
 */
export async function POST(request: NextRequest) {
  const sig = request.headers.get('stripe-signature');
  const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;

  if (!sig || !webhookSecret) {
    return NextResponse.json({ error: 'Missing signature' }, { status: 400 });
  }

  let event: Stripe.Event;
  try {
    const body = await request.text();
    event = stripe.webhooks.constructEvent(body, sig, webhookSecret);
  } catch (err) {
    console.error('Webhook signature verification failed:', err);
    return NextResponse.json({ error: 'Invalid signature' }, { status: 400 });
  }

  try {
    switch (event.type) {
      case 'payment_intent.succeeded': {
        const pi = event.data.object as Stripe.PaymentIntent;

        await db.update(schema.billingRecords)
          .set({ status: 'charged' })
          .where(eq(schema.billingRecords.stripePaymentIntentId, pi.id));

        // Lift any suspension now that the outstanding charge cleared.
        // The invoice itself is issued in processOwnerMonthlyBilling on the
        // synchronous charge; this is the async backstop for reactivation.
        const companyId = pi.metadata?.companyId;
        if (companyId) {
          await reactivateCompany(companyId).catch((e) => console.error('[webhook] reactivate failed:', e));
        }
        break;
      }
      case 'payment_intent.payment_failed': {
        const pi = event.data.object as Stripe.PaymentIntent;
        const errorMsg = pi.last_payment_error?.message ?? 'Payment failed';
        await db.update(schema.billingRecords)
          .set({ status: 'failed', errorMessage: errorMsg })
          .where(eq(schema.billingRecords.stripePaymentIntentId, pi.id));

        // Suspend the company until the invoice is settled.
        const companyId = pi.metadata?.companyId;
        if (companyId) {
          await suspendCompany(companyId, `Monthly payment failed: ${errorMsg}`)
            .catch((e) => console.error('[webhook] suspend failed:', e));
        }
        break;
      }
      default:
        break;
    }
  } catch (err) {
    console.error('Webhook handler error:', err);
    return NextResponse.json({ error: 'Handler error' }, { status: 500 });
  }

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