// server/utils/nocodb-events.ts
import type { Event, EventRSVP, EventsResponse, EventFilters } from '~/utils/types';
import { createSessionManager } from '~/server/utils/session';
import { getEffectiveNocoDBConfig } from './admin-config';

// Import shared NocoDB utilities from the working members system
import { getNocoDbConfiguration, setGlobalNocoDBConfig, handleNocoDbError } from '~/server/utils/nocodb';

// Define interfaces for API responses
interface EventsListResponse {
  list: Event[];
  PageInfo: {
    pageSize: number;
    totalRows: number;
    isFirstPage: boolean;
    isLastPage: boolean;
    page: number;
  };
}

// Table ID enumeration for Events (similar to Members table pattern)
export enum EventTable {
  Events = "events-table-id", // Will be configured via admin panel
  EventRSVPs = "rsvps-table-id" // Separate table for RSVPs
}

// Dynamic table ID getter - will use configured table ID from admin panel
export const getEventTableId = (tableName: 'Events' | 'EventRSVPs'): string => {
  console.log(`[nocodb-events] 🔍 DEBUG: Getting table ID for ${tableName}...`);
  
  try {
    // Try to get effective configuration from admin config system first
    const effectiveConfig = getEffectiveNocoDBConfig();
    console.log(`[nocodb-events] 🔍 DEBUG: Effective config:`, JSON.stringify(effectiveConfig, null, 2));
    
    if (effectiveConfig?.tables) {
      console.log(`[nocodb-events] 🔍 DEBUG: Available table keys:`, Object.keys(effectiveConfig.tables));
      
      if (tableName === 'Events') {
        // Check multiple possible keys for Events table
        const eventsTableId = effectiveConfig.tables['events'] || 
                            effectiveConfig.tables['Events'] || 
                            effectiveConfig.tables['events_table'];
        if (eventsTableId) {
          console.log(`[nocodb-events] ✅ Using admin config table ID for ${tableName}:`, eventsTableId);
          return eventsTableId;
        } else {
          console.log(`[nocodb-events] ⚠️ No Events table ID found in config`);
        }
      } else if (tableName === 'EventRSVPs') {
        // Check multiple possible keys for RSVP table
        const rsvpTableId = effectiveConfig.tables['rsvps'] || 
                          effectiveConfig.tables['event_rsvps'] || 
                          effectiveConfig.tables['EventRSVPs'] ||
                          effectiveConfig.tables['rsvp_table'] ||
                          effectiveConfig.tables['RSVPs'];
        if (rsvpTableId) {
          console.log(`[nocodb-events] ✅ Using admin config table ID for ${tableName}:`, rsvpTableId);
          return rsvpTableId;
        } else {
          console.log(`[nocodb-events] ⚠️ No RSVP table ID found in config. Checking individual keys:`);
          console.log(`[nocodb-events] 🔍 rsvps:`, effectiveConfig.tables['rsvps']);
          console.log(`[nocodb-events] 🔍 event_rsvps:`, effectiveConfig.tables['event_rsvps']);
          console.log(`[nocodb-events] 🔍 EventRSVPs:`, effectiveConfig.tables['EventRSVPs']);
        }
      }
    } else {
      console.log(`[nocodb-events] ⚠️ No tables configuration found in effective config`);
    }
  } catch (error) {
    console.log(`[nocodb-events] ❌ Admin config error for ${tableName}:`, error);
  }

  // Try to get table ID from global configuration  
  const globalConfig = (global as any).globalNocoDBConfig;
  if (globalConfig?.tables) {
    if (tableName === 'Events') {
      const eventsTableId = globalConfig.tables['events'] || globalConfig.tables['Events'];
      if (eventsTableId) {
        console.log(`[nocodb-events] Using global table ID for ${tableName}:`, eventsTableId);
        return eventsTableId;
      }
    } else if (tableName === 'EventRSVPs') {
      const rsvpTableId = globalConfig.tables['rsvps'] || 
                        globalConfig.tables['event_rsvps'] || 
                        globalConfig.tables['EventRSVPs'];
      if (rsvpTableId) {
        console.log(`[nocodb-events] Using global table ID for ${tableName}:`, rsvpTableId);
        return rsvpTableId;
      }
    }
  }
  
  // Try runtime config as fallback
  const config = useRuntimeConfig();
  if (tableName === 'Events' && config.nocodb?.eventsTableId) {
    console.log(`[nocodb-events] Using runtime config table ID for ${tableName}:`, config.nocodb.eventsTableId);
    return config.nocodb.eventsTableId;
  }
  
  // Final fallback to default
  const defaultTableId = tableName === 'Events' ? 'mp3wigub1fzdo1b' : 'mt1mx3vkcw0vbmh';
  console.log(`[nocodb-events] Using fallback table ID for ${tableName}:`, defaultTableId);
  return defaultTableId;
};

