// server/api/events/[id]/rsvp.post.ts
import { createNocoDBEventsClient } from '~/server/utils/nocodb-events';
import { getMemberByKeycloakId } from '~/server/utils/nocodb';
import { createSessionManager } from '~/server/utils/session';
import type { EventRSVPRequest } from '~/utils/types';

export default defineEventHandler(async (event) => {
  try {
    const eventId = getRouterParam(event, 'id');
    const body = await readBody(event) as EventRSVPRequest;
    
    if (!eventId) {
      throw createError({
        statusCode: 400,
        statusMessage: 'Event ID is required'
      });
    }

    // Get user session using the proper SessionManager
    const sessionManager = createSessionManager();
    const cookieHeader = getHeader(event, 'cookie');
    const session = sessionManager.getSession(cookieHeader);
    
    if (!session || !session.user) {
      throw createError({
        statusCode: 401,
        statusMessage: 'Authentication required'
      });
    }

    const eventsClient = createNocoDBEventsClient();

    // Get the event details
    const eventDetails = await eventsClient.findOne(eventId);
    if (!eventDetails) {
      throw createError({
        statusCode: 404,
        statusMessage: 'Event not found'
      });
    }

    // Check if event is active
    if (eventDetails.status !== 'active') {
      throw createError({
        statusCode: 400,
        statusMessage: 'Cannot RSVP to inactive events'
      });
    }

    // Check if event is in the past
    const eventDate = new Date(eventDetails.start_datetime);
    const now = new Date();
    if (eventDate < now) {
      throw createError({
        statusCode: 400,
        statusMessage: 'Cannot RSVP to past events'
      });
    }

    // Get member details for pricing logic
    const member = await getMemberByKeycloakId(session.user.id);
    if (!member) {
      throw createError({
        statusCode: 404,
        statusMessage: 'Member record not found'
      });
    }

    // Generate payment reference
    const paymentReference = generatePaymentReference(member.member_id || member.Id);

    // Determine pricing and payment status
    let paymentStatus: 'pending' | 'not_required' | 'paid' | 'overdue' = 'not_required';
    let isMemberPricing = 'false';
    
    if (eventDetails.is_paid === 'true' && body.rsvp_status === 'confirmed') {
      paymentStatus = 'pending';
      
      // Check if member qualifies for member pricing
      const isDuesCurrent = member.current_year_dues_paid === 'true';
      const memberPricingEnabled = eventDetails.member_pricing_enabled === 'true';
      
      if (isDuesCurrent && memberPricingEnabled) {
        isMemberPricing = 'true';
      }
    }

    // Validate guest count if event allows guests
    const extraGuests = parseInt((body as any).extra_guests || '0');
    if (extraGuests > 0) {
      if (eventDetails.guests_permitted !== 'true') {
        throw createError({
          statusCode: 400,
          statusMessage: 'This event does not allow guests'
        });
      }
      
      const maxGuestsAllowed = parseInt(eventDetails.max_guests_permitted || '0');
      if (extraGuests > maxGuestsAllowed) {
        throw createError({
          statusCode: 400,
          statusMessage: `Maximum ${maxGuestsAllowed} guests allowed per person`
        });
      }
    }

    // Check event capacity including guests
    if (eventDetails.max_attendees && body.rsvp_status === 'confirmed') {
      const maxCapacity = parseInt(eventDetails.max_attendees);
      const currentAttendees = parseInt(eventDetails.current_attendees || '0');
      const totalRequested = 1 + extraGuests; // Member + guests
      
      if (currentAttendees + totalRequested > maxCapacity) {
        // Auto-set to waitlist if over capacity
        body.rsvp_status = 'waitlist';
        console.log(`[RSVP] Event at capacity, placing on waitlist: ${currentAttendees} + ${totalRequested} > ${maxCapacity}`);
      }
    }

    // Get the event to find the proper event_id for RSVP tracking
    let rsvpEventId = eventId; // Default to the provided eventId
    try {
      // Try to get the event_id field if it exists in the event
      if (eventDetails.event_id) {
        rsvpEventId = eventDetails.event_id;
        console.log('[RSVP] Using event.event_id for RSVP:', rsvpEventId);
      } else {
        console.log('[RSVP] Using provided eventId for RSVP:', rsvpEventId);
      }
    } catch (eventIdError) {
      console.log('[RSVP] Could not get event_id, using provided eventId:', rsvpEventId);
    }

    // Create RSVP record
    const rsvpData = {
      record_type: 'rsvp',
      event_id: rsvpEventId, // Use the business event_id field
      member_id: member.member_id || member.Id,
      rsvp_status: body.rsvp_status,
      payment_status: paymentStatus,
      payment_reference: paymentReference,
      attended: 'false',
      rsvp_notes: body.rsvp_notes || '',
      extra_guests: extraGuests.toString(),
      is_member_pricing: isMemberPricing,
      created_at: new Date().toISOString(),
      updated_at: new Date().toISOString()
    };

    const newRSVP = await eventsClient.createRSVP(rsvpData);

    // Update event attendee count using the new force update method
    try {
      const newAttendeeCount = await eventsClient.forceUpdateEventAttendeeCount(eventId);
      console.log('[RSVP] ✅ Force updated event attendee count for event:', eventId, 'to:', newAttendeeCount);
    } catch (countError) {
      console.log('[RSVP] ⚠️ Failed to force update attendee count:', countError);
      // Don't fail the RSVP creation if count update fails
    }

    // Include payment information in response for paid events
    let responseData: any = newRSVP;
    
    if (eventDetails.is_paid === 'true' && paymentStatus === 'pending') {
      const registrationConfig = await getRegistrationConfig();
      
      responseData = {
        ...newRSVP,
        payment_info: {
          cost: isMemberPricing === 'true' ? 
            eventDetails.cost_members : 
            eventDetails.cost_non_members,
          iban: registrationConfig.iban,
          recipient: registrationConfig.accountHolder,
          reference: paymentReference,
          member_pricing: isMemberPricing === 'true'
        }
      };
    }

    return {
      success: true,
      data: responseData,
      message: (body.rsvp_status as string) === 'waitlist' ? 
        'Added to waitlist - event is full' : 
        'RSVP submitted successfully'
    };

  } catch (error: any) {
    console.error('Error processing RSVP:', error);
    
    if (error.statusCode) {
      throw error;
    }
    
    throw createError({
      statusCode: 500,
      statusMessage: 'Failed to process RSVP'
    });
  }
});

