import { mount } from 'enzyme';

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

import Drawer from '.';

mockMatchMedia();
jest.mock('../common');
jest.useFakeTimers();

jest.mock(
  '../dimmer',
  () =>
    function Dimmer({ open, children }) {
      return open ? <div className="dimmer">{children}</div> : null;
    },
);

jest.mock(
  '../slidingPanel',
  () =>
    function SlidingPanel({ open, children }) {
      return open ? <div className="sliding-panel">{children}</div> : null;
    },
);

const defaultLocale = 'en-GB';

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

describe('Drawer', () => {
  let component;
  const props = {
    open: true,
    position: 'left',
    onClose: jest.fn(),
    children: null,
    headerTitle: null,
    footerContent: null,
  };

  beforeEach(() => {
    component = mount(<Drawer {...props} />);
  });

  afterEach(() => {
    jest.clearAllMocks();
    component.unmount();
  });

  it('renders drawer header if title is provided', () => {
    expect(component.find('.np-drawer-header--title')).toHaveLength(0);
    component.setProps({ headerTitle: 'A title' });
    expect(component.find(Title)).toHaveLength(1);
    expect(component.find(Title).props().children).toBe('A title');
  });

  it('renders header with or without borders', () => {
    expect(component.find('.np-drawer-header--withborder')).toHaveLength(0);
    component.setProps({ headerTitle: 'A title' });
    expect(component.find('.np-drawer-header--withborder')).toHaveLength(1);
  });

  it('renders content if children are provided', () => {
    expect(component.find('.np-drawer-content')).toHaveLength(0);
    component.setProps({ children: 'SomeChildren' });
    expect(component.find('.np-drawer-content')).toHaveLength(1);
  });

  it('renders drawer footer if footerContent is provided', () => {
    expect(component.find('.np-drawer-footer')).toHaveLength(0);
    component.setProps({ footerContent: 'SomeContent' });
    expect(component.find('.np-drawer-footer')).toHaveLength(1);
  });

  it('passes onUnmount to Dimmer onExited prop', () => {
    const onUnmount = jest.fn();
    component.setProps({ onUnmount });
    component.setProps({ open: true });
    expect(component.find('Dimmer').prop('onExited')).toBe(onUnmount);
  });

  it('calls onUnmount when the component unmounts', () => {
    const onUnmount = jest.fn();
    component.setProps({ onUnmount });
    component.setProps({ open: true });
    expect(onUnmount).not.toHaveBeenCalled();
    jest.runAllTimers();
    component.setProps({ open: false });
    component.find('Dimmer').prop('onExited')();
    expect(onUnmount).toHaveBeenCalledTimes(1);
  });
});
