import { createClient } from '@supabase/supabase-js'; import type { Database } from './database.types'; const supabase = createClient( import.meta.env.PUBLIC_SUPABASE_URL, import.meta.env.PUBLIC_SUPABASE_ANON_KEY ); export interface TicketType { id: string; name: string; description: string; price_cents: number; quantity: number; is_active: boolean; event_id: string; sort_order: number; created_at: string; updated_at: string; } export interface TicketTypeFormData { name: string; description: string; price_cents: number; quantity: number; is_active: boolean; } export interface TicketSale { id: string; event_id: string; ticket_type_id: string; price_paid: number; status: string; checked_in: boolean; customer_email: string; customer_name: string; created_at: string; ticket_uuid: string; ticket_types: { name: string; price_cents: number; }; } export async function loadTicketTypes(eventId: string): Promise { try { const { data: ticketTypes, error } = await supabase .from('ticket_types') .select('*') .eq('event_id', eventId) .order('sort_order', { ascending: true }); if (error) { console.error('Error loading ticket types:', error); return []; } return ticketTypes || []; } catch (error) { console.error('Error loading ticket types:', error); return []; } } export async function createTicketType(eventId: string, ticketTypeData: TicketTypeFormData): Promise { try { // Get the next sort order const { data: existingTypes } = await supabase .from('ticket_types') .select('sort_order') .eq('event_id', eventId) .order('sort_order', { ascending: false }) .limit(1); const nextSortOrder = existingTypes?.[0]?.sort_order ? existingTypes[0].sort_order + 1 : 1; const { data: ticketType, error } = await supabase .from('ticket_types') .insert({ ...ticketTypeData, event_id: eventId, sort_order: nextSortOrder }) .select() .single(); if (error) { console.error('Error creating ticket type:', error); return null; } return ticketType; } catch (error) { console.error('Error creating ticket type:', error); return null; } } export async function updateTicketType(ticketTypeId: string, updates: Partial): Promise { try { const { error } = await supabase .from('ticket_types') .update(updates) .eq('id', ticketTypeId); if (error) { console.error('Error updating ticket type:', error); return false; } return true; } catch (error) { console.error('Error updating ticket type:', error); return false; } } export async function deleteTicketType(ticketTypeId: string): Promise { try { // Check if there are any tickets sold for this type const { data: tickets } = await supabase .from('tickets') .select('id') .eq('ticket_type_id', ticketTypeId) .limit(1); if (tickets && tickets.length > 0) { throw new Error('Cannot delete ticket type with existing sales'); } const { error } = await supabase .from('ticket_types') .delete() .eq('id', ticketTypeId); if (error) { console.error('Error deleting ticket type:', error); return false; } return true; } catch (error) { console.error('Error deleting ticket type:', error); return false; } } export async function toggleTicketTypeStatus(ticketTypeId: string, isActive: boolean): Promise { return updateTicketType(ticketTypeId, { is_active: isActive }); } export async function loadTicketSales(eventId: string, filters?: { ticketTypeId?: string; searchTerm?: string; status?: string; }): Promise { try { let query = supabase .from('tickets') .select(` id, event_id, ticket_type_id, price_paid, status, checked_in, customer_email, customer_name, created_at, ticket_uuid, ticket_types ( name, price_cents ) `) .eq('event_id', eventId) .order('created_at', { ascending: false }); // Apply filters if (filters?.ticketTypeId) { query = query.eq('ticket_type_id', filters.ticketTypeId); } if (filters?.status) { query = query.eq('status', filters.status); } if (filters?.searchTerm) { query = query.or(`customer_email.ilike.%${filters.searchTerm}%,customer_name.ilike.%${filters.searchTerm}%`); } const { data: tickets, error } = await query; if (error) { console.error('Error loading ticket sales:', error); return []; } return tickets || []; } catch (error) { console.error('Error loading ticket sales:', error); return []; } } export async function checkInTicket(ticketId: string): Promise { try { const { error } = await supabase .from('tickets') .update({ checked_in: true }) .eq('id', ticketId); if (error) { console.error('Error checking in ticket:', error); return false; } return true; } catch (error) { console.error('Error checking in ticket:', error); return false; } } export async function refundTicket(ticketId: string): Promise { try { const { error } = await supabase .from('tickets') .update({ status: 'refunded' }) .eq('id', ticketId); if (error) { console.error('Error refunding ticket:', error); return false; } return true; } catch (error) { console.error('Error refunding ticket:', error); return false; } } export function formatTicketPrice(cents: number): string { return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(cents / 100); } export function calculateTicketTypeStats(ticketType: TicketType, sales: TicketSale[]): { sold: number; available: number; revenue: number; } { const typeSales = sales.filter(sale => sale.ticket_type_id === ticketType.id && sale.status === 'confirmed'); const sold = typeSales.length; const available = ticketType.quantity - sold; const revenue = typeSales.reduce((sum, sale) => sum + sale.price_paid, 0); return { sold, available, revenue }; }