import { useMemo, useState } from 'react' import { addDays, format } from 'date-fns' import { DateRange, Matcher } from 'react-day-picker' import { DisableCalendarDates } from '../CalendarTypes' type Props = { disableCalendarDates?: DisableCalendarDates calendarRange?: DateRange updateCalendarMonthNavigation?: boolean updateCalendarDefaultMonth?: number } export const useUpdateDisabledDates = ({ disableCalendarDates, calendarRange, updateCalendarMonthNavigation, updateCalendarDefaultMonth, }: Props) => { const [overlappingDate, setOverlappingDate] = useState< DateRange[] | undefined >(undefined) const [lastPossibleCheckout, setLatsPossibleCheckout] = useState([]) const newDisableCalendarDates = useMemo(() => { if (disableCalendarDates?.availableDates) { const dateFormat = 'dd-MM-yyyy' const { disabledDates } = disableCalendarDates const { updatedDisabledDates, newOverlappingDates } = ( disabledDates || [] ).reduce( ( acc: { updatedDisabledDates: { to: Date; from: Date }[] newOverlappingDates: { to: Date; from: Date }[] }, dateRange ) => { const formattedFromDate = format(dateRange.from, dateFormat) const formattedToDate = format(dateRange.to, dateFormat) const hasTwoOverlappingDates = disableCalendarDates.availableDates?.some( (item) => format(item.lastCheckOut, dateFormat) === formattedFromDate && format(item.lastCheckOut, dateFormat) === formattedToDate ) const hasOneOverlappingDate = disableCalendarDates.availableDates?.some( (item) => format(item.lastCheckOut, dateFormat) === formattedFromDate && format(item.lastCheckOut, dateFormat) !== formattedToDate ) if (hasTwoOverlappingDates) { acc.newOverlappingDates.push(dateRange) } else if (hasOneOverlappingDate) { acc.newOverlappingDates.push(dateRange) acc.updatedDisabledDates.push({ ...dateRange, from: addDays(dateRange.from, 1), }) } else { acc.updatedDisabledDates.push(dateRange) } return acc }, { updatedDisabledDates: [], newOverlappingDates: [] } ) // Find last possible checkout ( disable all dates after the last possible checkout ) const lastPossibleCheckoutDate: Date | undefined = disableCalendarDates.availableDates.at(-1)?.lastCheckOut if (lastPossibleCheckoutDate) { setLatsPossibleCheckout({ after: lastPossibleCheckoutDate }) } // Extract overlapping dates ( dates that are only available for checkout ) if (newOverlappingDates.length) { setOverlappingDate([...newOverlappingDates]) } const newDisableCalendarDates = { ...disableCalendarDates, disabledDates: updatedDisabledDates, } return newDisableCalendarDates } return disableCalendarDates }, [ disableCalendarDates, calendarRange, updateCalendarMonthNavigation, updateCalendarDefaultMonth, ]) return { newDisableCalendarDates, overlappingDate, lastPossibleCheckout } }