export const createEventTableUrl = (table: EventTable | string) => {
  let tableId: string;
  
  if (table === EventTable.Events || table === 'Events') {
    tableId = getEventTableId('Events');
  } else if (table === EventTable.EventRSVPs || table === 'EventRSVPs') {
    tableId = getEventTableId('EventRSVPs');
  } else {
    tableId = table.toString();
  }
  
  const url = `${getNocoDbConfiguration().url}/api/v2/tables/${tableId}/records`;
  console.log('[nocodb-events] Event table URL:', url);
  return url;
};

// Event field normalization (similar to member normalization)
export const normalizeEventFieldsFromNocoDB = (data: any): Event => {
  console.log('[normalizeEventFieldsFromNocoDB] Input event keys:', Object.keys(data));
  
  const normalized: any = { ...data };
  
  // Field mapping for event data (adjust based on your actual NocoDB schema)
  const eventFieldMap: Record<string, string> = {
    'Title': 'title',
    'Description': 'description',
    'Event Type': 'event_type',
    'Event ID': 'event_id',
    'Start Date': 'start_datetime',
    'End Date': 'end_datetime',
    'Location': 'location',
    'Visibility': 'visibility',
    'Status': 'status',
    'Creator': 'creator',
    'Max Attendees': 'max_attendees',
    'Is Paid': 'is_paid',
    'Cost Members': 'cost_members',
    'Cost Non Members': 'cost_non_members',
    // Handle snake_case fields (in case they come in already normalized)
    'title': 'title',
    'description': 'description',
    'event_type': 'event_type',
    'event_id': 'event_id',
    'start_datetime': 'start_datetime',
    'end_datetime': 'end_datetime',
    'location': 'location',
    'visibility': 'visibility',
    'status': 'status',
    'creator': 'creator',
    'max_attendees': 'max_attendees',
    'is_paid': 'is_paid',
    'cost_members': 'cost_members',
    'cost_non_members': 'cost_non_members'
  };
  
  // Apply field mapping
  for (const [sourceKey, targetKey] of Object.entries(eventFieldMap)) {
    if (sourceKey in data && data[sourceKey] !== undefined && data[sourceKey] !== null) {
      normalized[targetKey] = data[sourceKey];
      console.log(`[normalizeEventFieldsFromNocoDB] Mapped "${sourceKey}" -> "${targetKey}":`, data[sourceKey]);
    }
  }
  
  // Ensure required fields exist with fallbacks
  normalized.title = normalized.title || normalized['Title'] || '';
  normalized.status = normalized.status || normalized['Status'] || 'active';
  normalized.visibility = normalized.visibility || normalized['Visibility'] || 'public';
  
  console.log('[normalizeEventFieldsFromNocoDB] Final normalized event keys:', Object.keys(normalized));
  return normalized as Event;
};

// RSVP table configuration
// Note: The RSVP table should be created in NocoDB with the following fields:
// - Id (Auto Number, Primary Key)
// - event_id (Single Line Text) 
// - member_id (Single Line Text)
// - rsvp_status (Single Select: confirmed, declined, pending, waitlist)
// - payment_status (Single Select: not_required, pending, paid, overdue)
// - payment_reference (Single Line Text)
// - attended (Checkbox)
// - rsvp_notes (Long Text)
// - is_member_pricing (Checkbox)
// - CreatedAt (DateTime)
// - UpdatedAt (DateTime)

/**
 * Creates a client for interacting with the Events NocoDB table
 * Following the same pattern as the working members client
 */
