import PocketBase from 'pocketbase';
import { BookingType, Resource, TimeSlot, Booking } from '@/types/booking';

// Initialize PocketBase client
export const pb = new PocketBase(process.env.NEXT_PUBLIC_POCKETBASE_URL || 'http://127.0.0.1:8090');

// Disable auto cancellation for SSR
pb.autoCancellation(false);

// API functions for booking system

export const bookingApi = {
    // Get all active booking types
    async getBookingTypes(): Promise<BookingType[]> {
        try {
            const records = await pb.collection('bookingTypes').getFullList<BookingType>({
                sort: 'created',
                expand: 'resources',
            });
            return records;
        } catch (error) {
            console.error('Error fetching booking types:', error);
            throw error;
        }
    },

    // Get available resources
    async getResources(): Promise<Resource[]> {
        try {
            const records = await pb.collection('resources').getFullList<Resource>({
                filter: 'is_active = true',
                sort: 'type',
            });
            return records;
        } catch (error) {
            console.error('Error fetching resources:', error);
            throw error;
        }
    },

    // Get available time slots for a specific booking type and date range
    async getAvailableTimeSlots(
        bookingTypeId: string,
        startDate: Date,
        endDate: Date
    ): Promise<TimeSlot[]> {
        try {
            const startDateStr = startDate.toISOString().split('T')[0];
            const endDateStr = endDate.toISOString().split('T')[0];

            const records = await pb.collection('timeSlots').getFullList<TimeSlot>({
                filter: `is_active = true && booking_types ~ "${bookingTypeId}" && start_time >= "${startDateStr}" && start_time <= "${endDateStr}"`,
                sort: 'start_time',
            });
            return records;
        } catch (error) {
            console.error('Error fetching time slots:', error);
            throw error;
        }
    },

    // Check if a time slot has availability
    async checkTimeSlotAvailability(
        timeSlotId: string,
        startTime: string,
        endTime: string,
        participantsCount: number
    ): Promise<{ available: boolean; currentBookings: number }> {
        try {
            // Get existing confirmed bookings for this time slot
            const existingBookings = await pb.collection('bookings').getFullList<Booking>({
                filter: `status = "confirmed" && start_time >= "${startTime}" && end_time <= "${endTime}"`,
            });

            // Get the time slot to check max capacity
            const timeSlot = await pb.collection('timeSlots').getOne<TimeSlot>(timeSlotId);

            const currentBookings = existingBookings.reduce((sum, booking) =>
                sum + (booking.participants_count || 0), 0
            );

            const availableSpots = timeSlot.max_capacity - currentBookings;
            const available = availableSpots >= participantsCount;

            return {
                available,
                currentBookings,
            };
        } catch (error) {
            console.error('Error checking availability:', error);
            throw error;
        }
    },

    // Create a new booking
    async createBooking(bookingData: {
        booking_type: string;
        customer_name: string;
        customer_email: string;
        start_time: string;
        end_time: string;
        participants_count: number;
        internal_notes?: string;
    }): Promise<Booking> {
        try {
            const record = await pb.collection('bookings').create<Booking>({
                ...bookingData,
                status: 'confirmed',
                payment_status: 'not_required', // We'll handle payment logic later
                payment_required: false,
            });
            return record;
        } catch (error) {
            console.error('Error creating booking:', error);
            throw error;
        }
    },

    // Get booking by cancellation token (for cancellation flow)
    async getBookingByToken(token: string): Promise<Booking | null> {
        try {
            const records = await pb.collection('bookings').getFullList<Booking>({
                filter: `cancellation_token = "${token}"`,
            });
            return records[0] || null;
        } catch (error) {
            console.error('Error fetching booking by token:', error);
            return null;
        }
    },

    // Cancel booking
    async cancelBooking(bookingId: string): Promise<boolean> {
        try {
            await pb.collection('bookings').update(bookingId, {
                status: 'cancelled',
            });
            return true;
        } catch (error) {
            console.error('Error cancelling booking:', error);
            return false;
        }
    },
};