/**
 * navigation.js
 */

import ElementHelpers from '../helpers/element-helpers';

/**
 * Declare constants
 */
const attributeBase = 'data-rs-navigation';

export class Navigation {
  constructor(element) {
    this.element = element;
    this.menuIcon = ElementHelpers.getElementByAttribute(
      this.attributes.menuIcon
    );
    this.modalMain = ElementHelpers.getElementByAttributeWithinElement(
      this.element,
      this.attributes.modalMain
    );
    this.collapsibles = ElementHelpers.getElementsByAttributeWithinElement(
      this.element,
      this.attributes.collapsible
    );
    this.toggables = ElementHelpers.getElementsByAttributeWithinElement(
      this.element,
      this.attributes.toggable
    );
    this.modalHeader = ElementHelpers.getElementByAttributeWithinElement(
      this.element,
      this.attributes.modalHeader
    );
    this.menuLabelsAttribute = ElementHelpers.getElementByAttribute(
      this.attributes.menuLabels
    );
    this.menuLabels = this.menuLabelsAttribute.getAttribute(
      this.attributes.menuLabels
    );
    this.scrollPos = 0;
    this.addEventHandlers();
  }

  /**
   * Declare classes
   */
  get classes() {
    return {
      hidden: 'hidden',
      modalOpen: 'modal-open',
      modalNavOpen: 'modal-nav-open',
      modalActive: 'modal--active',
      modalHeaderDivider: 'modal__header--divider',
      modalHeaderDividerIn: 'modal__header--divider-in',
      modalHeaderDividerOut: 'modal__header--divider-out',
      collapsibleTriggerExpanded: 'collapsible__trigger--expanded'
    };
  }

  /**
   * Declare attribute constants
   */
  get attributes() {
    return {
      ariaExpanded: 'aria-expanded',
      ariaHidden: 'aria-hidden',
      collapsibleContent: 'data-rs-collapsible-content',
      collapsible: 'data-rs-collapsible',
      toggable: 'data-rs-toggable',
      content: 'data-rs-collapsible-content',
      headerDivider: `${attributeBase}-header-divider`,
      menuIcon: `${attributeBase}-menu-icon`,
      menuLabels: `${attributeBase}-menu-labels`,
      modalMain: `${attributeBase}-modal-main`,
      modalHeader: `${attributeBase}-modal-header`
    };
  }

  get getMenuLabels() {
    const defaultLabels = {
      openMenu: 'open menu',
      closeMenu: 'close menu'
    };

    const labels = this.menuLabels
      ? JSON.parse(this.menuLabels)
      : defaultLabels;

    return labels;
  }

  /**
   * Add event handlers
   */
  addEventHandlers() {
    this.menuIcon.addEventListener('click', () => {
      // close all menu items on mobile when menu is closed

      if (
        document
          .querySelector('html')
          .classList.contains(this.classes.modalOpen)
      ) {
        console.log('click');
        this.setMenuAriaLabelToOpen();
        setTimeout(() => {
          this.closeCollapsible();
        }, 500);
      } else {
        this.setMenuAriaLabelToClose();
      }

      // add classes to HTML
      document
        .querySelector('html')
        .classList.toggle(`${this.classes.modalOpen}`);
      document
        .querySelector('html')
        .classList.toggle(`${this.classes.modalNavOpen}`);
      // add active classes to modal
      this.element.classList.toggle(`${this.classes.modalActive}`);

      // remove animated border classes on modal
      const modalHeaderDivider =
        ElementHelpers.getElementByAttributeWithinElement(
          this.element,
          this.attributes.headerDivider
        );
      if (modalHeaderDivider !== null) {
        modalHeaderDivider.classList.remove(
          `${this.classes.modalHeaderDividerIn}`
        );
        modalHeaderDivider.classList.remove(
          `${this.classes.modalHeaderDividerOut}`
        );
      }
    });

    this.modalMain.addEventListener(
      'scroll',
      () => {
        this.checkPosition();
      },
      { passive: true }
    );
  }

  setMenuAriaLabelToOpen() {
    this.menuLabelsAttribute.setAttribute(
      'aria-label',
      this.getMenuLabels.openMenu
    );
  }

  setMenuAriaLabelToClose() {
    this.menuLabelsAttribute.setAttribute(
      'aria-label',
      this.getMenuLabels.closeMenu
    );
  }

  closeCollapsible() {
    this.collapsibles.forEach((element) => {
      this.content = element.parentElement.querySelector(
        `[${this.attributes.collapsibleContent}]`
      );
      element.classList.remove(this.classes.collapsibleTriggerExpanded);
      element.setAttribute(this.attributes.ariaExpanded, 'false');
      element.removeAttribute(this.attributes.expanded);
      this.content.style.maxHeight = '0px';
      this.content.setAttribute(this.attributes.content, '');
      this.content.setAttribute(this.attributes.ariaHidden, 'true');
    });

    this.toggables.forEach((element) => {
      element.classList.remove('icon__toggler--active');
    });
  }

  /**
   * Check position
   */
  checkPosition() {
    const modalMainY = this.modalMain.scrollTop;
    if (modalMainY > this.scrollPos) {
      this.modalHeader.classList.add(this.classes.modalHeaderDivider);
      this.modalHeader.setAttribute(this.attributes.headerDivider, '');
      this.modalHeader.classList.add(this.classes.modalHeaderDividerIn);
      this.modalHeader.classList.remove(this.classes.modalHeaderDividerOut);
    }
    if (modalMainY === 0) {
      this.modalHeader.classList.add(this.classes.modalHeaderDividerOut);
      this.modalHeader.classList.remove(this.classes.modalHeaderDivider);
      this.modalHeader.removeAttribute(this.attributes.headerDivider);
      this.modalHeader.classList.remove(this.classes.modalHeaderDividerIn);
    }
  }

  /**
   * Get selector
   */
  static getSelector() {
    return `[${attributeBase}]`;
  }
}
