import React, {useState, useEffect} from 'react';
import PropTypes from 'prop-types';
import Button, {BUTTON_TYPE} from '@propellerads/button';
import {
  Date,
  COLOR,
  SIZE,
} from '@propellerads/icon';
import ArrowButton, {ARROW_TYPE} from '@propellerads/arrow-button';
import {
  START_DATE,
  END_DATE,
} from 'react-dates/constants';

import DatePickerInput from '../DatePickerInput';

import {getInputValue, getNextDatePeriod, getPreviousDatePeriod} from '../helpers';

import DEFAULT_PRESET_PROPS from '../defaultProps';

import {
  StyledDatePickerControls,
  DatePickerControlsButton,
  DatePickerControlsFields,
  DatePickerControlsFast,
} from './style';

const KEY_ENTER = 13;
const KEY_ESC = 27;

const DatePickerControls = (props) => {
  const {
    elementId,
    onStartDateInputFocus,
    onStartDateInputBlur,
    onEndDateInputFocus,
    onEndDateInputBlur,
    activePreset,
    onArrowButtonClick,
    onStartDateInputChange,
    onEndDateInputChange,
    onEnterKeyDown,
    onEscKeyDown,
    startDatePlaceholderText,
    endDatePlaceholderText,
    startDate,
    endDate,
    disabled,
    isExpanded,
    isShowFastControl,
  } = props;

  const [startValue, changeStartValue] = useState(startDate);
  const [endValue, changeEndValue] = useState(endDate);

  const isDisabled = disabled === true;

  useEffect(() => {
    changeStartValue(startDate);
  }, [startDate, isExpanded]);

  useEffect(() => {
    changeEndValue(endDate);
  }, [endDate, isExpanded]);

  function onStartDateInputInnerChange(value) {
    changeStartValue(value);
    onStartDateInputChange(value);
  }

  function onEndDateInputInnerChange(value) {
    changeEndValue(value);
    onEndDateInputChange(value);
  }

  function onFastControlsPreviousButtonClick() {
    onArrowButtonClick(getPreviousDatePeriod(startDate, endDate));
  }

  function onFastControlsNextButtonClick() {
    onArrowButtonClick(getNextDatePeriod(startDate, endDate));
  }

  function resetOnLastState() {
    changeStartValue(startDate);
    changeEndValue(endDate);
  }

  function onStartDateKeyDown(event) {
    if (event.keyCode === KEY_ENTER) {
      onStartDateInputInnerChange(event.target.value);
      onEnterKeyDown();
      event.target.blur();
      event.preventDefault();
    }

    if (event.keyCode === KEY_ESC) {
      resetOnLastState();
      onEscKeyDown();
      event.target.blur();
      event.preventDefault();
    }
  }

  function onEndDateKeyDown(event) {
    if (event.keyCode === KEY_ENTER) {
      onEndDateInputInnerChange(event.target.value);
      onEnterKeyDown();
      event.target.blur();
      event.preventDefault();
    }

    if (event.keyCode === KEY_ESC) {
      resetOnLastState();
      onEscKeyDown();
      event.target.blur();
      event.preventDefault();
    }
  }

  return (
    <StyledDatePickerControls
      isExpanded={isExpanded}
      isDisabled={isDisabled}
    >
      <Button
        type={BUTTON_TYPE.PLAIN}
        onClick={onStartDateInputFocus}
        elementId={`${elementId}-controls-button`}
      >
        <DatePickerControlsButton
          withIcon={!activePreset}
          isDisabled={isDisabled}
        >
          {(activePreset && activePreset.label) || (
            <Date
              size={SIZE.SMALL}
              color={COLOR.GRAY}
            />
          )}
        </DatePickerControlsButton>
      </Button>

      <DatePickerControlsFields>
        <DatePickerInput
          onChange={onStartDateInputInnerChange}
          onFocus={onStartDateInputFocus}
          onBlur={onStartDateInputBlur}
          onKeyDown={onStartDateKeyDown}
          id={`${elementId}-start-date`}
          value={getInputValue(startValue)}
          placeholder={startDatePlaceholderText}
          isDisabled={isDisabled || disabled === START_DATE}
        />
        {' \u2013 '}
        <DatePickerInput
          onChange={onEndDateInputInnerChange}
          onFocus={onEndDateInputFocus}
          onBlur={onEndDateInputBlur}
          onKeyDown={onEndDateKeyDown}
          id={`${elementId}-end-date`}
          value={getInputValue(endValue)}
          placeholder={endDatePlaceholderText}
          isDisabled={isDisabled || disabled === END_DATE}
        />
      </DatePickerControlsFields>

      {isShowFastControl && activePreset && !disabled && (
        <DatePickerControlsFast>
          <ArrowButton
            elementId={`${elementId}-fast-controls-previous`}
            onClick={onFastControlsPreviousButtonClick}
            type={ARROW_TYPE.PREVIOUS}
          />
          <ArrowButton
            elementId={`${elementId}-fast-controls-next`}
            onClick={onFastControlsNextButtonClick}
            type={ARROW_TYPE.NEXT}
          />
        </DatePickerControlsFast>
      )}
    </StyledDatePickerControls>
  );
};

DatePickerControls.propTypes = {
  activePreset: PropTypes.shape(DEFAULT_PRESET_PROPS),
  elementId: PropTypes.string.isRequired,
  onStartDateInputFocus: PropTypes.func.isRequired,
  onStartDateInputBlur: PropTypes.func.isRequired,
  onEndDateInputFocus: PropTypes.func.isRequired,
  onEndDateInputBlur: PropTypes.func.isRequired,
  onArrowButtonClick: PropTypes.func.isRequired,
  onStartDateInputChange: PropTypes.func.isRequired,
  onEndDateInputChange: PropTypes.func.isRequired,
  onEnterKeyDown: PropTypes.func.isRequired,
  onEscKeyDown: PropTypes.func.isRequired,
  startDatePlaceholderText: PropTypes.string,
  endDatePlaceholderText: PropTypes.string,
  startDate: PropTypes.object,
  endDate: PropTypes.object,
  isExpanded: PropTypes.bool,
  isShowFastControl: PropTypes.bool,
  disabled: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf([START_DATE, END_DATE])]),
};

DatePickerControls.defaultProps = {
  activePreset: undefined,
  startDatePlaceholderText: undefined,
  endDatePlaceholderText: undefined,
  startDate: undefined,
  endDate: undefined,
  isExpanded: false,
  isShowFastControl: true,
  disabled: false,
};

export default DatePickerControls;
