import React from 'react'
import {
  DayPicker,
  type DayButtonProps,
  type DateRange,
} from 'react-day-picker'
import {
  SvgTaillessLineArrowLeft1,
  SvgTaillessLineArrowRight1,
} from '@chainlink/blocks-icons'
import { cn } from '../../utils/cn'
import { buttonIconVariants } from '../Button'

export type CalendarProps = React.ComponentProps<typeof DayPicker>

/**
 * Custom DayButton — all button-level visual styles live here.
 * Uses data-attributes for state so the Calendar classNames only
 * handle cell-level layout and the range band background.
 */
function CalendarDayButton({
  day,
  modifiers,
  className,
  ...props
}: DayButtonProps) {
  const ref = React.useRef<HTMLButtonElement>(null)
  React.useEffect(() => {
    if (modifiers.focused) ref.current?.focus()
  }, [modifiers.focused])

  return (
    <button
      ref={ref}
      data-day={day.date.toLocaleDateString()}
      data-today={modifiers.today && !modifiers.selected}
      data-selected-single={
        modifiers.selected &&
        !modifiers.range_start &&
        !modifiers.range_end &&
        !modifiers.range_middle
      }
      data-range-start={modifiers.range_start}
      data-range-end={modifiers.range_end}
      data-range-middle={modifiers.range_middle}
      className={cn(
        buttonIconVariants({ variant: 'ghost', size: 'xs' }),
        'relative isolate z-10 h-9 max-h-9 min-h-9 w-9 min-w-9 max-w-9 rounded-md p-0 font-normal',
        'bg-background aria-selected:opacity-100',
        // Today
        'data-[today=true]:rounded-md data-[today=true]:bg-muted-more data-[today=true]:text-foreground',
        // Hover
        'hover:bg-muted hover:text-foreground',
        // Single / multi selected
        'data-[selected-single=true]:rounded-md data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[selected-single=true]:hover:bg-primary data-[selected-single=true]:hover:text-primary-foreground',
        // Range start — rounded left, flat right
        'data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-start=true]:hover:bg-primary data-[range-start=true]:hover:text-primary-foreground',
        // Range middle — transparent over muted cell band, rounded on hover (no transition so both snap together)
        'data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-transparent data-[range-middle=true]:text-foreground data-[range-middle=true]:transition-none data-[range-middle=true]:hover:rounded-md data-[range-middle=true]:hover:bg-muted-more data-[range-middle=true]:hover:text-foreground',
        // Range end
        'data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-end=true]:hover:bg-primary data-[range-end=true]:hover:text-primary-foreground',
        className,
      )}
      {...props}
    />
  )
}

function Calendar({
  className,
  classNames,
  showOutsideDays = true,
  ...props
}: CalendarProps) {
  return (
    <DayPicker
      showOutsideDays={showOutsideDays}
      className={cn(
        'w-fit rounded-md border bg-background p-3 shadow-sm',
        className,
      )}
      classNames={{
        months: cn(
          'relative flex flex-col space-y-4 sm:flex-row sm:space-y-0',
          props.numberOfMonths === 1 ? 'sm:space-x-0' : 'sm:space-x-4',
        ),
        month: 'space-y-4 relative',
        month_caption: 'flex justify-center pt-2 relative items-center',
        caption_label: 'text-sm font-medium text-foreground',
        nav: 'flex items-center justify-between absolute inset-x-0 top-0',
        button_previous: cn(
          buttonIconVariants({ variant: 'default', size: 'xs' }),
          'z-10 h-4 w-4 bg-transparent p-0 opacity-50 hover:opacity-100',
        ),
        button_next: cn(
          buttonIconVariants({ variant: 'default', size: 'xs' }),
          'z-10 h-4 w-4 bg-transparent p-0 opacity-50 hover:opacity-100',
        ),
        month_grid: 'w-full border-collapse',
        weekdays: 'flex',
        weekday:
          'text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]',
        weeks: 'flex flex-col',
        week: 'flex w-full mt-2',
        // Cell — layout only
        day: 'h-9 w-9 text-center text-sm p-0 relative focus-within:relative focus-within:z-20',
        // Range band on cells
        range_start: 'bg-muted rounded-s-md',
        range_middle: 'bg-muted',
        range_end: 'bg-muted rounded-e-md',
        // Button handles all selected/today visuals
        selected: '',
        today: '',
        outside:
          'text-muted-foreground opacity-50 bg-background hover:opacity-100',
        disabled: 'text-muted-foreground opacity-50 bg-background',
        hidden: 'invisible',
        ...classNames,
      }}
      components={{
        DayButton: CalendarDayButton,
        Chevron: (chevronProps) => {
          const { orientation, ...iconProps } = chevronProps
          const Icon =
            orientation === 'left'
              ? SvgTaillessLineArrowLeft1
              : SvgTaillessLineArrowRight1
          return <Icon {...iconProps} className="h-4 w-4" />
        },
        ...props.components,
      }}
      {...props}
    />
  )
}
Calendar.displayName = 'Calendar'

export { Calendar, CalendarDayButton, type DateRange }
