import { NextRequest, NextResponse } from 'next/server';
import { stripe } from '@/shared/billing/stripe-client';
import { createAdminClient } from '@/shared/db/supabase-client';

// --- ASA GENERATED START ---
// Webhook handler for billing/webhook slice.
// ENQUEUE-ONLY PATTERN: verify signature → store event → return 200.
// No inline business logic processing.
// Security: uses req.text() for raw body (NOT req.json()) to preserve Stripe signature.
// --- ASA GENERATED END ---

// --- USER CODE START ---

export async function POST(request: NextRequest): Promise<NextResponse> {
  const signature = request.headers.get('stripe-signature');

  if (!signature) {
    return NextResponse.json({ error: 'Missing stripe-signature header' }, { status: 400 });
  }

  let event;

  try {
    // CRITICAL: Use request.text() — NOT request.json().
    // Stripe signature verification requires the raw body string.
    // Using request.json() parses and re-serializes, breaking the signature.
    const rawBody = await request.text();

    event = stripe.webhooks.constructEvent(
      rawBody,
      signature,
      process.env.STRIPE_WEBHOOK_SECRET!,
    );
  } catch (err) {
    console.error('[billing/webhook] Signature verification failed:', err);
    return NextResponse.json({ error: 'Invalid signature' }, { status: 400 });
  }

  // ENQUEUE: Insert into webhook_events table with status 'pending'.
  // A scheduled processor will handle business logic asynchronously.
  const supabase = createAdminClient();

  const { error: insertError } = await supabase
    .from('webhook_events')
    .upsert(
      {
        stripe_event_id: event.id,
        type: event.type,
        payload: event.data,
        status: 'pending',
        attempt_count: 0,
        received_at: new Date().toISOString(),
      },
      { onConflict: 'stripe_event_id', ignoreDuplicates: true },
    );

  if (insertError) {
    console.error('[billing/webhook] Failed to store event:', insertError);
    // Still return 200 — Stripe will retry if we return error
    // and we don't want to process the same event twice
  }

  // Return 200 immediately — no inline processing
  return NextResponse.json({ received: true });
}

// --- USER CODE END ---