// Helper functions

function generatePaymentReference(memberId: string): string {
  const date = new Date().toISOString().split('T')[0];
  return `EVT-${memberId}-${date}`;
}

async function getRegistrationConfig() {
  // This should fetch from your admin config system
  return {
    iban: 'FR76 1234 5678 9012 3456 7890 123',
    accountHolder: 'MonacoUSA Association'
  };
}

async function updateEventAttendeeCount(eventId: string) {
  console.log('[updateEventAttendeeCount] Updating attendee count for event:', eventId);
  
  try {
    const eventsClient = createNocoDBEventsClient();
    
    // Get all confirmed RSVPs for this event
    const confirmedRSVPs = await eventsClient.getEventRSVPs(eventId, 'confirmed');
    
    // Calculate total attendees (confirmed RSVPs + their guests)
    let totalAttendees = 0;
    
    for (const rsvp of confirmedRSVPs) {
      totalAttendees += 1; // The member themselves
      const guestCount = parseInt(rsvp.extra_guests || '0');
      totalAttendees += guestCount; // Add their guests
    }
    
    console.log('[updateEventAttendeeCount] Calculated total attendees:', totalAttendees, 'from', confirmedRSVPs.length, 'RSVPs');
    
    // Update the event's current_attendees field
    await eventsClient.update(eventId, {
      current_attendees: totalAttendees.toString()
    });
    
    console.log('[updateEventAttendeeCount] ✅ Successfully updated event attendee count to:', totalAttendees);
    
    return totalAttendees;
  } catch (error) {
    console.error('[updateEventAttendeeCount] ❌ Error updating attendee count:', error);
    throw error;
  }
}
