import React, { useContext, useEffect, useState } from 'react';

import { StoreProduct } from '@medusajs/types';

import { getAvailableTimeSlotsForDisplay } from '~/lib/services/connected-online.service';

import { ServiceCategory } from '../service-categories';
import { BookingContext, Location, TimeSlot } from './booking.context';

export function useBooking() {
  const context = useContext(BookingContext);

  if (!context) {
    throw new Error('useBooking must be used within a BookingProvider.');
  }

  return context;
}

export const BookingProvider: React.FC<{
  children: React.ReactElement;
  category: ServiceCategory;
}> = ({ children, category }) => {
  const [selectedService, setSelectedService] = useState<StoreProduct | null>(
    category.products[0] || null,
  );
  const [selectedLocationId, setSelectedLocationId] = useState<number | null>(
    null,
  );
  const [selectedDate, setSelectedDate] = useState<Date>();
  const [timeSlots, setTimeSlots] = useState<TimeSlot[] | null>(null);
  const [locations, setLocations] = useState<Location[] | null>(null);
  const [isLoadingTimeSlots, setIsLoadingTimeSlots] = useState(false);

  useEffect(() => {
    let metadataServiceIds = [];
    try {
      metadataServiceIds = JSON.parse(
        selectedService?.metadata?.serviceIds as string,
      );
    } catch (e) {
      console.error(e);
    }
    if (metadataServiceIds.length) {
      updateTimeSlots(metadataServiceIds);
    }
  }, [selectedService?.metadata?.serviceIds, selectedLocationId]);

  const updateTimeSlots = async (serviceIds: number[]) => {
    setIsLoadingTimeSlots(true);
    try {
      const response = await getAvailableTimeSlotsForDisplay(
        serviceIds,
        selectedLocationId,
      );
      setTimeSlots(response.timeSlots);
      setLocations(response.locations);
    } catch (error) {
      setTimeSlots(null);
    } finally {
      setIsLoadingTimeSlots(false);
    }
  };

  return (
    <BookingContext.Provider
      value={{
        timeSlots,
        locations,
        selectedService,
        selectedLocationId,
        setSelectedLocationId,
        selectedDate,
        isLoadingTimeSlots,
        setSelectedService,
        updateTimeSlots,
        setSelectedDate,
      }}
    >
      {children}
    </BookingContext.Provider>
  );
};
