/* eslint-disable no-unused-expressions */
/* eslint-disable no-restricted-syntax */
import React, { useRef } from 'react';
import PropTypes from 'prop-types';
import keygen from '~helpers/keygen';
import Item from './item';
import styles from './items.module.scss';
import { getPositionClass, itemHasChildren } from '~helpers/menu';
import { isMobileDevice } from '~helpers/device-detect';

// Test included with menu molecule test
const Items = ({ item, menuListRef, gtmClass = '', level = 1, canOpenAllSubMenus = true }) => {
  let link;
  let menu;

  const parentMenuRef = useRef(null);
  const subMenuListRef = useRef(null);

  const closeOtherMenus = (target) => {
    const parentsWithOpenSubMenu = target.parentNode.getElementsByClassName(styles.showSubMenu)[0];
    const openSubmenus = parentsWithOpenSubMenu?.getElementsByClassName(styles.show)[0];

    if (parentsWithOpenSubMenu && parentsWithOpenSubMenu !== target) {
      // close other opened levels except the target
      parentsWithOpenSubMenu && parentsWithOpenSubMenu.classList.remove(styles.showSubMenu);
      openSubmenus && openSubmenus.classList.remove(styles.show);

      // if other levels have open submenus, close them too
      openSubmenus
        .getElementsByClassName(styles.showSubMenu)[0]
        ?.classList.remove(styles.showSubMenu);
      openSubmenus.getElementsByClassName(styles.show)[0]?.classList.remove(styles.show);
    }
  };

  const onClick = (e) => {
    const { target } = e;

    // check if multiple submenus can be opened at same time, if not close them
    if (!canOpenAllSubMenus) {
      closeOtherMenus(target);
    }

    // toggle the clicked menu item
    target.classList.toggle(styles.showSubMenu);
    target.getElementsByTagName('UL')[0]?.classList.toggle(styles.show);
  };

  if (item.children) {
    link = <Item item={item} gtmClass={gtmClass} />;
    menu = (
      <ul
        ref={subMenuListRef}
        className={`${styles.subMenuList || ''} ${
          itemHasChildren(item) ? styles.hasChildWithSubmenu || '' : ''
        }`}
      >
        {item.children.map((child) => (
          <Items
            key={keygen()}
            item={child}
            menuListRef={menuListRef}
            gtmClass={gtmClass}
            canOpenAllSubMenus={canOpenAllSubMenus}
            level={level + 1}
          />
        ))}
      </ul>
    );
  } else {
    link = <Item item={item} gtmClass={gtmClass} />;
  }
  return (
    <li
      ref={parentMenuRef}
      className={`${styles.menuItem || ''} ${styles[`level${level.toString()}`] || ''} 
      ${item.children !== undefined ? styles.hasChildren || '' : ''} 
      `}
      onFocus={(e) => getPositionClass(e.target, styles)}
      onMouseOver={(e) => getPositionClass(e.target, styles)}
      role="menuitem"
      tabIndex="0"
      onKeyDown={(e) => {
        if (isMobileDevice()) {
          if (e.defaultPrevented) return;
          e.preventDefault();
          onClick(e);
        }
      }}
      onClick={(e) => {
        if (isMobileDevice()) {
          if (e.defaultPrevented) return;
          e.preventDefault();
          onClick(e);
        }
      }}
    >
      {link}
      {menu}
    </li>
  );
};

Items.propTypes = {
  item: PropTypes.shape({
    title: PropTypes.string,
    value: PropTypes.string,
    children: PropTypes.arrayOf(
      PropTypes.shape({
        title: PropTypes.string,
        value: PropTypes.string,
      })
    ),
  }).isRequired,
  menuListRef: PropTypes.oneOfType([PropTypes.element, PropTypes.any]),
  gtmClass: PropTypes.string,
  level: PropTypes.number,
  canOpenAllSubMenus: PropTypes.bool,
};

export default Items;
