/**
 * @module tgam-patterns-accordion
 */

import { toArray } from "./dom-methods";
import ee from "./event-emitter";
import EVENT_NAMES from "./event-names";

const accordionControlSelector = ".c-control--accordion";
const accordionSelector = ".c-accordion";
const accordionOpenClass = "c-accordion__item--open";
const hideArrowsIfNoChildren = true;

let accordionControl;
let selectedItem;

/**
 * @method init
 * @description init method, adds event listener for scroll and resize
 * @return {undefined}
 */
export default function init() {
  accordionControl = toArray(document.querySelectorAll(accordionControlSelector));

  accordionControl.forEach((el) => {
    if (hideArrowsIfNoChildren) {
      const accordionItem = el.parentElement.parentElement;
      const subAccordionList = accordionItem.querySelector(accordionSelector);
      const hasSubAccordion = subAccordionList !== null;
      if (!hasSubAccordion) {
        accordionItem.classList.add("c-accordion__item--empty");
      }
    }
  });

  const accordionContainer = document.querySelector(".c-accordion-top-level");
  accordionContainer && accordionContainer.addEventListener("click", onAccordionContainerClicked);
}

/**
 * @method onAccordionContainerClicked
 * @description callback for clicking on the accordion container
 * @param {MouseEvent} m - click event
 * @return {undefined}
 */
export function onAccordionContainerClicked(m) {
  const targetElement = m.target.parentElement;
  const isAccordionButton = targetElement.classList.contains("c-control--accordion");
  isAccordionButton && onAccordionClicked(targetElement, m);
}

/**
 * @method closeAllItems
 * @description removes all open classes
 * @return {undefined}
 */
export function closeAllItems() {
  const accordionItem = toArray(document.querySelectorAll(".c-accordion__item"));

  accordionItem.forEach((el) => {

    // only close accordion items that is not currently in focus
    el !== selectedItem && el.classList.remove(accordionOpenClass);
  });
}

/**
 * @method isRootAccordionItem
 * @description if element item contains an accordion level 2 return true
 * @param {HTMLElement} accordionItem
 * @return {boolean}
 */
export function isRootAccordionItem(accordionItem) {
  return accordionItem.querySelector(".c-accordion--level-2") !== null;
}

/**
 * @method onAccordionClicked
 * @description on accordion clicked
 * @param {HTMLElement} el c-control--accordion element
 * @param {MouseEvent} e click event
 * @return {undefined}
 */
export function onAccordionClicked(el, e) {
  const accordionItem = el.parentElement.parentElement;
  const subAccordionList = accordionItem.querySelector(accordionSelector);
  const buttonElement = el.querySelector(".c-control__button");
  const hasSubAccordion = subAccordionList !== null;
  const isOpen = hasSubAccordion && accordionItem.classList.contains(accordionOpenClass);

  // if clicking on a root accordion item, then close all other root level items
  if (isRootAccordionItem(accordionItem)) {
    selectedItem = accordionItem;
    closeAllItems();
  }

  if (hasSubAccordion && !isOpen) {
    accordionItem.classList.add(accordionOpenClass);
    buttonElement.setAttribute("aria-expanded", true);
  } else {
    accordionItem.classList.remove(accordionOpenClass);
    buttonElement.setAttribute("aria-expanded", false);
  }

  e.stopPropagation();

  ee.emit(EVENT_NAMES.accordion.clicked);
}
