import React, { useEffect, useRef } from 'react'
import { enAU } from 'date-fns/locale'
import { DayPicker, type PropsBase, type PropsSingle } from 'react-day-picker'
import { Icon } from '~components/Icon'
import { type OverrideClassName } from '~components/types/OverrideClassName'
import { baseCalendarClassNames } from '../baseCalendarClassNames'
import { type DeprecatedReactDayPickerProps } from '../types'
import { isInvalidDate, isValidWeekStartsOn } from '../utils'
import styles from './CalendarSingle.module.scss'

export type CalendarSingleElement = HTMLDivElement

export type CalendarSingleProps = {
  id?: string
  onMount?: (calendarElement: CalendarSingleElement) => void
  /** Exposes the react-day-picker component prop. Please be aware, consumers using this will have to guarentee functions as expected */
  components?: PropsBase['components']
} & OverrideClassName<
  Omit<PropsSingle & Omit<PropsBase, 'mode'>, 'mode' | DeprecatedReactDayPickerProps>
>

export const CalendarSingle = ({
  id,
  onMount,
  classNameOverride,
  selected,
  defaultMonth,
  weekStartsOn,
  locale = enAU,
  components = {},
  ...restProps
}: CalendarSingleProps): JSX.Element => {
  const calendarRef = useRef<CalendarSingleElement>(null)

  useEffect(() => {
    if (calendarRef.current) onMount?.(calendarRef.current)
  }, [calendarRef, onMount])

  const monthToShow = selected ?? defaultMonth
  const selectedMonth = monthToShow && isInvalidDate(monthToShow) ? undefined : monthToShow

  /* eslint-disable camelcase */
  const classNames: PropsBase['classNames'] = {
    ...baseCalendarClassNames,
    nav: styles.nav,
    nav_button_next: styles.navButtonNext,
  }
  /* eslint-enable camelcase */

  return (
    <div ref={calendarRef} id={id} className={classNameOverride}>
      <DayPicker
        mode="single"
        selected={selected && isInvalidDate(selected) ? undefined : selected}
        defaultMonth={selectedMonth}
        weekStartsOn={isValidWeekStartsOn(weekStartsOn) ? weekStartsOn : undefined}
        classNames={classNames}
        components={{
          Chevron: (props) => {
            if (props.orientation === 'left') {
              return (
                <Icon
                  name="arrow_back"
                  isPresentational
                  shouldMirrorInRTL
                  className={styles.chevronIcon}
                />
              )
            }

            return (
              <Icon
                name="arrow_forward"
                isPresentational
                shouldMirrorInRTL
                className={styles.chevronIcon}
              />
            )
          },
          ...components,
        }}
        locale={locale}
        {...restProps}
      />
    </div>
  )
}

CalendarSingle.displayName = 'CalendarSingle'
