export const prerender = false;

import type { APIRoute } from 'astro';
import { supabase } from '../../../lib/supabase';
import { requireAuth, getClientIP, checkRateLimit, createAuthResponse } from '../../../lib/auth';
import { validateRequest } from '../../../lib/validation';
import { stripe } from '../../../lib/stripe';
import { z } from 'zod';

// Validation schema for refund requests
const refundSchema = z.object({
  ticket_id: z.string().uuid(),
  refund_amount: z.number().positive().max(10000), // Max $100 refund
  reason: z.string().min(5).max(500) // Reasonable reason length
});

export const POST: APIRoute = async ({ request }) => {
  try {
    // Rate limiting for refund requests
    const clientIP = getClientIP(request);
    if (!checkRateLimit(`refund:${clientIP}`, 3, 300000)) { // 3 requests per 5 minutes
      return createAuthResponse({ error: 'Rate limit exceeded for refund requests' }, 429);
    }

    // Require authentication
    const auth = await requireAuth(request);
    
    const body = await request.json();
    
    // Validate input
    const validation = validateRequest(refundSchema, body);
    if (!validation.success) {
      return createAuthResponse({ 
        error: 'Invalid refund request',
        details: validation.error
      }, 400);
    }

    const { ticket_id, refund_amount, reason } = validation.data;

    // Get ticket with purchase attempt info
    const { data: ticket, error: ticketError } = await supabase
      .from('tickets')
      .select(`
        *,
        purchase_attempts (
          id,
          stripe_payment_intent_id,
          total_amount,
          purchaser_email,
          purchaser_name
        )
      `)
      .eq('id', ticket_id)
      .single();

    if (ticketError || !ticket) {
      return createAuthResponse({ error: 'Ticket not found' }, 404);
    }

    // Check if ticket is already refunded
    if (ticket.refund_status !== 'none') {
      return createAuthResponse({ 
        error: 'Ticket already has a refund request' 
      }, 400);
    }

    // Validate refund amount
    const ticketPrice = parseFloat(ticket.price);
    if (refund_amount > ticketPrice) {
      return createAuthResponse({ 
        error: 'Refund amount cannot exceed ticket price' 
      }, 400);
    }

    // Create refund record
    const { data: refundRecord, error: refundError } = await supabase
      .from('refunds')
      .insert({
        purchase_attempt_id: ticket.purchase_attempt_id,
        ticket_id: ticket_id,
        amount: refund_amount,
        reason: reason,
        status: 'pending',
        processed_by: auth.user.id
      })
      .select()
      .single();

    if (refundError) {
      throw refundError;
    }

    // Update ticket status
    const { error: ticketUpdateError } = await supabase
      .from('tickets')
      .update({
        refund_status: 'requested',
        refund_amount: refund_amount,
        refund_requested_at: new Date().toISOString(),
        refund_reason: reason,
        refunded_by: auth.user.id
      })
      .eq('id', ticket_id);

    if (ticketUpdateError) {
      throw ticketUpdateError;
    }

    // Process Stripe refund if payment intent exists
    let stripeRefund = null;
    if (ticket.purchase_attempts?.stripe_payment_intent_id) {
      try {
        // Update refund status to processing
        await supabase
          .from('refunds')
          .update({ status: 'processing' })
          .eq('id', refundRecord.id);

        await supabase
          .from('tickets')
          .update({ refund_status: 'processing' })
          .eq('id', ticket_id);

        // Create Stripe refund
        stripeRefund = await stripe!.refunds.create({
          payment_intent: ticket.purchase_attempts.stripe_payment_intent_id,
          amount: Math.round(refund_amount * 100), // Convert to cents
          reason: 'requested_by_customer',
          metadata: {
            ticket_id: ticket_id,
            refund_record_id: refundRecord.id,
            reason: reason
          }
        });

        // Update refund with Stripe ID
        await supabase
          .from('refunds')
          .update({ 
            stripe_refund_id: stripeRefund.id,
            status: 'completed',
            processed_at: new Date().toISOString()
          })
          .eq('id', refundRecord.id);

        // Update ticket status to completed
        await supabase
          .from('tickets')
          .update({
            refund_status: 'completed',
            refund_completed_at: new Date().toISOString(),
            stripe_refund_id: stripeRefund.id
          })
          .eq('id', ticket_id);

        // Check if all tickets for this purchase are refunded
        const { data: allTickets } = await supabase
          .from('tickets')
          .select('refund_status')
          .eq('purchase_attempt_id', ticket.purchase_attempt_id);

        if (allTickets && allTickets.every(t => t.refund_status === 'completed')) {
          // Mark entire purchase as fully refunded
          await supabase
            .from('purchase_attempts')
            .update({ 
              refund_status: 'full',
              refund_completed_at: new Date().toISOString()
            })
            .eq('id', ticket.purchase_attempt_id);
        } else if (allTickets && allTickets.some(t => t.refund_status === 'completed')) {
          // Mark purchase as partially refunded
          await supabase
            .from('purchase_attempts')
            .update({ 
              refund_status: 'partial',
              refund_requested_at: new Date().toISOString()
            })
            .eq('id', ticket.purchase_attempt_id);
        }

      } catch (stripeError) {

        // Update refund status to failed
        await supabase
          .from('refunds')
          .update({ status: 'failed' })
          .eq('id', refundRecord.id);

        await supabase
          .from('tickets')
          .update({ refund_status: 'failed' })
          .eq('id', ticket_id);

        return createAuthResponse({ 
          error: 'Failed to process refund with Stripe'
          // Don't expose internal error details
        }, 500);
      }
    }

    return createAuthResponse({
      success: true,
      refund: {
        id: refundRecord.id,
        amount: refund_amount,
        status: stripeRefund ? 'completed' : 'pending',
        stripe_refund_id: stripeRefund?.id
      }
    });

  } catch (error) {

    return createAuthResponse({ 
      error: 'Failed to process refund'
      // Don't expose internal error details in production
    }, 500);
  }
};