import { shallow } from 'enzyme';

import { mockMatchMedia } from '../test-utils';

import DateTrigger from './dateTrigger';
import DayCalendar from './dayCalendar';
import MonthCalendar from './monthCalendar';
import YearCalendar from './yearCalendar';

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

mockMatchMedia();

const defaultLocale = 'en-GB';
jest.mock('react-intl', () => ({
  injectIntl: (Component) =>
    function (props) {
      return <Component {...props} intl={{ locale: defaultLocale }} />;
    },
  useIntl: () => ({ locale: defaultLocale }),
  defineMessages: (translations) => translations,
}));

describe('DateLookup view', () => {
  const date = new Date(2018, 11, 27);
  const min = new Date(2018, 11, 26);
  const max = new Date(2018, 11, 28);
  let component;
  let props;

  beforeEach(() => {
    props = {
      value: date,
      min,
      max,
      size: 'lg',
      placeholder: 'Asd..',
      label: 'Date..',
      onChange: jest.fn(),
      id: '123456',
    };
    component = shallow(<DateLookup {...props} />);
  });

  it('shows open button', () => {
    expect(dateTrigger()).toHaveLength(1);
  });

  it('passes id to the component', () => {
    expect(component.prop('id')).toBe('123456');
  });

  it('passes props forward to open button', () => {
    expect(Number(dateTrigger().prop('selectedDate'))).toBe(Number(date));
    expect(dateTrigger().prop('size')).toBe('lg');
    expect(dateTrigger().prop('placeholder')).toBe('Asd..');
    expect(dateTrigger().prop('label')).toBe('Date..');
    expect(dateTrigger().prop('monthFormat')).toBe('long');
    expect(dateTrigger().prop('disabled')).toBe(false);
    expect(dateTrigger().prop('onClick')).toBe(component.instance().open);
    expect(dateTrigger().prop('children')).not.toBeNull();
  });

  it('passes onClear prop to open button', () => {
    component.setProps({ clearable: true });
    expect(dateTrigger().prop('onClear')).not.toBeNull();
  });

  describe('when in day mode', () => {
    beforeEach(() => {
      component.setState({ open: true, mode: 'day' });
    });

    it('renders day calendar', () => {
      expect(dayCalendar()).toHaveLength(1);
    });

    it('passes props forward to day calendar', () => {
      expect(Number(dayCalendar().prop('selectedDate'))).toBe(Number(date));
      expect(Number(dayCalendar().prop('min'))).toBe(Number(min));
      expect(Number(dayCalendar().prop('max'))).toBe(Number(max));
      expect(dayCalendar().prop('viewMonth')).toBe(11);
      expect(dayCalendar().prop('viewYear')).toBe(2018);
      expect(dayCalendar().prop('monthFormat')).toBe('long');
    });

    it('passes event handlers forward to day calendar', () => {
      expect(dayCalendar().prop('onSelect')).toBe(component.instance().handleSelectedDateUpdate);
      expect(dayCalendar().prop('onLabelClick')).toBe(component.instance().switchToYears);
      expect(dayCalendar().prop('onViewDateUpdate')).toBe(
        component.instance().handleViewDateUpdate,
      );
    });
  });

  describe('when in month mode', () => {
    beforeEach(() => {
      component.setState({ open: true, mode: 'month' });
    });

    it('renders month calendar', () => {
      expect(monthCalendar()).toHaveLength(1);
    });

    it('passes props forward to month calendar', () => {
      expect(Number(monthCalendar().prop('selectedDate'))).toBe(Number(date));
      expect(Number(monthCalendar().prop('min'))).toBe(Number(min));
      expect(Number(monthCalendar().prop('max'))).toBe(Number(max));
      expect(monthCalendar().prop('viewYear')).toBe(2018);
      expect(monthCalendar().prop('placeholder')).toBe('Asd..');
    });

    it('passes event handlers forward to month calendar', () => {
      expect(monthCalendar().prop('onSelect')).toBe(component.instance().switchToDays);
      expect(monthCalendar().prop('onLabelClick')).toBe(component.instance().switchToYears);
      expect(monthCalendar().prop('onViewDateUpdate')).toBe(
        component.instance().handleViewDateUpdate,
      );
    });
  });

  describe('when in year mode', () => {
    beforeEach(() => {
      component.setState({ open: true, mode: 'year' });
    });

    it('renders year calendar', () => {
      expect(yearCalendar()).toHaveLength(1);
    });

    it('passes props forward to year calendar', () => {
      expect(Number(yearCalendar().prop('selectedDate'))).toBe(Number(date));
      expect(Number(yearCalendar().prop('min'))).toBe(Number(min));
      expect(Number(yearCalendar().prop('max'))).toBe(Number(max));
      expect(yearCalendar().prop('viewYear')).toBe(2018);
      expect(yearCalendar().prop('placeholder')).toBe('Asd..');
    });

    it('passes event handlers forward to year calendar', () => {
      expect(yearCalendar().prop('onSelect')).toBe(component.instance().switchToMonths);
      expect(yearCalendar().prop('onViewDateUpdate')).toBe(
        component.instance().handleViewDateUpdate,
      );
    });
  });

  const dateTrigger = () => component.find(DateTrigger);
  const dayCalendar = () => component.find(DayCalendar);
  const monthCalendar = () => component.find(MonthCalendar);
  const yearCalendar = () => component.find(YearCalendar);
});
