import {Component, Element, h, Host, Listen, Prop, State} from '@stencil/core';

@Component({
  tag: 'hy-menu-level-container',
  styleUrl: 'menu-level-container.scss',
  shadow: false
})
export class MenuLevelContainer {
  @Element() el: HTMLElement;

  @State() open: boolean = false;
  @Prop() menuLevel: number;
  @Prop() menuType?: string;
  @Prop({mutable: true, reflect: true}) triggerItem: string;
  @Prop({mutable: true, reflect: true}) depth: number = 0;
  @Prop({reflect: true}) activeTrailTriggered: boolean = false;
  @Prop({mutable: true}) headingItem: any;

  // Add/Remove is-hidden class from each upper level menu-items
  // to make browsing more accessible.
  assignMenuItemClass(parentMenu: Element, type: string) {
    const items = Array.from(parentMenu.children);
    items.forEach((item) => {
      if (type === 'remove') {
        item.classList.remove('is-hidden');
      } else {
        item.classList.add('is-hidden');
      }
    });
  }

  @Listen('menuContainerActiveTrail', {target: 'document', capture: true})
  menuContainerActiveTrail(data) {
    const currentMenuContainer = this.el.getAttribute('trigger-item');
    if (currentMenuContainer === data.detail.triggerItem) {
      this.activeTrailTriggered = true;
      this.open = true;
      this.assignMenuItemClass(this.el.parentElement.closest('hy-menu-level-container'), 'add');
    }
  }

  @Listen('menuContainerToggled', {target: 'document', capture: true})
  menuContainerToggled(data) {
    // Toggle submenu.
    if (this.triggerItem == data.detail.triggerItem) {
      this.activeTrailTriggered = false;
      this.open = !this.open;
      this.assignMenuItemClass(this.el.parentElement.closest('hy-menu-level-container'), data.detail.triggerType);

      // Scroll to .hy-menu top.
      let hyMenu = this.el.parentElement.closest('hy-menu');
      hyMenu.shadowRoot.querySelector('.hy-menu').scrollTop = 0;
    }
  }

  componentWillUpdate() {
    if (this.menuType) {
      const items = Array.from(this.el.children);
      items.forEach((item) => {
        item.setAttribute('menu-type', this.menuType);
      });
    }
  }

  componentWillRender() {
    let parentMenu = this.el.closest('hy-menu-level-container');
    let nextParentMenu;
    this.depth = 0;
    while (parentMenu) {
      nextParentMenu = parentMenu.parentElement.closest('hy-menu-level-container');
      if (nextParentMenu === parentMenu) {
        break;
      } else {
        parentMenu = nextParentMenu;
        this.depth = this.depth + 1;
      }
    }

    // Set trigger item for each menu level container and handle only submenus.
    // Add a heading element foreach level.
    if (this.menuLevel > 1) {
      const parentMenuItem = this.el.closest('hy-menu-item');
      this.triggerItem = parentMenuItem.getAttribute('menu-link-id');
      this.headingItem = {...this.headingItem, url: parentMenuItem.getAttribute('url')};
      this.headingItem = {...this.headingItem, label: parentMenuItem.getAttribute('label')};
    } else {
      this.triggerItem = 'home';
    }
  }

  render() {
    let classAttributes = ['hy-menu-level-container', 'hy-menu-level-container--level-' + this.depth];

    if (this.menuType === 'desktop') {
      classAttributes = [...classAttributes, 'hy-menu--desktop'];

      return (
        <Host class={classAttributes.join(' ')}>
          <slot />
        </Host>
      );
    } else {
      classAttributes = [...classAttributes, 'hy-menu--mobile'];

      if (this.depth === 1) {
        this.open = true;
        classAttributes = [...classAttributes, this.open ? 'is-open' : null];

        return (
          <Host aria-expanded={this.open.toString()} class={classAttributes.join(' ')} tabindex={'-1'}>
            <slot />
          </Host>
        );
      } else {
        classAttributes = [...classAttributes, this.open ? 'is-open' : null];

        return (
          <Host aria-expanded={this.open.toString()} class={classAttributes.join(' ')} tabindex={'-1'}>
            <hy-menu-item
              label={this.headingItem.label}
              url={this.headingItem.url}
              isHeading={true}
              menu-type={'mobile'}
            />
            <slot />
          </Host>
        );
      }
    }
  }
}