import { useMemo, useState } from 'react';
import { useRouter } from 'next/navigation';
import { formatCurrency } from '@/packages/shared/src/utils';
import { addHours, isAfter, isSameDay } from 'date-fns';
import { orderBy } from 'lodash';
import { useTranslation } from 'react-i18next';
import { pathsConfig } from '@kit/shared/config';
import { formatDateAndTime } from '@kit/shared/utils';
import { Button } from '@kit/ui/shadcn/button';
import { Card } from '@kit/ui/shadcn/card';
import { toast } from '@kit/ui/sonner';
import { Trans } from '@kit/ui/trans';
import { cn } from '@kit/ui/utils';
import { updateReservationTime } from '~/lib/services/reservation.service';
import { createInitialReservationAction } from '../../_lib/server/actions';
import { EnrichedCartItem } from '../cart/types';
import { ServiceProvider, TimeSlot } from './booking.context';
import { useBooking } from './booking.provider';
const getServiceProviderTitle = (
currentLocale: string,
serviceProvider?: ServiceProvider,
) => {
if (!serviceProvider) return null;
if (currentLocale === 'en') return serviceProvider.jobTitleEn;
if (currentLocale === 'ru') return serviceProvider.jobTitleRu;
return serviceProvider.jobTitleEt;
};
const PAGE_SIZE = 7;
const TimeSlots = ({
countryCode,
cartItem,
onComplete,
}: {
countryCode: string;
cartItem?: EnrichedCartItem;
onComplete?: () => void;
}) => {
const [currentPage, setCurrentPage] = useState(1);
const {
t,
i18n: { language: currentLocale },
} = useTranslation();
const booking = useBooking();
const router = useRouter();
const selectedDate = booking.selectedDate ?? new Date();
const filteredBookings = useMemo(
() =>
orderBy(
booking?.timeSlots?.filter(({ StartTime }) => {
const firstAvailableTimeToSelect = isSameDay(selectedDate, new Date())
? addHours(new Date(), 0.5)
: selectedDate;
return isAfter(StartTime, firstAvailableTimeToSelect);
}) ?? [],
'StartTime',
'asc',
),
[booking.timeSlots, selectedDate],
);
const totalPages = Math.ceil(filteredBookings.length / PAGE_SIZE);
const paginatedBookings = useMemo(() => {
const startIndex = (currentPage - 1) * PAGE_SIZE;
const endIndex = startIndex + PAGE_SIZE;
return filteredBookings.slice(startIndex, endIndex);
}, [filteredBookings, currentPage, PAGE_SIZE]);
const handlePageChange = (page: number) => {
setCurrentPage(page);
};
const generatePageNumbers = () => {
const pages = [];
const maxVisiblePages = 5;
if (totalPages <= maxVisiblePages) {
for (let i = 1; i <= totalPages; i++) {
pages.push(i);
}
} else {
if (currentPage <= 3) {
for (let i = 1; i <= 4; i++) {
pages.push(i);
}
pages.push('...');
pages.push(totalPages);
} else if (currentPage >= totalPages - 2) {
pages.push(1);
pages.push('...');
for (let i = totalPages - 3; i <= totalPages; i++) {
pages.push(i);
}
} else {
pages.push(1);
pages.push('...');
for (let i = currentPage - 1; i <= currentPage + 1; i++) {
pages.push(i);
}
pages.push('...');
pages.push(totalPages);
}
}
return pages;
};
if (!booking?.timeSlots?.length) {
return null;
}
const handleBookTime = async (timeSlot: TimeSlot, comments?: string) => {
const selectedService = booking.selectedService;
const selectedVariant = selectedService?.variants?.[0];
const syncedService = timeSlot.syncedService;
if (!syncedService || !selectedVariant) {
return toast.error(t('booking:serviceNotFound'));
}
const bookTimePromise = createInitialReservationAction(
selectedVariant,
countryCode,
Number(syncedService.id),
syncedService?.clinic_id,
timeSlot.UserID,
timeSlot.SyncUserID,
timeSlot.StartTime,
booking.selectedLocationId ? booking.selectedLocationId : null,
comments,
).then(() => {
if (onComplete) {
onComplete();
}
router.push(pathsConfig.app.cart);
});
toast.promise(() => bookTimePromise, {
success:
{t('booking:noResults')}