import React, { useMemo } from 'react';
import { defineMessages, useIntl } from 'react-intl';

import IconButton from 'soapbox/components/icon-button';
import BundleContainer from 'soapbox/features/ui/containers/bundle-container';
import { DatePicker } from 'soapbox/features/ui/util/async-components';
import { useInstance, useFeatures } from 'soapbox/hooks';

const messages = defineMessages({
  birthdayPlaceholder: { id: 'edit_profile.fields.birthday_placeholder', defaultMessage: 'Your birthday' },
  previousMonth: { id: 'datepicker.previous_month', defaultMessage: 'Previous month' },
  nextMonth: { id: 'datepicker.next_month', defaultMessage: 'Next month' },
  previousYear: { id: 'datepicker.previous_year', defaultMessage: 'Previous year' },
  nextYear: { id: 'datepicker.next_year', defaultMessage: 'Next year' },
});

interface IBirthdayInput {
  value?: string
  onChange: (value: string) => void
  required?: boolean
}

const BirthdayInput: React.FC<IBirthdayInput> = ({ value, onChange, required }) => {
  const intl = useIntl();
  const features = useFeatures();
  const instance = useInstance();

  const supportsBirthdays = features.birthdays;
  const minAge = instance.pleroma.getIn(['metadata', 'birthday_min_age']) as number;

  const maxDate = useMemo(() => {
    if (!supportsBirthdays) return null;

    let maxDate = new Date();
    maxDate = new Date(maxDate.getTime() - minAge * 1000 * 60 * 60 * 24 + maxDate.getTimezoneOffset() * 1000 * 60);
    return maxDate;
  }, [minAge]);

  const selected = useMemo(() => {
    if (!supportsBirthdays || !value) return null;

    const date = new Date(value);
    return new Date(date.getTime() + (date.getTimezoneOffset() * 60000));
  }, [value]);

  if (!supportsBirthdays) return null;

  const renderCustomHeader = ({
    decreaseMonth,
    increaseMonth,
    prevMonthButtonDisabled,
    nextMonthButtonDisabled,
    decreaseYear,
    increaseYear,
    prevYearButtonDisabled,
    nextYearButtonDisabled,
    date,
  }: {
    decreaseMonth(): void
    increaseMonth(): void
    prevMonthButtonDisabled: boolean
    nextMonthButtonDisabled: boolean
    decreaseYear(): void
    increaseYear(): void
    prevYearButtonDisabled: boolean
    nextYearButtonDisabled: boolean
    date: Date
  }) => {
    return (
      <div className='flex flex-col gap-2'>
        <div className='flex items-center justify-between'>
          <IconButton
            className='datepicker__button rtl:rotate-180'
            src={require('@tabler/icons/chevron-left.svg')}
            onClick={decreaseMonth}
            disabled={prevMonthButtonDisabled}
            aria-label={intl.formatMessage(messages.previousMonth)}
            title={intl.formatMessage(messages.previousMonth)}
          />
          {intl.formatDate(date, { month: 'long' })}
          <IconButton
            className='datepicker__button rtl:rotate-180'
            src={require('@tabler/icons/chevron-right.svg')}
            onClick={increaseMonth}
            disabled={nextMonthButtonDisabled}
            aria-label={intl.formatMessage(messages.nextMonth)}
            title={intl.formatMessage(messages.nextMonth)}
          />
        </div>
        <div className='flex items-center justify-between'>
          <IconButton
            className='datepicker__button rtl:rotate-180'
            src={require('@tabler/icons/chevron-left.svg')}
            onClick={decreaseYear}
            disabled={prevYearButtonDisabled}
            aria-label={intl.formatMessage(messages.previousYear)}
            title={intl.formatMessage(messages.previousYear)}
          />
          {intl.formatDate(date, { year: 'numeric' })}
          <IconButton
            className='datepicker__button rtl:rotate-180'
            src={require('@tabler/icons/chevron-right.svg')}
            onClick={increaseYear}
            disabled={nextYearButtonDisabled}
            aria-label={intl.formatMessage(messages.nextYear)}
            title={intl.formatMessage(messages.nextYear)}
          />
        </div>
      </div>
    );
  };

  const handleChange = (date: Date) => onChange(date ? new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().slice(0, 10) : '');

  return (
    <div className='relative mt-1 rounded-md shadow-sm'>
      <BundleContainer fetchComponent={DatePicker}>
        {Component => (<Component
          selected={selected}
          wrapperClassName='react-datepicker-wrapper'
          onChange={handleChange}
          placeholderText={intl.formatMessage(messages.birthdayPlaceholder)}
          minDate={new Date('1900-01-01')}
          maxDate={maxDate}
          required={required}
          renderCustomHeader={renderCustomHeader}
          isClearable={!required}
        />)}
      </BundleContainer>
    </div>
  );
};

export default BirthdayInput;