import React, {
  DetailedHTMLProps,
  FC,
  forwardRef,
  useEffect,
  useState,
} from 'react';
import DatePicker from 'react-datepicker';
import './datepicker.css';
import css from './index.module.css';
import classNames from 'classnames';
import { registerLocale, setDefaultLocale } from 'react-datepicker';
import { de, frCH, enGB, it, fr } from 'date-fns/locale';

export interface MilaDatePickerProps {
  onChange?: (e) => void;
  onBlur?: (e) => void;
  onFocus?: (e) => void;
  label?: string;
  selected?: unknown;
  error?: unknown;
  hideError?: boolean;
  [x: string]: unknown;
  locale: string;
  disabled: boolean;
  filterDate?: (date: Date | number) => boolean;
}

const setupLocale = (locale: string): void => {
  switch (locale.substring(0, 2)) {
    case 'de':
      registerLocale(locale, de);
      setDefaultLocale(de);
      break;
    case 'en':
      registerLocale(locale, enGB);
      setDefaultLocale(enGB);
      break;
    case 'it':
      registerLocale(locale, it);
      setDefaultLocale(it);
      break;
    case 'fr':
      if (locale.includes('ch')) {
        registerLocale(locale, frCH);
        setDefaultLocale(fr);
      } else {
        registerLocale(locale, fr);
        setDefaultLocale(fr);
      }
      break;
    default:
      registerLocale(locale, enGB);
      setDefaultLocale(enGB);
      break;
  }
};

const MilaDatePicker: FC<MilaDatePickerProps> = props => {
  setupLocale(props.locale);
  const [isActive, setActive] = useState(props.selected != null);
  const [isDesktop, setDesktop] = useState(true);

  const updateMedia = (): void => {
    setDesktop(window.innerWidth > 700);
  };

  const datePickerClasses = classNames(css.datepicker, {
    [css.datepicker__active]: isActive,
    [css.datepicker__error]: props.error,
    [css.datepicker__disabled]: props.disabled,
  });

  const disableFocus = (): void => {
    if (props.selected == null || props.selected === '') {
      setActive(false);
    } else if (!isActive) {
      setActive(true);
    }
  };

  // Dont show keyboard on mobile
  const ref = React.createRef<HTMLInputElement>();
  const Input = forwardRef(
    (
      props: DetailedHTMLProps<unknown, unknown>,
      ref: React.Ref<HTMLInputElement>,
    ) => {
      return (
        <>
          <input {...props} ref={ref} readOnly />
        </>
      );
    },
  );
  Input.displayName = 'custom';

  useEffect(() => {
    setDesktop(window.innerWidth > 700);
  }, []);
  useEffect(() => {
    window.addEventListener('resize', updateMedia);
    return (): void => window.removeEventListener('resize', updateMedia);
  });

  useEffect(() => {
    disableFocus();
  }, [props.selected]);

  return (
    <div className={datePickerClasses}>
      <div className={css.datepicker__wrapper}>
        {props.label && <span className={css.input__label}>{props.label}</span>}
        <DatePicker
          {...{
            ...(!isDesktop && {
              withPortal: true,
              customInput: <Input ref={ref} />,
            }),
          }}
          {...props}
          autoComplete="off"
          type="string"
          onBlur={(e): void => {
            disableFocus();
            if (props.onBlur) props.onBlur(e);
          }}
          onFocus={(e): void => {
            setActive(true);
            if (props.onFocus) props.onFocus(e);
          }}
          onChange={(e): void => {
            setActive(true);
            if (props.onChange) props.onChange(e);
          }}
          calendarClassName={`${
            !isDesktop ? 'mila-picker mila-picker-mobile' : 'mila-picker'
          }`}
          locale={props.locale}
          filterDate={props.filterDate}
        />
      </div>

      {!props.hideError && props.error && (
        <div className={css.error}>{props.error}</div>
      )}
    </div>
  );
};
export default MilaDatePicker;
