import { shallow } from 'enzyme';
import { useIntl } from 'react-intl';

import { DateLookupWithoutInputAttributes as DateLookup } from './DateLookup';

jest.mock('react-intl');

// Tests for getDerivedStateFromProps results
describe('DateLookup state', () => {
  let component;
  let defaultProps;
  let initialValue;
  const defaultState = { selectedDate: null, min: null, max: null };

  beforeEach(() => {
    initialValue = new Date();
    defaultProps = { onChange: jest.fn(), value: initialValue };
    useIntl.mockReturnValue({ locale: 'en-GB' });
    component = shallow(<DateLookup {...defaultProps} />);
  });

  it('sets correct defaults', () => {
    const { selectedDate, min, max, viewMonth, viewYear, open, mode } = component.instance().state;
    expect(selectedDate).not.toBeNull();
    expect(min).toBeNull();
    expect(max).toBeNull();
    expect(viewMonth).not.toBeNull();
    expect(viewYear).not.toBeNull();
    expect(open).toBe(false);
    expect(mode).toBe('day');
  });

  it('does not update when date props did not change', () => {
    const props = { open: true };
    expect(DateLookup.getDerivedStateFromProps(props, defaultState)).toBeNull();
  });

  it('updates selectedDate on props value change', () => {
    const props = { value: new Date(2018, 11, 27) };
    const newState = DateLookup.getDerivedStateFromProps(props, defaultState);
    expect(Number(newState.selectedDate)).toBe(Number(new Date(2018, 11, 27)));
  });

  it('sets date values to midnight', () => {
    const props = {
      value: new Date(2018, 11, 27, 15, 23),
      min: new Date(2018, 10, 27, 22, 23),
      max: new Date(2018, 11, 28, 0, 30),
    };
    const newState = DateLookup.getDerivedStateFromProps(props, defaultState);
    expect(Number(newState.selectedDate)).toBe(Number(new Date(2018, 11, 27, 0, 0)));
    expect(Number(newState.min)).toBe(Number(new Date(2018, 10, 27, 0, 0)));
    expect(Number(newState.max)).toBe(Number(new Date(2018, 11, 28, 0, 0)));
  });

  it('calls onChange with min when it is < min', () => {
    const onChange = jest.fn();
    const props = { value: new Date(2018, 11, 27), min: new Date(2018, 11, 28), onChange };
    DateLookup.getDerivedStateFromProps(props, defaultState);
    expect(onChange).toHaveBeenCalledWith(new Date(2018, 11, 28));
  });

  it('calls onChange with max when it is > min', () => {
    const onChange = jest.fn();
    const props = { value: new Date(2018, 11, 27), max: new Date(2018, 10, 1), onChange };
    DateLookup.getDerivedStateFromProps(props, defaultState);
    expect(onChange).toHaveBeenCalledWith(new Date(2018, 10, 1));
  });

  it('updates viewMonth and viewYear to date within min/max on Clear', () => {
    const props = { value: null, min: new Date(2018, 11, 26), max: new Date(2018, 11, 26) };
    const newState = DateLookup.getDerivedStateFromProps(props, defaultState);
    expect(newState.viewMonth).toBe(11);
    expect(newState.viewYear).toBe(2018);
  });
});
