import { getSupabaseAdmin, createClient } from '@/lib/supabase/server';
import { NextRequest, NextResponse } from 'next/server';
import { checkRateLimit, getClientIP, createRateLimitResponse } from '@/lib/rate-limit';
import { createPaymentIntent } from '@/lib/stripe/server';
import { withCSRFProtection } from '@/lib/csrf';

// Rate limit: 10 requests per 15 minutes per user (sensitive financial operation)
const PAYMENT_RATE_LIMIT = 10;
const PAYMENT_WINDOW_MS = 15 * 60 * 1000;

const handler = async (request: NextRequest) => {
  try {
    // --- Rate limiting (by IP as initial check) ---
    const clientIP = getClientIP(request);
    const ipRateLimit = checkRateLimit(`payment-ip:${clientIP}`, PAYMENT_RATE_LIMIT, PAYMENT_WINDOW_MS);
    
    if (!ipRateLimit.allowed) {
      const retryAfter = Math.ceil((ipRateLimit.resetTime - Date.now()) / 1000);
      return createRateLimitResponse(clientIP, retryAfter);
    }
    
    const supabase = await createClient();
    const {
      data: { user },
    } = await supabase.auth.getUser();
    
    if (!user) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }
    
    // --- Stricter rate limiting by user ID ---
    const userRateLimit = checkRateLimit(`payment-user:${user.id}`, PAYMENT_RATE_LIMIT, PAYMENT_WINDOW_MS);
    
    if (!userRateLimit.allowed) {
      const retryAfter = Math.ceil((userRateLimit.resetTime - Date.now()) / 1000);
      return createRateLimitResponse(user.id, retryAfter);
    }

    const body = await request.json();
    const { match_id, company_id } = body;
    const amount = 50.0; // Hardcoded amount to prevent client override

    if (!match_id || !company_id) {
      return NextResponse.json({ error: 'Missing required fields' }, { status: 400 });
    }

    // Verify user owns the company
    const { data: company } = await supabase
      .from('companies')
      .select('id, name')
      .eq('id', company_id)
      .eq('profile_id', user.id)
      .single();

    if (!company) {
      return NextResponse.json({ error: 'Company not found or unauthorized' }, { status: 403 });
    }

    // Verify match exists and belongs to company's job (can be in any status except rejected)
    const { data: match } = await supabase
      .from('matches')
      .select('status, jobs!inner(company_id, title)')
      .eq('id', match_id)
      .neq('status', 'rejected')
      .eq('jobs.company_id', company_id)
      .single();

    if (!match) {
      return NextResponse.json({ error: 'Match not found, already rejected, or unauthorized' }, { status: 403 });
    }

    // Check if payment already exists for this match
    const { data: existingPayment } = await supabase
      .from('payments')
      .select('id, status, stripe_payment_id')
      .eq('match_id', match_id)
      .single();

    if (existingPayment?.status === 'charged') {
      return NextResponse.json({ error: 'Payment already completed for this hire' }, { status: 400 });
    }

    // Create Stripe PaymentIntent
    const jobTitle = (match.jobs as { title?: string }).title || 'Job';
    const { clientSecret, paymentIntentId } = await createPaymentIntent({
      amount,
      matchId: match_id,
      companyId: company_id,
      companyName: company.name,
      description: `Hire for ${jobTitle}`,
    });

    // Create or update payment record using service role
    const supabaseService = getSupabaseAdmin();
    
    let payment;
    if (existingPayment) {
      // Update existing payment record with new PaymentIntent
      const { data: updatedPayment, error } = await supabaseService
        .from('payments')
        .update({
          stripe_payment_id: paymentIntentId,
          amount,
          status: 'pending',
        })
        .eq('id', existingPayment.id)
        .select()
        .single();
      
      if (error) {
        return NextResponse.json({ error: error.message }, { status: 500 });
      }
      payment = updatedPayment;
    } else {
      // Create new payment record
      const { data: newPayment, error } = await supabaseService
        .from('payments')
        .insert({
          match_id,
          company_id,
          amount,
          status: 'pending',
          stripe_payment_id: paymentIntentId,
        })
        .select()
        .single();

      if (error) {
        return NextResponse.json({ error: error.message }, { status: 500 });
      }
      payment = newPayment;
    }

    return NextResponse.json({ 
      payment,
      clientSecret,
      publishableKey: process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY,
    });
  } catch (error) {
    console.error('Payment creation error:', error);
    if (error instanceof Error && error.message.includes('Stripe')) {
      return NextResponse.json({ error: 'Payment service unavailable' }, { status: 503 });
    }
    return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
  }
}

// Apply CSRF protection to the handler
export const POST = withCSRFProtection(handler);
