import type { SupabaseClient } from '@supabase/supabase-js'; import type { Database } from '@kit/supabase/database'; import type { CreateBookingInput } from '../schema/booking.schema'; /* eslint-disable @typescript-eslint/no-explicit-any */ export function createBookingManagementApi(client: SupabaseClient) { const db = client; return { // --- Rooms --- async listRooms(accountId: string) { const { data, error } = await client .from('rooms') .select('*') .eq('account_id', accountId) .eq('is_active', true) .order('room_number'); if (error) throw error; return data ?? []; }, async getRoom(roomId: string) { const { data, error } = await client .from('rooms') .select('*') .eq('id', roomId) .single(); if (error) throw error; return data; }, // --- Availability --- async checkAvailability(roomId: string, checkIn: string, checkOut: string) { const { count, error } = await client .from('bookings') .select('*', { count: 'exact', head: true }) .eq('room_id', roomId) .not('status', 'in', '("cancelled","no_show")') .lt('check_in', checkOut) .gt('check_out', checkIn); if (error) throw error; return (count ?? 0) === 0; }, // --- Bookings --- async listBookings( accountId: string, opts?: { status?: string; from?: string; to?: string; page?: number }, ) { let query = client .from('bookings') .select('*', { count: 'exact' }) .eq('account_id', accountId) .order('check_in', { ascending: false }); if (opts?.status) query = query.eq('status', opts.status); if (opts?.from) query = query.gte('check_in', opts.from); if (opts?.to) query = query.lte('check_out', opts.to); const page = opts?.page ?? 1; query = query.range((page - 1) * 25, page * 25 - 1); const { data, error, count } = await query; if (error) throw error; return { data: data ?? [], total: count ?? 0 }; }, async createBooking(input: CreateBookingInput) { const available = await this.checkAvailability( input.roomId, input.checkIn, input.checkOut, ); if (!available) throw new Error('Room is not available for the selected dates'); const { data, error } = await client .from('bookings') .insert({ account_id: input.accountId, room_id: input.roomId, guest_id: input.guestId, check_in: input.checkIn, check_out: input.checkOut, adults: input.adults, children: input.children, status: input.status, total_price: input.totalPrice, notes: input.notes, }) .select() .single(); if (error) throw error; return data; }, async updateBookingStatus(bookingId: string, status: string) { const { error } = await client .from('bookings') .update({ status }) .eq('id', bookingId); if (error) throw error; }, // --- Guests --- async listGuests(accountId: string, search?: string) { let query = client .from('guests') .select('*') .eq('account_id', accountId) .order('last_name'); if (search) query = query.or( `last_name.ilike.%${search}%,first_name.ilike.%${search}%,email.ilike.%${search}%`, ); const { data, error } = await query; if (error) throw error; return data ?? []; }, async createGuest(input: { accountId: string; firstName: string; lastName: string; email?: string; phone?: string; city?: string; }) { const { data, error } = await client .from('guests') .insert({ account_id: input.accountId, first_name: input.firstName, last_name: input.lastName, email: input.email, phone: input.phone, city: input.city, }) .select() .single(); if (error) throw error; return data; }, async createRoom(input: { accountId: string; roomNumber: string; name?: string; roomType?: string; capacity?: number; floor?: number; pricePerNight: number; description?: string; }) { const { data, error } = await client .from('rooms') .insert({ account_id: input.accountId, room_number: input.roomNumber, name: input.name, room_type: input.roomType ?? 'standard', capacity: input.capacity ?? 2, floor: input.floor, price_per_night: input.pricePerNight, description: input.description, }) .select() .single(); if (error) throw error; return data; }, }; }