import { NextRequest, NextResponse } from 'next/server';
import { getServiceRoleSupabase } from '@/lib/supabase';
import { verifyWebhookSignature, type NexaPayWebhookEvent, type NexaPayTier } from '@/services/nexapay';
import { sendPaymentReceipt } from '@/services/email';

export const dynamic = 'force-dynamic';
// We need the raw body to verify the HMAC signature.
export const runtime = 'nodejs';

export async function POST(req: NextRequest) {
  const rawBody = await req.text();
  const signature = req.headers.get('x-nexapay-signature');

  if (!verifyWebhookSignature(rawBody, signature)) {
    return NextResponse.json({ error: 'invalid signature' }, { status: 401 });
  }

  let event: NexaPayWebhookEvent;
  try {
    event = JSON.parse(rawBody) as NexaPayWebhookEvent;
  } catch {
    return NextResponse.json({ error: 'invalid body' }, { status: 400 });
  }

  const sb = getServiceRoleSupabase();
  if (!sb) {
    console.error('[nexapay webhook] Supabase service role not configured');
    return NextResponse.json({ error: 'misconfigured' }, { status: 500 });
  }

  const userId = event.data.metadata?.userId;
  const tier = event.data.metadata?.tier as NexaPayTier | undefined;
  const founderPricing = event.data.metadata?.founderPricing === 'true';

  if (!userId || !tier) {
    return NextResponse.json({ ok: true, ignored: 'missing metadata' });
  }

  switch (event.type) {
    case 'payment.succeeded': {
      const subscription_end = new Date();
      subscription_end.setUTCDate(subscription_end.getUTCDate() + 30);

      const { error } = await sb
        .from('user_profiles')
        .update({
          tier,
          subscription_status: 'active',
          subscription_start: new Date().toISOString(),
          subscription_end: subscription_end.toISOString(),
          cancel_at_period_end: false,
          founder_pricing: founderPricing,
          nexapay_customer_id: event.data.customer_id ?? null,
        })
        .eq('id', userId);

      if (error) {
        console.error('[nexapay webhook] update failed', error);
        return NextResponse.json({ error: 'update_failed' }, { status: 500 });
      }

      // Fire-and-forget receipt email. Don't block the webhook ACK.
      const { data: profileRow } = await sb
        .from('user_profiles')
        .select('email')
        .eq('id', userId)
        .maybeSingle();
      if (profileRow?.email) {
        void sendPaymentReceipt(profileRow.email, {
          tier,
          amount: `$${(event.data.amount / 100).toFixed(2)}`,
          renewsAt: subscription_end.toISOString().slice(0, 10),
        });
      }
      break;
    }

    case 'payment.failed': {
      await sb
        .from('user_profiles')
        .update({ subscription_status: 'grace_period' })
        .eq('id', userId);
      break;
    }

    case 'payment.refunded':
    case 'subscription.canceled': {
      await sb
        .from('user_profiles')
        .update({
          subscription_status: 'canceled',
          cancel_at_period_end: true,
        })
        .eq('id', userId);
      break;
    }
  }

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