import { NextRequest, NextResponse } from 'next/server';
import { constructWebhookEvent, stripe } from '@/lib/stripe/server';
import { getSupabaseAdmin } from '@/lib/supabase/server';
import type Stripe from 'stripe';

// Disable body parsing for webhook verification
export const runtime = 'nodejs';
export const dynamic = 'force-dynamic';

export async function POST(request: NextRequest) {
  try {
    // Get the raw body as text for signature verification
    const payload = await request.text();
    const signature = request.headers.get('stripe-signature');

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

    // Verify webhook signature and construct event
    let event: Stripe.Event;
    try {
      event = constructWebhookEvent(payload, signature);
    } catch (error) {
      console.error('Webhook signature verification failed:', error);
      return NextResponse.json({ error: 'Invalid signature' }, { status: 400 });
    }

    const supabaseService = getSupabaseAdmin();

    // Handle specific event types
    switch (event.type) {
      case 'payment_intent.succeeded': {
        const paymentIntent = event.data.object as Stripe.PaymentIntent;
        await handlePaymentSuccess(supabaseService, paymentIntent);
        break;
      }

      case 'payment_intent.payment_failed': {
        const paymentIntent = event.data.object as Stripe.PaymentIntent;
        await handlePaymentFailure(supabaseService, paymentIntent);
        break;
      }

      case 'payment_intent.canceled': {
        const paymentIntent = event.data.object as Stripe.PaymentIntent;
        await handlePaymentCancellation(supabaseService, paymentIntent);
        break;
      }

      default:
        console.log(`Unhandled event type: ${event.type}`);
    }

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

async function handlePaymentSuccess(
  supabase: ReturnType<typeof getSupabaseAdmin>,
  paymentIntent: Stripe.PaymentIntent
) {
  const matchId = paymentIntent.metadata?.match_id;
  
  if (!matchId) {
    console.error('No match_id in payment intent metadata');
    return;
  }

  try {
    // Update payment status to charged
    const { data: payment, error: paymentError } = await supabase
      .from('payments')
      .update({
        status: 'charged',
      })
      .eq('stripe_payment_id', paymentIntent.id)
      .select('id, match_id, company_id')
      .single();

    if (paymentError) {
      console.error('Error updating payment status:', paymentError);
      return;
    }

    if (!payment) {
      console.error('Payment not found for intent:', paymentIntent.id);
      return;
    }

    // Update match status to hired
    const { error: matchError } = await supabase
      .from('matches')
      .update({
        status: 'hired',
        contractor_action: 'accepted',
        hired_at: new Date().toISOString(),
        fee_charged: true,
      })
      .eq('id', matchId);

    if (matchError) {
      console.error('Error updating match status:', matchError);
      return;
    }

    // Create notification for worker
    const { data: match } = await supabase
      .from('matches')
      .select('worker_id, jobs(title)')
      .eq('id', matchId)
      .single();

    if (match) {
      const jobTitle = (match.jobs as { title?: string }).title || 'a job';
      await supabase.from('notifications').insert({
        profile_id: match.worker_id,
        type: 'hire_confirmed',
        title: 'You\'ve been hired!',
        body: `Congratulations! You've been hired for ${jobTitle}.`,
        data: { match_id: matchId, payment_id: payment.id },
      });
    }

    console.log('Payment success processed for match:', matchId);
  } catch (error) {
    console.error('Error processing payment success:', error);
  }
}

async function handlePaymentFailure(
  supabase: ReturnType<typeof getSupabaseAdmin>,
  paymentIntent: Stripe.PaymentIntent
) {
  try {
    const { error } = await supabase
      .from('payments')
      .update({
        status: 'pending', // Keep as pending to allow retry
      })
      .eq('stripe_payment_id', paymentIntent.id);

    if (error) {
      console.error('Error updating payment failure:', error);
    }

    console.log('Payment failed for intent:', paymentIntent.id);
  } catch (error) {
    console.error('Error handling payment failure:', error);
  }
}

async function handlePaymentCancellation(
  supabase: ReturnType<typeof getSupabaseAdmin>,
  paymentIntent: Stripe.PaymentIntent
) {
  try {
    const { error } = await supabase
      .from('payments')
      .delete()
      .eq('stripe_payment_id', paymentIntent.id)
      .eq('status', 'pending');

    if (error) {
      console.error('Error deleting cancelled payment:', error);
    }

    console.log('Payment cancelled for intent:', paymentIntent.id);
  } catch (error) {
    console.error('Error handling payment cancellation:', error);
  }
}
