import { cleanup } from '@testing-library/react';
import { render } from '../../utils/theme-render-wrapper';
import { useEffect, useState } from 'react';
import noop from 'lodash/noop';
import { RightSideBarProvider, RightSideBar, useRightSideBar } from '.';

afterEach(cleanup);

const initMediaQueryTest = (
  width: number,
  isMatches: (query: string, width: number) => boolean
) => {
  Object.defineProperty(window, 'innerWidth', {
    writable: true,
    configurable: true,
    value: width
  });
  window.matchMedia = jest.fn().mockImplementation(query => {
    return {
      matches: isMatches?.(query, width),
      media: query,
      onchange: null,
      addListener: jest.fn(),
      removeListener: jest.fn()
    };
  });
};

const Wrapper = () => {
  const {
    addEventListener,
    displayDifComponent,
    handleComponentsArray,
    handleMainDrawer,
    setComponentSecondaryDrawer,
    setDrawerBehavior,
    setDrawerLocked,
    setShowDrawer
  } = useRightSideBar();
  const [listenerAttached, setListenerAttached] = useState(false);
  const [testIteration, setTestIteration] = useState(0);

  useEffect(() => {
    if (!listenerAttached) {
      addEventListener('open', noop);
      addEventListener('openSecondary', noop);
      addEventListener('open', noop); // add a duplicate event
      displayDifComponent(['Main Drawer Content']);
      setComponentSecondaryDrawer('Secondary Drawer Content 1');
      setComponentSecondaryDrawer('Secondary Drawer Content 2');
      setShowDrawer(true);
      setDrawerLocked(true);
      setListenerAttached(true);
    }
  }, [
    addEventListener,
    displayDifComponent,
    listenerAttached,
    setComponentSecondaryDrawer,
    setDrawerLocked,
    setShowDrawer
  ]);

  useEffect(() => {
    if (listenerAttached && testIteration < 3) {
      if (!testIteration) setDrawerBehavior();
      handleComponentsArray();
      handleMainDrawer();
      setTestIteration(testIteration + 1);
    }
  }, [handleComponentsArray, handleMainDrawer, listenerAttached, setDrawerBehavior, testIteration]);

  return <RightSideBar />;
};

describe('<RightSideBar />', () => {
  it('should render successfully', () => {
    const { baseElement } = render(
      <RightSideBarProvider>
        <RightSideBar />
      </RightSideBarProvider>
    );
    expect(baseElement).toBeTruthy();
  });

  it('should throw error when not wrapped inside RightSideBarProvider', () => {
    const consoleErrorFn = jest.spyOn(console, 'error').mockImplementation(() => jest.fn());
    expect(() => render(<RightSideBar />)).toThrow(
      'useRightSideBar must be used within a RightSideBarProvider'
    );
    consoleErrorFn.mockRestore();
  });

  it('should be rendered in a 1920px wide window', () => {
    initMediaQueryTest(1920, query => query === '(min-width:1439px)');
    const { container } = render(
      <RightSideBarProvider>
        <Wrapper />
      </RightSideBarProvider>
    );
  });
});