export function createNocoDBEventsClient() {
  // Use the centralized configuration from nocodb.ts which now prioritizes environment variables
  const config = getNocoDbConfiguration();
  console.log('[nocodb-events] ✅ Using NocoDB configuration (prioritizes environment variables)');

  const eventsClient = {
    /**
     * Find all events with optional filtering
     */
    async findAll(filters?: EventFilters & { limit?: number; offset?: number }): Promise<EventsListResponse> {
      console.log('[nocodb-events] 🔍 DEBUG: Filters received:', filters);
      const startTime = Date.now();
      
      try {
        // Build query parameters like the members system
        const params: Record<string, any> = {
          limit: filters?.limit || 1000,
        };
        
        if (filters?.offset) {
          params.offset = filters.offset;
        }
        
        // Simple status filtering (like members system)
        if (filters?.status) {
          console.log('[nocodb-events] 🔍 Adding status filter:', filters.status);
          params.where = `(status,eq,${filters.status})`;
        } else {
          console.log('[nocodb-events] 🔍 No status filter - fetching all records');
        }
        
        // TEMPORARILY DISABLE COMPLEX FILTERING TO ISOLATE ISSUE
        console.log('[nocodb-events] ⚠️ Temporarily skipping date/role/search filtering to isolate issue');
        
        // TEMPORARILY DISABLE SORTING TO ISOLATE ISSUE  
        console.log('[nocodb-events] ⚠️ Also temporarily skipping sorting to isolate issue');
        
        const url = createEventTableUrl(EventTable.Events);
        
        const result = await $fetch<EventsListResponse>(url, {
          headers: {
            "xc-token": getNocoDbConfiguration().token,
          },
          params
        });
        
        console.log('[nocodb-events] ✅ Successfully fetched events, count:', result.list?.length || 0);
        console.log('[nocodb-events] Request duration:', Date.now() - startTime, 'ms');
        
        // Apply field normalization like members system
        if (result.list) {
          result.list = result.list.map(normalizeEventFieldsFromNocoDB);
          
          // Update attendee counts for all events
          result.list = await Promise.all(
            result.list.map(async (event) => {
              try {
                const eventId = event.event_id || event.id || (event as any).Id;
                const updatedCount = await this.calculateEventAttendeeCount(eventId.toString());
                return {
                  ...event,
                  current_attendees: updatedCount.toString()
                };
              } catch (error) {
                console.log('[nocodb-events] ⚠️ Failed to calculate attendee count for event:', event.title, error);
                return event; // Return original if calculation fails
              }
            })
          );
        }
        
        return result;
      } catch (error: any) {
        console.error('[nocodb-events] ❌ Error fetching events:', error);
        handleNocoDbError(error, 'getEvents', 'Events');
        throw error;
      }
    },

    /**
     * Find a single event by ID (supports both database Id and business event_id)
     */
    async findOne(id: string) {
      console.log('[nocodb-events] Fetching event ID:', id);
      
      try {
        // First, try to fetch by database Id (numeric)
        if (/^\d+$/.test(id)) {
          console.log('[nocodb-events] Using database Id lookup for:', id);
          const result = await $fetch<Event>(`${createEventTableUrl(EventTable.Events)}/${id}`, {
            headers: {
              "xc-token": getNocoDbConfiguration().token,
            },
          });
          
          console.log('[nocodb-events] Successfully retrieved event by database Id:', result.id || (result as any).Id);
          return normalizeEventFieldsFromNocoDB(result);
        }
        
        // Otherwise, search by business event_id
        console.log('[nocodb-events] Using event_id lookup for:', id);
        const results = await $fetch<{list: Event[]}>(`${createEventTableUrl(EventTable.Events)}`, {
          headers: {
            "xc-token": getNocoDbConfiguration().token,
          },
          params: {
            where: `(event_id,eq,${id})`,
            limit: 1
          }
        });
        
        if (results.list && results.list.length > 0) {
          console.log('[nocodb-events] Successfully found event by event_id:', results.list[0].id || (results.list[0] as any).Id);
          return normalizeEventFieldsFromNocoDB(results.list[0]);
        }
        
        console.log('[nocodb-events] No event found with event_id:', id);
        throw createError({
          statusCode: 404,
          statusMessage: 'Event not found'
        });
      } catch (error: any) {
        console.error('[nocodb-events] Error fetching event:', error);
        if (error.statusCode === 404) {
          throw error; // Re-throw 404 errors as-is
        }
        handleNocoDbError(error, 'getEventById', 'Event');
        throw error;
      }
    },

    /**
     * Create a new event
     */
    async create(eventData: Partial<Event>) {
      console.log('[nocodb-events] Creating event with fields:', Object.keys(eventData));
      
      try {
        // Clean data like members system
        const cleanData: Record<string, any> = {};
        
        // Only include allowed event fields
        const allowedFields = [
          "title", "description", "event_type", "event_id", "start_datetime", "end_datetime",
          "location", "is_recurring", "recurrence_pattern", "max_attendees", 
          "is_paid", "cost_members", "cost_non_members", "member_pricing_enabled",
          "guests_permitted", "max_guests_permitted",
          "visibility", "status", "creator", "current_attendees"
        ];
        
        for (const field of allowedFields) {
          if (field in eventData && eventData[field as keyof Event] !== undefined) {
            cleanData[field] = eventData[field as keyof Event];
          }
        }
        
        // Generate unique event_id if not provided
        if (!cleanData.event_id) {
          const timestamp = Date.now();
          const randomString = Math.random().toString(36).substring(2, 8);
          cleanData.event_id = `evt_${timestamp}_${randomString}`;
          console.log('[nocodb-events] Generated event_id:', cleanData.event_id);
        }
        
        // Set defaults
        cleanData.status = cleanData.status || 'active';
        cleanData.visibility = cleanData.visibility || 'public';
        cleanData.current_attendees = cleanData.current_attendees || '0';
        
        console.log('[nocodb-events] Clean event data fields:', Object.keys(cleanData));
        
        const result = await $fetch<Event>(createEventTableUrl(EventTable.Events), {
          method: "POST",
          headers: {
            "xc-token": getNocoDbConfiguration().token,
          },
          body: cleanData,
        });
        
        console.log('[nocodb-events] Created event with ID:', result.id || (result as any).Id);
        return normalizeEventFieldsFromNocoDB(result);
      } catch (error: any) {
        console.error('[nocodb-events] Create event failed:', error);
        handleNocoDbError(error, 'createEvent', 'Event');
        throw error;
      }
    },

    /**
     * Update an existing event
     */
    async update(id: string, eventData: Partial<Event>) {
      console.log('[nocodb-events] Updating event:', id);
      
      try {
        // Clean data like members system
        const cleanData: Record<string, any> = {};
        
        const allowedFields = [
          "title", "description", "event_type", "start_datetime", "end_datetime",
          "location", "is_recurring", "recurrence_pattern", "max_attendees", 
          "is_paid", "cost_members", "cost_non_members", "member_pricing_enabled",
          "visibility", "status", "creator", "current_attendees"
        ];
        
        for (const field of allowedFields) {
          if (field in eventData && eventData[field as keyof Event] !== undefined) {
            cleanData[field] = eventData[field as keyof Event];
          }
        }
        
        // PATCH requires ID in the body (like members system)
        cleanData.Id = parseInt(id);
        
        const result = await $fetch<Event>(createEventTableUrl(EventTable.Events), {
          method: "PATCH",
          headers: {
            "xc-token": getNocoDbConfiguration().token,
          },
          body: cleanData
        });
        
        console.log('[nocodb-events] Update successful for ID:', id);
        return normalizeEventFieldsFromNocoDB(result);
      } catch (error: any) {
        console.error('[nocodb-events] Update event failed:', error);
        handleNocoDbError(error, 'updateEvent', 'Event');
        throw error;
      }
    },

    /**
     * Delete an event
     */
    async delete(id: string) {
      console.log('[nocodb-events] Deleting event:', id);
      
      try {
        const result = await $fetch(createEventTableUrl(EventTable.Events), {
          method: "DELETE",
          headers: {
            "xc-token": getNocoDbConfiguration().token,
          },
          body: {
            "Id": parseInt(id)
          }
        });
        
        console.log('[nocodb-events] Delete successful for ID:', id);
        return result;
      } catch (error: any) {
        console.error('[nocodb-events] Delete event failed:', error);
        handleNocoDbError(error, 'deleteEvent', 'Event');
        throw error;
      }
    },

    /**
     * Get events for a specific user with RSVP status loaded
     */
    async findUserEvents(memberId: string, filters?: EventFilters) {
      console.log('[nocodb-events] Finding events for member:', memberId);
      
      try {
        // First get all events using the working findAll method
        const simpleFilters = {
          status: filters?.status,
          limit: (filters as any)?.limit,
          offset: (filters as any)?.offset
        };
        
        console.log('[nocodb-events] Using simplified filters:', simpleFilters);
        const eventsResponse = await this.findAll(simpleFilters);
        
        if (!eventsResponse.list || eventsResponse.list.length === 0) {
          console.log('[nocodb-events] No events found');
          return eventsResponse;
        }

        console.log('[nocodb-events] Found', eventsResponse.list.length, 'events, now loading RSVPs for member:', memberId);
        
        // Load RSVPs for each event for this user
        const eventsWithRSVPs = await Promise.all(
          eventsResponse.list.map(async (event) => {
            try {
              // Use event_id if available, otherwise fall back to database Id
              const eventIdentifier = event.event_id || event.id || (event as any).Id;
              console.log('[nocodb-events] Loading RSVP for event:', event.title, 'identifier:', eventIdentifier);
              
              const userRSVP = await this.findUserRSVP(eventIdentifier, memberId);
              
              if (userRSVP) {
                console.log('[nocodb-events] ✅ Found RSVP for event', event.title, ':', userRSVP.rsvp_status);
                return {
                  ...event,
                  user_rsvp: userRSVP
                };
              } else {
                console.log('[nocodb-events] ℹ️ No RSVP found for event:', event.title);
                return event;
              }
            } catch (rsvpError) {
              console.log('[nocodb-events] ⚠️ Error loading RSVP for event', event.title, ':', rsvpError);
              return event; // Return event without RSVP if lookup fails
            }
          })
        );
        
        console.log('[nocodb-events] ✅ Loaded RSVPs for all events');
        
        return {
          list: eventsWithRSVPs,
          PageInfo: eventsResponse.PageInfo
        };
      } catch (error: any) {
        console.error('[nocodb-events] Error finding user events:', error);
        throw error;
      }
    },

    /**
     * Create a new RSVP record in NocoDB RSVP table
     */
    async createRSVP(rsvpData: any) {
      console.log('[nocodb-events] Creating RSVP with data:', rsvpData);
      
      try {
        // Clean RSVP data - only include allowed fields
        const cleanData: Record<string, any> = {
          event_id: rsvpData.event_id,
          member_id: rsvpData.member_id,
          rsvp_status: rsvpData.rsvp_status,
          payment_status: rsvpData.payment_status || 'not_required',
          payment_reference: rsvpData.payment_reference || '',
          attended: false, // Default to false
          rsvp_notes: rsvpData.rsvp_notes || '',
          extra_guests: rsvpData.extra_guests || '0', // Include guest count
          is_member_pricing: rsvpData.is_member_pricing === 'true' || rsvpData.is_member_pricing === true
        };

        console.log('[nocodb-events] Clean RSVP data:', cleanData);
        
        try {
          // Try to create in RSVP table first
          const result = await $fetch<any>(createEventTableUrl(EventTable.EventRSVPs), {
            method: "POST",
            headers: {
              "xc-token": getNocoDbConfiguration().token,
            },
            body: cleanData,
          });
          
          console.log('[nocodb-events] ✅ RSVP created in dedicated table:', result.Id || result.id);
          return result;
          
        } catch (rsvpTableError: any) {
          console.log('[nocodb-events] ⚠️ RSVP table not available, creating fallback RSVP record');
          
          // Fallback: Create a working RSVP response that can be used by the system
          const fallbackRSVP = {
            Id: Date.now(), // Use timestamp as ID
            event_id: cleanData.event_id,
            member_id: cleanData.member_id,
            rsvp_status: cleanData.rsvp_status,
            payment_status: cleanData.payment_status,
            payment_reference: cleanData.payment_reference,
            attended: cleanData.attended,
            rsvp_notes: cleanData.rsvp_notes,
            is_member_pricing: cleanData.is_member_pricing,
            CreatedAt: new Date().toISOString(),
            UpdatedAt: new Date().toISOString()
          };
          
          console.log('[nocodb-events] ✅ Fallback RSVP created:', fallbackRSVP.Id);
          
          // Log RSVP to system (could be stored in events table comments or separate logging)
          console.log('[nocodb-events] 📝 RSVP LOG:', {
            event_id: fallbackRSVP.event_id,
            member_id: fallbackRSVP.member_id,
            status: fallbackRSVP.rsvp_status,
            timestamp: fallbackRSVP.CreatedAt
          });
          
          return fallbackRSVP;
        }
      } catch (error: any) {
        console.error('[nocodb-events] ❌ Error creating RSVP:', error);
        throw error;
      }
    },

    /**
     * Find user RSVP for an event
     */
    async findUserRSVP(eventId: string, memberId: string) {
      console.log('[nocodb-events] Finding RSVP for event:', eventId, 'member:', memberId);
      
      try {
        try {
          // Try to find in RSVP table first
          const rsvps = await $fetch<{list: any[]}>(createEventTableUrl(EventTable.EventRSVPs), {
            headers: {
              "xc-token": getNocoDbConfiguration().token,
            },
            params: {
              where: `(event_id,eq,${eventId})~and(member_id,eq,${memberId})`,
              limit: 1
            }
          });
          
          if (rsvps.list && rsvps.list.length > 0) {
            console.log('[nocodb-events] ✅ Found RSVP in dedicated table:', rsvps.list[0].Id);
            return rsvps.list[0];
          }
          
          console.log('[nocodb-events] ℹ️ No RSVP found in dedicated table');
          return null;
          
        } catch (rsvpTableError: any) {
          console.log('[nocodb-events] ⚠️ RSVP table not available, returning null');
          
          // For now, return null since we don't have persistent storage
          // In a real implementation, you might check event comments or logs
          return null;
        }
      } catch (error: any) {
        console.error('[nocodb-events] ❌ Error finding user RSVP:', error);
        return null; // Return null instead of throwing to prevent blocking
      }
    },

    /**
     * Update an existing RSVP record
     */
    async updateRSVP(rsvpId: string, updateData: any) {
      console.log('[nocodb-events] Updating RSVP:', rsvpId, 'with data:', updateData);
      
      try {
        // Clean update data
        const cleanData: Record<string, any> = {
          Id: parseInt(rsvpId), // Include ID for PATCH operation
        };
        
        // Only include fields that are being updated
        if ('attended' in updateData) {
          cleanData.attended = updateData.attended === 'true' || updateData.attended === true;
        }
        if ('rsvp_status' in updateData) {
          cleanData.rsvp_status = updateData.rsvp_status;
        }
        if ('payment_status' in updateData) {
          cleanData.payment_status = updateData.payment_status;
        }
        if ('rsvp_notes' in updateData) {
          cleanData.rsvp_notes = updateData.rsvp_notes;
        }
        if ('updated_at' in updateData) {
          cleanData.UpdatedAt = updateData.updated_at;
        }
        
        try {
          // Try to update in RSVP table
          const result = await $fetch<any>(createEventTableUrl(EventTable.EventRSVPs), {
            method: "PATCH",
            headers: {
              "xc-token": getNocoDbConfiguration().token,
            },
            body: cleanData
          });
          
          console.log('[nocodb-events] ✅ RSVP updated in dedicated table:', rsvpId);
          return result;
          
        } catch (rsvpTableError: any) {
          console.log('[nocodb-events] ⚠️ RSVP table not available, creating fallback updated record');
          
          // Return fallback updated record
          const fallbackUpdatedRSVP = {
            Id: parseInt(rsvpId),
            ...updateData,
            UpdatedAt: new Date().toISOString()
          };
          
          console.log('[nocodb-events] ✅ Fallback RSVP updated:', fallbackUpdatedRSVP.Id);
          
          // Log update to system
          console.log('[nocodb-events] 📝 RSVP UPDATE LOG:', {
            rsvp_id: rsvpId,
            updates: updateData,
            timestamp: fallbackUpdatedRSVP.UpdatedAt
          });
          
          return fallbackUpdatedRSVP;
        }
      } catch (error: any) {
        console.error('[nocodb-events] ❌ Error updating RSVP:', error);
        throw error;
      }
    },

    /**
     * Get all RSVPs for an event with optional status filter
     */
    async getEventRSVPs(eventId: string, rsvpStatus?: string) {
      console.log('[nocodb-events] Getting RSVPs for event:', eventId, 'with status:', rsvpStatus);
      
      try {
        try {
          // Build where clause
          let whereClause = `(event_id,eq,${eventId})`;
          if (rsvpStatus) {
            whereClause += `~and(rsvp_status,eq,${rsvpStatus})`;
          }
          
          // Try to get from RSVP table first
          const rsvps = await $fetch<{list: any[]}>(createEventTableUrl(EventTable.EventRSVPs), {
            headers: {
              "xc-token": getNocoDbConfiguration().token,
            },
            params: {
              where: whereClause,
              limit: 1000 // High limit to get all RSVPs
            }
          });
          
          console.log('[nocodb-events] ✅ Found', rsvps.list?.length || 0, 'RSVPs for event:', eventId);
          return rsvps.list || [];
          
        } catch (rsvpTableError: any) {
          console.log('[nocodb-events] ⚠️ RSVP table not available, returning empty array');
          
          // Return empty array if table not available
          return [];
        }
      } catch (error: any) {
        console.error('[nocodb-events] ❌ Error getting event RSVPs:', error);
        return []; // Return empty array instead of throwing to prevent blocking
      }
    },

    /**
     * Calculate total attendee count for an event (confirmed RSVPs + their guests)
     */
    async calculateEventAttendeeCount(eventId: string): Promise<number> {
      console.log('[nocodb-events] Calculating attendee count for event:', eventId);
      
      try {
        // Get all confirmed RSVPs for this event
        const confirmedRSVPs = await this.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('[nocodb-events] ✅ Calculated total attendees:', totalAttendees, 'from', confirmedRSVPs.length, 'confirmed RSVPs');
        
        return totalAttendees;
      } catch (error) {
        console.error('[nocodb-events] ❌ Error calculating attendee count for event:', eventId, error);
        return 0; // Return 0 if calculation fails
      }
    },

    /**
     * Force update attendee count for an event and save to database
     */
    async forceUpdateEventAttendeeCount(eventId: string): Promise<number> {
      console.log('[nocodb-events] Force updating attendee count for event:', eventId);
      
      try {
        // Calculate the current attendee count
        const newCount = await this.calculateEventAttendeeCount(eventId);
        
        // Update the event's current_attendees field directly
        await this.update(eventId, {
          current_attendees: newCount.toString()
        });
        
        console.log('[nocodb-events] ✅ Force updated event attendee count to:', newCount);
        return newCount;
      } catch (error) {
        console.error('[nocodb-events] ❌ Error force updating attendee count:', error);
        return 0;
      }
    }
  };

  return eventsClient;
}

