import { NextRequest, NextResponse } from 'next/server';
import { logger } from '@/lib/logger';
import { stripe } from '@/lib/stripe/server';
import { getSupabaseAdmin } from '@/lib/supabase/server';
import { HTTP_STATUS_INTERNAL_SERVER_ERROR } from '@/lib/constants';
import { sendEmail, EMAIL_TEMPLATES } from '@/lib/email';
import { checkRateLimit, getClientIP, createRateLimitResponse } from '@/lib/rate-limit';

// Rate limit: 3 refund requests per 10 minutes
const REFUND_RATE_LIMIT = 3;
const REFUND_WINDOW_MS = 10 * 60 * 1000;

/**
 * POST /api/payments/refund
 * 
 * Process a refund for a no-show or disputed hire.
 * Admin only (CEO PIN auth).
 * 
 * Body: { match_id: string, reason?: string }
 * 
 * Refund policy:
 * - No-show: Full refund of $50 hire fee
 * - First-hire guarantee: Full refund if first hire doesn't work out
 * - All other: Admin discretion
 */
export async function POST(request: NextRequest) {
  try {
    const clientIP = getClientIP(request);
    const rateLimit = await checkRateLimit(`refund:${clientIP}`, REFUND_RATE_LIMIT, REFUND_WINDOW_MS);
    if (!rateLimit.allowed) {
      const retryAfter = Math.ceil((rateLimit.resetTime - Date.now()) / 1000);
      return createRateLimitResponse(clientIP, retryAfter);
    }

    const pin = request.headers.get('x-ceo-pin');
    if (pin !== '5050') {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const { match_id: matchId, reason } = await request.json();
    if (!matchId) {
      return NextResponse.json({ error: 'Missing match_id' }, { status: 400 });
    }

    const admin = getSupabaseAdmin();

    // Get payment record
    const { data: payment, error: payErr } = await admin
      .from('payments')
      .select('id, match_id, company_id, amount, status, stripe_payment_id')
      .eq('match_id', matchId)
      .eq('status', 'charged')
      .single();

    if (payErr || !payment) {
      return NextResponse.json(
        { error: 'No charged payment found for this match' },
        { status: 404 }
      );
    }

    // Verify stripe_payment_id is a real PI (not a placeholder)
    if (!payment.stripe_payment_id || payment.stripe_payment_id.startsWith('checkout_')) {
      return NextResponse.json(
        { error: 'Payment has no valid Stripe payment intent — cannot refund' },
        { status: 400 }
      );
    }

    // Process refund via Stripe
    let refund;
    try {
      refund = await stripe.refunds.create({
        payment_intent: payment.stripe_payment_id,
        reason: 'requested_by_customer',
        metadata: {
          match_id: matchId,
          refund_reason: reason || 'no-show',
          refunded_by: 'admin',
        },
      });
    } catch (stripeErr) {
      logger.error('Stripe refund failed:', stripeErr);
      return NextResponse.json(
        { error: 'Stripe refund failed. Check Stripe dashboard.' },
        { status: 502 }
      );
    }

    // Update payment record
    const { error: updateErr } = await admin
      .from('payments')
      .update({
        status: 'refunded',
      })
      .eq('id', payment.id);

    if (updateErr) {
      logger.error('Failed to update payment status after refund:', updateErr);
      // Don't fail — Stripe refund already processed
    }

    // Get contractor details for notification
    const { data: company } = await admin
      .from('companies')
      .select('name, profile_id, profiles!inner(email, name)')
      .eq('id', payment.company_id)
      .single();

    // Email contractor about refund
    if (company) {
      const profile = company.profiles as unknown as { email: string; name: string };
      if (profile?.email) {
        try {
          const refundReason = reason || 'Worker no-show';
          await sendEmail(
            profile.email,
            'RateRight — Your $50 Hire Fee Has Been Refunded',
            `
            <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
              <h2 style="color: #1a1a1a;">Refund Processed ✅</h2>
              <p>Hi ${profile.name || 'there'},</p>
              <p>We've processed a full refund of <strong>$50.00 AUD</strong> for your hire fee.</p>
              <p><strong>Reason:</strong> ${refundReason}</p>
              <p><strong>Refund ID:</strong> ${refund.id}</p>
              <p>The refund should appear on your statement within 5-10 business days.</p>
              <p>We're sorry for the inconvenience. If you'd like to find another worker, head back to 
                <a href="https://rateright.com.au/dashboard" style="color: #2563eb;">your dashboard</a>.
              </p>
              <br/>
              <p style="color: #666; font-size: 12px;">
                RateRight Pty Ltd | ABN 88 688 279 769<br/>
                This is not a tax invoice.
              </p>
            </div>
            `
          );
        } catch (emailErr) {
          logger.error('Refund email failed:', emailErr);
        }
      }
    }

    // Create notification for contractor
    if (company) {
      const profile = company.profiles as unknown as { email: string; name: string };
      await admin.from('notifications').insert({
        profile_id: company.profile_id,
        type: 'system',
        title: 'Refund Processed',
        body: `Your $50 hire fee has been refunded. Reason: ${reason || 'Worker no-show'}. It should appear on your statement within 5-10 business days.`,
        data: { matchId, refundId: refund.id, type: 'refund' },
      });
    }

    logger.info('Refund processed', {
      matchId,
      paymentId: payment.id,
      refundId: refund.id,
      amount: payment.amount,
      reason: reason || 'no-show',
    });

    return NextResponse.json({
      success: true,
      refund_id: refund.id,
      amount: payment.amount,
      status: refund.status,
    });
  } catch (error) {
    logger.error('Refund error:', error);
    return NextResponse.json(
      { error: 'Failed to process refund' },
      { status: HTTP_STATUS_INTERNAL_SERVER_ERROR }
    );
  }
}
