// server/api/events/calendar-feed.get.ts
import { createNocoDBEventsClient } from '~/server/utils/nocodb-events';

export default defineEventHandler(async (event) => {
  try {
    const query = getQuery(event);
    const { user_id, user_role, format } = query;
    
    if (!user_id) {
      throw createError({
        statusCode: 400,
        statusMessage: 'User ID is required'
      });
    }

    const eventsClient = createNocoDBEventsClient();
    
    // Get events for the user (next 6 months)
    const now = new Date();
    const sixMonthsLater = new Date();
    sixMonthsLater.setMonth(now.getMonth() + 6);
    
    const filters = {
      start_date: now.toISOString(),
      end_date: sixMonthsLater.toISOString(),
      user_role: (user_role as string) || 'user',
      status: 'active'
    };

    // For now, return empty events array - this should be implemented with actual database queries
    const response = { list: [] };
    const events = response.list || [];

    // Generate iCal content
    const icalContent = generateICalContent(events, {
      calendarName: 'MonacoUSA Events',
      timezone: 'Europe/Paris',
      includeRSVPStatus: true
    });

    // Set appropriate headers for calendar subscription
    setHeader(event, 'Content-Type', 'text/calendar; charset=utf-8');
    setHeader(event, 'Content-Disposition', 'attachment; filename="monacousa-events.ics"');
    setHeader(event, 'Cache-Control', 'no-cache, must-revalidate');
    
    return icalContent;

  } catch (error) {
    console.error('Error generating calendar feed:', error);
    throw createError({
      statusCode: 500,
      statusMessage: 'Failed to generate calendar feed'
    });
  }
});

/**
 * Generate iCal content from events array
 */
function generateICalContent(events: any[], options: {
  calendarName: string;
  timezone: string;
  includeRSVPStatus: boolean;
}): string {
  const now = new Date();
  const lines: string[] = [];
  
  // iCal header
  lines.push('BEGIN:VCALENDAR');
  lines.push('VERSION:2.0');
  lines.push('PRODID:-//MonacoUSA//Portal//EN');
  lines.push(`X-WR-CALNAME:${options.calendarName}`);
  lines.push(`X-WR-TIMEZONE:${options.timezone}`);
  lines.push('X-WR-CALDESC:Events from MonacoUSA Portal');
  lines.push('CALSCALE:GREGORIAN');
  lines.push('METHOD:PUBLISH');
  
  // Add timezone definition
  lines.push('BEGIN:VTIMEZONE');
  lines.push(`TZID:${options.timezone}`);
  lines.push('BEGIN:STANDARD');
  lines.push('DTSTART:19701025T030000');
  lines.push('RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU');
  lines.push('TZNAME:CET');
  lines.push('TZOFFSETFROM:+0200');
  lines.push('TZOFFSETTO:+0100');
  lines.push('END:STANDARD');
  lines.push('BEGIN:DAYLIGHT');
  lines.push('DTSTART:19700329T020000');
  lines.push('RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU');
  lines.push('TZNAME:CEST');
  lines.push('TZOFFSETFROM:+0100');
  lines.push('TZOFFSETTO:+0200');
  lines.push('END:DAYLIGHT');
  lines.push('END:VTIMEZONE');

  // Process each event
  events.forEach(eventItem => {
    if (!eventItem.start_datetime || !eventItem.end_datetime) return;
    
    const startDate = new Date(eventItem.start_datetime);
    const endDate = new Date(eventItem.end_datetime);
    const createdDate = eventItem.created_at ? new Date(eventItem.created_at) : now;
    const modifiedDate = eventItem.updated_at ? new Date(eventItem.updated_at) : now;
    
    lines.push('BEGIN:VEVENT');
    lines.push(`UID:${eventItem.id}@monacousa.org`);
    lines.push(`DTSTART;TZID=${options.timezone}:${formatICalDateTime(startDate)}`);
    lines.push(`DTEND;TZID=${options.timezone}:${formatICalDateTime(endDate)}`);
    lines.push(`DTSTAMP:${formatICalDateTime(now)}`);
    lines.push(`CREATED:${formatICalDateTime(createdDate)}`);
    lines.push(`LAST-MODIFIED:${formatICalDateTime(modifiedDate)}`);
    lines.push(`SUMMARY:${escapeICalText(eventItem.title)}`);
    
    // Add description with event details
    let description = eventItem.description || '';
    if (eventItem.is_paid === 'true') {
      description += `\\n\\nEvent Fee: €${eventItem.cost_members || eventItem.cost_non_members || 'TBD'}`;
      if (eventItem.cost_members && eventItem.cost_non_members) {
        description += ` (Members: €${eventItem.cost_members}, Non-members: €${eventItem.cost_non_members})`;
      }
    }
    
    // Add RSVP status if available
    if (options.includeRSVPStatus && eventItem.user_rsvp) {
      const rsvpStatus = eventItem.user_rsvp.rsvp_status;
      description += `\\n\\nRSVP Status: ${rsvpStatus.toUpperCase()}`;
      
      if (rsvpStatus === 'confirmed' && eventItem.user_rsvp.payment_reference) {
        description += `\\nPayment Reference: ${eventItem.user_rsvp.payment_reference}`;
      }
    }
    
    if (description) {
      lines.push(`DESCRIPTION:${escapeICalText(description)}`);
    }
    
    // Add location
    if (eventItem.location) {
      lines.push(`LOCATION:${escapeICalText(eventItem.location)}`);
    }
    
    // Add categories based on event type
    const eventTypeLabels = {
      'meeting': 'Meeting',
      'social': 'Social Event',
      'fundraiser': 'Fundraiser',
      'workshop': 'Workshop',
      'board-only': 'Board Meeting'
    };
    const category = eventTypeLabels[eventItem.event_type as keyof typeof eventTypeLabels] || 'Event';
    lines.push(`CATEGORIES:${category}`);
    
    // Add status
    let eventStatus = 'CONFIRMED';
    if (eventItem.status === 'cancelled') {
      eventStatus = 'CANCELLED';
    } else if (eventItem.status === 'draft') {
      eventStatus = 'TENTATIVE';
    }
    lines.push(`STATUS:${eventStatus}`);
    
    // Add transparency for paid events
    if (eventItem.is_paid === 'true') {
      lines.push('TRANSP:OPAQUE');
    } else {
      lines.push('TRANSP:TRANSPARENT');
    }
    
    // Add URL (link back to portal)
    lines.push(`URL:https://portal.monacousa.org/dashboard/events`);
    
    lines.push('END:VEVENT');
  });

  // iCal footer
  lines.push('END:VCALENDAR');
  
  // Join with CRLF as per RFC 5545
  return lines.join('\r\n');
}

/**
 * Format date for iCal (YYYYMMDDTHHMMSS format)
 */
function formatICalDateTime(date: Date): string {
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  const hours = String(date.getHours()).padStart(2, '0');
  const minutes = String(date.getMinutes()).padStart(2, '0');
  const seconds = String(date.getSeconds()).padStart(2, '0');
  
  return `${year}${month}${day}T${hours}${minutes}${seconds}`;
}

/**
 * Escape special characters for iCal text fields
 */
function escapeICalText(text: string): string {
  if (!text) return '';
  
  return text
    .replace(/\\/g, '\\\\')  // Escape backslashes
    .replace(/;/g, '\\;')    // Escape semicolons
    .replace(/,/g, '\\,')    // Escape commas
    .replace(/\n/g, '\\n')   // Escape newlines
    .replace(/\r/g, '')      // Remove carriage returns
    .replace(/"/g, '\\"');   // Escape quotes
}