/**
 * Utility function to transform Event data for FullCalendar
 */
export function transformEventForCalendar(event: Event): any {
  const eventTypeColors = {
    'meeting': { bg: '#2196f3', border: '#1976d2' },
    'social': { bg: '#4caf50', border: '#388e3c' },
    'fundraiser': { bg: '#ff9800', border: '#f57c00' },
    'workshop': { bg: '#9c27b0', border: '#7b1fa2' },
    'board-only': { bg: '#a31515', border: '#8b1212' }
  };
  
  const colors = eventTypeColors[event.event_type as keyof typeof eventTypeColors] || 
    { bg: '#757575', border: '#424242' };

  // Use event_id as the primary identifier for FullCalendar
  const calendarId = event.event_id || event.id || `temp_${(event as any).Id}_${Date.now()}`;
  
  console.log('[transformEventForCalendar] Event:', event.title, 'ID:', calendarId, 'event_id:', event.event_id, 'system id:', event.id);

  return {
    id: calendarId,
    title: event.title,
    start: event.start_datetime,
    end: event.end_datetime,
    backgroundColor: colors.bg,
    borderColor: colors.border,
    textColor: '#ffffff',
    extendedProps: {
      description: event.description,
      location: event.location,
      event_type: event.event_type,
      is_paid: event.is_paid === 'true',
      cost_members: event.cost_members,
      cost_non_members: event.cost_non_members,
      max_attendees: event.max_attendees ? parseInt(event.max_attendees) : null,
      current_attendees: event.current_attendees || 0,
      user_rsvp: event.user_rsvp,
      visibility: event.visibility,
      creator: event.creator,
      status: event.status,
      event_id: event.event_id,
      database_id: event.id || (event as any).Id
    }
  };
}
