import { DateRange, Matcher } from 'react-day-picker'
import { isEqual, endOfDay } from 'date-fns'

import { DisableCalendarDates, RangeContext } from '../CalendarTypes'

type Props = {
  rangeContext?: RangeContext
  availableDates?: DisableCalendarDates['availableDates']
  calendarRange?: DateRange
}

export const handleRangeContextDisabledDates = ({
  rangeContext,
  availableDates,
  calendarRange,
}: Props) => {
  let findFirstPossibleRangeContextCheckIn:
    | NonNullable<DisableCalendarDates['availableDates']>['0']
    | undefined
  let findLastPossibleRangeContextCheckOut:
    | NonNullable<DisableCalendarDates['availableDates']>['0']
    | undefined

  let firstPossibleRangeContextCheckIn: Matcher[] = []
  let lastPossibleRangeContextCheckOut: Matcher[] = []

  // Parse data
  const rangeContextFrom = rangeContext?.from && endOfDay(rangeContext.from)
  const rangeContextTo = rangeContext?.to && endOfDay(rangeContext.to)
  const calendarRangeFrom = calendarRange?.from && endOfDay(calendarRange.from)

  if (rangeContext && availableDates?.length) {
    // Find the first possible check-in after the last date gap till the range context

    findFirstPossibleRangeContextCheckIn = availableDates?.find(
      (date) =>
        rangeContextFrom &&
        endOfDay(date.checkIn) < rangeContextFrom &&
        endOfDay(date.lastCheckOut) >= rangeContextFrom
    )

    if (findFirstPossibleRangeContextCheckIn?.checkIn) {
      firstPossibleRangeContextCheckIn.push({
        before: findFirstPossibleRangeContextCheckIn.checkIn,
      })
    }

    // Find the last possible checkout before the first date gap till the range context
    findLastPossibleRangeContextCheckOut = availableDates?.find(
      (date) =>
        rangeContextTo && isEqual(rangeContextTo, endOfDay(date.checkIn))
    )

    if (findLastPossibleRangeContextCheckOut?.checkIn) {
      lastPossibleRangeContextCheckOut.push({
        after: findLastPossibleRangeContextCheckOut.lastCheckOut,
      })
    }
  }

  // Get possible check-out dates for current check-in
  const currentSelectionAvailability = availableDates?.find((date) => {
    return calendarRangeFrom
      ? isEqual(endOfDay(date.checkIn), calendarRangeFrom)
      : false
  })

  return {
    findFirstPossibleRangeContextCheckIn,
    findLastPossibleRangeContextCheckOut,
    firstPossibleRangeContextCheckIn,
    lastPossibleRangeContextCheckOut,
    currentSelectionAvailability,
  }
}
