/**
 * 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.modalHeader = ElementHelpers.getElementByAttributeWithinElement(
      this.element,
      this.attributes.modalHeader
    );
    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',
      content: 'data-rs-collapsible-content',
      headerDivider: `${attributeBase}-header-divider`,
      menuIcon: `${attributeBase}-menu-icon`,
      modalMain: `${attributeBase}-modal-main`,
      modalHeader: `${attributeBase}-modal-header`
    };
  }

  /**
   * Add event handlers
   */
  addEventHandlers() {
    this.menuIcon.addEventListener('click', () => {
      // close all menu items on mobile when menu is closed
      document
        .querySelector('html')
        .classList.contains(this.classes.modalOpen) &&
        setTimeout(() => this.closeCollapsible(), 500);
      // 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 }
    );
  }

  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');
    });
  }

  /**
   * 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}]`;
  }
}
