import React from 'react';
import { render, cleanup, waitFor, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';

import getNavigation from '~tests/factories/sections/navigationStatic.factory';

import NavigationProvider from '~organisms/navigation/navigationContext';
import { getMenuObj } from '~helpers/menu';
import Menu from '.';

let data;
let section;
let menus;

beforeEach(() => {
  data = getNavigation();
  section = {
    modules: [data],
  };
  menus = getMenuObj(section.modules, 'menu');
});
describe('Menu Component', () => {
  test('render menu and lists', async () => {
    const { container } = render(
      <NavigationProvider>
        <Menu section={section} />
      </NavigationProvider>
    );
    await waitFor(() => {
      expect(container).toBeTruthy();
      expect(container.querySelectorAll('.menuContainer > ul').length).toEqual(1);
      expect(container.querySelectorAll('.menuContainer > ul > li').length).toEqual(6);
      expect(container.querySelectorAll('ul')).toHaveLength(7);
      expect(container.querySelectorAll('.horizontal')).toHaveLength(1);
      expect(container.querySelectorAll('.collapseFull')).toHaveLength(1);
      expect(container.querySelectorAll('.collapse')).toHaveLength(0);
    });
  });
  test('render menu with other props - collapse mobile animation', async () => {
    const { container } = render(
      <NavigationProvider>
        <Menu section={section} mobileAnimation="collapse" />
      </NavigationProvider>
    );
    await waitFor(() => {
      expect(container.querySelectorAll('.horizontal')).toHaveLength(1);
      expect(container.querySelectorAll('.collapseFull')).toHaveLength(0);
      expect(container.querySelectorAll('.collapse')).toHaveLength(1);
    });
  });
  test('render menu with other props - slideLeft mobile animation', async () => {
    const { container } = render(
      <NavigationProvider>
        <Menu section={section} mobileAnimation="slideLeft" />
      </NavigationProvider>
    );
    await waitFor(() => {
      expect(container.querySelectorAll('.horizontal')).toHaveLength(1);
      expect(container.querySelectorAll('.collapseFull')).toHaveLength(0);
      expect(container.querySelectorAll('.slideLeft')).toHaveLength(1);
    });
  });
  test('render menu items', async () => {
    const { container } = render(
      <NavigationProvider>
        <Menu section={section} />
      </NavigationProvider>
    );
    await waitFor(() => {
      expect(container.querySelectorAll('.menuItem a')[0]).toHaveTextContent(
        menus.children[0].title
      );
      expect(
        container.querySelectorAll('.menuItem.level1')[3].querySelectorAll('.subMenuList')
      ).toHaveLength(5);
      expect(container.querySelectorAll('.menuItem a')[2]).toHaveTextContent(
        menus.children[1].children[0].title
      );
      expect(container.querySelectorAll('.menuItem a')[3]).toHaveTextContent(
        menus.children[2].title
      );
      expect(
        container.querySelectorAll('.menuItem')[8].querySelectorAll('.subMenuList')
      ).toHaveLength(1);
      expect(container.querySelectorAll('.menuItem a')[7]).toHaveTextContent(
        menus.children[3].children[0].title
      );
      expect(
        container.querySelectorAll('.menuItem')[7].querySelectorAll('.subMenuList')
      ).toHaveLength(0);
    });
  });
  test('test menu icon', async () => {
    const { container } = render(
      <NavigationProvider>
        <Menu section={section} />
      </NavigationProvider>
    );

    await waitFor(() => {
      expect(container.querySelectorAll('.menuIconContainer').length).toEqual(1);
      expect(container.querySelectorAll('.menuIcon')).toHaveLength(1);
    });
  });
  test('test menu icon click event', async () => {
    const { container } = render(
      <NavigationProvider>
        <Menu section={section} />
      </NavigationProvider>
    );
    const btn = container.querySelector('.menuIconContainer');
    expect(container.querySelectorAll('.menuIcon.active')).toHaveLength(0);
    fireEvent.click(btn);
    await waitFor(() => {
      expect(container.querySelectorAll('.menuIcon.active')).toHaveLength(1);
    });
  });
  test('test menu opening on menu icon click event', async () => {
    const { container } = render(
      <NavigationProvider>
        <Menu section={section} />
      </NavigationProvider>
    );
    const btn = container.querySelector('.menuIconContainer');
    expect(container.querySelectorAll('.menuList.show')).toHaveLength(0);
    fireEvent.click(btn);
    await waitFor(() => {
      expect(container.querySelectorAll('.menuList.show')).toHaveLength(1);
    });
  });
  test('test menu level classes', async () => {
    const { container } = render(
      <NavigationProvider>
        <Menu section={section} />
      </NavigationProvider>
    );
    await waitFor(() => {
      expect(container.querySelectorAll('.menuItem')[0]).toHaveClass('level1');
      expect(container.querySelectorAll('.menuItem')[2]).toHaveClass('level2');
      expect(container.querySelectorAll('.menuItem')[6]).toHaveClass('level3');
      expect(container.querySelectorAll('.menuItem')[17]).toHaveClass('level1');
      expect(container.querySelectorAll('.menuItem')[8]).toHaveClass('level2');
    });
  });
});
afterEach(() => {
  cleanup();
});
