import {
  CalendarDate,
  DateValue,
  getLocalTimeZone,
  parseAbsolute,
} from '@internationalized/date';
import {Fragment, memo, useEffect, useState} from 'react';
import {useDateFormatter} from './use-date-formatter';
import {shallowEqual} from '../utils/shallow-equal';
import {useSettings} from '../core/settings/use-settings';

export const DateFormatPresets: Record<string, Intl.DateTimeFormatOptions> = {
  numeric: {year: 'numeric', month: '2-digit', day: '2-digit'},
  short: {year: 'numeric', month: 'short', day: '2-digit'},
  long: {month: 'long', day: '2-digit', year: 'numeric'},
};

interface FormattedDateTimeRangeProps {
  start?: string | DateValue | Date;
  end?: string | DateValue | Date;
  options?: Intl.DateTimeFormatOptions;
}
export const FormattedDateTimeRange = memo(
  ({start, end, options}: FormattedDateTimeRangeProps) => {
    const {dates} = useSettings();
    const formatter = useDateFormatter(
      options || DateFormatPresets[dates?.format || 'short']
    );

    const [formatted, setFormatted] = useState<string>();

    useEffect(() => {
      if (!start || !end) {
        setFormatted('');
        return;
      }
      try {
        setFormatted(formatter.formatRange(castToDate(start), castToDate(end)));
      } catch {}
    }, [start, end, formatter]);

    return <Fragment>{formatted}</Fragment>;
  },
  shallowEqual
);

function castToDate(date: string | DateValue | Date): Date {
  if (date instanceof CalendarDate) {
    return date.toDate(getLocalTimeZone());
  }
  if (typeof date === 'string') {
    return parseAbsolute(date, getLocalTimeZone()).toDate();
  }
  return date as Date;
}
