import {
  DateRangePicker as AriaDateRangePicker,
  Button,
  Dialog,
  Group,
  OverlayArrow,
  Popover,
} from 'react-aria-components';

import dayjs from 'dayjs';
import { tv } from 'tailwind-variants';

import { CalendarIcon } from '@/components/icons';

import { RangeCalendar } from '../calendar/RangeCalendar';
import { calendarDateToDate, dateToCalendarDate } from '../calendar/utils';

const trigger = tv({
  base: 'flex h-9 w-[260px] cursor-pointer items-center border border-kc-gray-be bg-white text-left outline-none transition',
  variants: {
    isHovered: {
      true: 'border-kc-black-34',
    },
    isFocused: {
      true: 'border-kc-black-34',
    },
    isDisabled: {
      true: 'cursor-default border-kc-gray-99 bg-kc-gray-eb',
    },
    isFocusVisible: {
      true: 'ring-2 ring-offset-2 ring-primary',
    },
  },
});

export type DateRangePickerProps = {
  value: { start: Date; end: Date } | null;
  onChange: (value: { start: Date; end: Date } | null) => void;
  maxValue?: Date | null;
  minValue?: Date | null;
  isDisabled?: boolean;
  className?: string;
  startName?: string;
  endName?: string;
};

export function DateRangePicker({
  value,
  onChange,
  maxValue,
  minValue,
  isDisabled,
  className,
  startName,
  endName,
}: DateRangePickerProps) {
  const ariaValue = value ? { start: dateToCalendarDate(value.start)!, end: dateToCalendarDate(value.end)! } : null;

  return (
    <AriaDateRangePicker
      aria-label="날짜 범위 선택"
      value={ariaValue}
      onChange={(range) => {
        if (!range) {
          onChange(null);
        } else {
          onChange({
            start: calendarDateToDate(range.start)!,
            end: calendarDateToDate(range.end)!,
          });
        }
      }}
      maxValue={maxValue !== undefined ? dateToCalendarDate(maxValue) : undefined}
      minValue={minValue !== undefined ? dateToCalendarDate(minValue) : undefined}
      isDisabled={isDisabled}
      granularity="day"
      firstDayOfWeek="sun"
      className={className}
      startName={startName}
      endName={endName}
    >
      <Group>
        <Button className={(renderProps) => trigger(renderProps)}>
          <span className={`tabular-nums px-3 text-sm ${value?.start ? 'text-kc-black-34' : 'text-kc-gray-99'}`}>
            {value?.start ? dayjs(value.start).format('YYYY. MM. DD') : 'YYYY.MM.DD'}
          </span>
          <span className="text-sm text-kc-gray-99">~</span>
          <span className={`tabular-nums flex-1 px-3 text-sm ${value?.end ? 'text-kc-black-34' : 'text-kc-gray-99'}`}>
            {value?.end ? dayjs(value.end).format('YYYY. MM. DD') : 'YYYY.MM.DD'}
          </span>
          <span className="flex h-full w-8 shrink-0 items-center justify-center text-kc-gray-99">
            <CalendarIcon className="h-4 w-4" />
          </span>
        </Button>
      </Group>
      <Popover className="bg-white border border-kc-gray-be p-3 px-6 pb-6 drop-shadow-modal outline-none" offset={12}>
        <OverlayArrow className="group/arrow">
          <svg
            width="12"
            height="8"
            viewBox="0 0 12 8"
            className="block fill-white stroke-kc-gray-be group-data-[placement=bottom]/arrow:rotate-180"
          >
            <path d="M0 0 L6 8 L12 0" />
          </svg>
        </OverlayArrow>
        <Dialog className="outline-none">
          <RangeCalendar />
        </Dialog>
      </Popover>
    </AriaDateRangePicker>
  );
}
