'use client'

import * as React from 'react'
import { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react'
import { DayButton, DayPicker, getDefaultClassNames } from 'react-day-picker'
import { enUS, ru, es } from "date-fns/locale"
import { Locale } from 'date-fns'

import { cn } from '@/lib/utils/cn'
import { CalendarButton, buttonVariants } from '@/components/ui/calendar-button'
import { Button } from './button'
import { TimePicker } from '../shared/TimePicker'
import { useCurrentLocale, useI18n } from '@/locales/client'

interface CalendarProps
  extends Omit<React.ComponentProps<typeof DayPicker>, 'selected' | 'onSelect' | 'mode'> {
  value?: Date
  onChange?: (dateTime: Date) => void
  onCancel?: () => void
  hideTime?: boolean
  buttonVariant?: React.ComponentProps<typeof CalendarButton>['variant']
  bookedDates?: []
}

const localeMap: Record<string, Locale> = {
  en: enUS,
  ru,
  es,
}

const Calendar: React.FC<CalendarProps> = ({
  value,
  onChange,
  onCancel,
  className,
  classNames,
  showOutsideDays = true,
  captionLayout = 'label',
  buttonVariant = 'ghost',
  formatters,
  components,
  hideTime = false,
  bookedDates = [],
  ...props
}) => {
  const defaultClassNames = getDefaultClassNames()
  const [selectedDate, setSelectedDate] = React.useState<Date>(value ?? new Date())
  const [selectedTime, setSelectedTime] = React.useState<Date>(value ?? new Date())
  
  React.useEffect(() => {
    if (value) {
      setSelectedDate(value)
      setSelectedTime(value)
      return
    } 
  }, [value]);
  
  const today = new Date();
  today.setHours(0, 0, 0, 0) 


  const handleChoose = () => {
    const dateTime = new Date(selectedDate)
    dateTime.setHours(selectedTime.getHours(), selectedTime.getMinutes(), selectedTime.getSeconds())
    onChange?.(dateTime)
  }

  const t = useI18n()
  const currentLocale = useCurrentLocale()

  return (
    <div className="bg-grey-700 w-fit p-[20px_16px] rounded-[8px]">
      <DayPicker
        mode="single"
        showOutsideDays={showOutsideDays}
        selected={selectedDate}
        onSelect={(date: Date | undefined) => date && setSelectedDate(date)}
        disabled={[{ before: today }, ...bookedDates]}
        className={cn(
          'border-none group/calendar p-0 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent',
          String.raw`rtl:**:[.rdp-button_next>svg]:rotate-180`,
          String.raw`rtl:**:[.rdp-button_previous>svg]:rotate-180`,
          className,
        )}
        captionLayout={captionLayout}
        locale={localeMap[currentLocale]}
        formatters={{
          formatMonthDropdown: (date) => date.toLocaleString(currentLocale, { month: 'short' }),
          ...formatters,
        }}
        classNames={{
          root: cn('w-fit', defaultClassNames.root),
          months: cn('flex gap-4 flex-col md:flex-row relative', defaultClassNames.months),
          month: cn(
            'b3-regular text-base-white flex flex-col w-full text-white gap-y-10 gap-x-4',
            defaultClassNames.month,
          ),
          nav: cn(
            'flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between',
            defaultClassNames.nav,
          ),
          button_previous: cn(
            buttonVariants({ variant: buttonVariant }),
            'size-10 hover:bg-[#F6ECE5] bg-[#D6D0CA24] hover:text-grey-900 text-base-white cursor-pointer aria-disabled:opacity-50 p-0 select-none',
            defaultClassNames.button_previous,
          ),
          button_next: cn(
            buttonVariants({ variant: buttonVariant }),
            'size-10 hover:bg-[#F6ECE5]  bg-[#D6D0CA24] hover:text-grey-900 text-base-white cursor-pointer aria-disabled:opacity-50 p-0 select-none',
            defaultClassNames.button_next,
          ),
          month_caption: cn(
            'flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)',
            defaultClassNames.month_caption,
          ),
          dropdowns: cn(
            'w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5',
            defaultClassNames.dropdowns,
          ),
          dropdown_root: cn(
            'relative has-focus:border-ring border border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] rounded-md',
            defaultClassNames.dropdown_root,
          ),
          dropdown: cn('absolute inset-0 opacity-0', defaultClassNames.dropdown),
          caption_label: cn(
            'select-none font-medium',
            captionLayout === 'label'
              ? 'text-sm'
              : 'rounded-md pl-2 pr-1 flex items-center gap-1 text-sm h-8 [&>svg]:text-muted-foreground [&>svg]:size-3.5',
            defaultClassNames.caption_label,
          ),
          table: 'w-full border-collapse',
          weekdays: cn('flex', defaultClassNames.weekdays),
          weekday: cn(
            'text-muted-foreground rounded-md flex-1 font-normal text-[0.8rem] select-none',
            defaultClassNames.weekday,
          ),
          week: cn('flex w-full mt-2', defaultClassNames.week),
          week_number_header: cn(
            'select-none w-(--cell-size)',
            defaultClassNames.week_number_header,
          ),
          week_number: cn(
            'text-[0.8rem] select-none text-muted-foreground',
            defaultClassNames.week_number,
          ),
          day: cn(
            'size-10 relative w-full h-full p-0 data-[selected=true]:bg-base-white data-[selected=true]:text-base-black data-[selected=true]:rounded-md text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md group/day aspect-square select-none',
            defaultClassNames.day,
          ),
          range_start: cn('rounded-l-md bg-accent', defaultClassNames.range_start),
          range_middle: cn('rounded-none', defaultClassNames.range_middle),
          range_end: cn('rounded-r-md bg-accent', defaultClassNames.range_end),
          outside: cn(
            'text-muted-foreground aria-selected:text-muted-foreground',
            defaultClassNames.outside,
          ),
          disabled: cn('text-muted-foreground opacity-50', defaultClassNames.disabled),
          hidden: cn('invisible', defaultClassNames.hidden),
          selected: cn('bg-primary'),
          ...classNames,
        }}
        components={{ Chevron, Root, DayButton: CalendarDayButton, WeekNumber, ...components }}
        {...props}
      />

      {!hideTime && (
        <div className="mt-4">
          <TimePicker
            value={selectedTime}
            onChange={(time: Date | undefined) => time && setSelectedTime(time)}
          />
        </div>
      )}

      <div className="w-full flex justify-between mt-4">
        <Button sizes="btn-md" variant="tertiary" onClick={onCancel}>
          {t('calendar.cancel')}
        </Button>
        <Button sizes="btn-md" variant="primary" onClick={handleChoose}>
          {t('calendar.choose')}
        </Button>
      </div>
    </div>
  )
}

function Chevron({ className, orientation, ...props }: any) {
  if (orientation === 'left')
    return <ChevronLeftIcon className={cn('size-4', className)} {...props} />
  if (orientation === 'right')
    return <ChevronRightIcon className={cn('size-4', className)} {...props} />
  return <ChevronDownIcon className={cn('size-4', className)} {...props} />
}

function Root({ className, rootRef, ...props }: any) {
  return <div data-slot="calendar" ref={rootRef} className={cn(className)} {...props} />
}

function WeekNumber({ children, ...props }: any) {
  return (
    <td {...props}>
      <div className="flex size-(--cell-size) items-center justify-center text-center">
        {children}
      </div>
    </td>
  )
}

function CalendarDayButton({
  className,
  day,
  modifiers,
  ...props
}: React.ComponentProps<typeof DayButton>) {
  const defaultClassNames = getDefaultClassNames()
  const ref = React.useRef<HTMLButtonElement>(null)
  React.useEffect(() => {
    if (modifiers.focused) ref.current?.focus()
  }, [modifiers.focused])
  return (
    <CalendarButton
      ref={ref}
      variant="ghost"
      size="icon"
      className={cn(defaultClassNames.day, className)}
      {...props}
    />
  )
}

export { Calendar, CalendarDayButton }
