import {Component, Element, Prop, Host, Listen, Event, h, EventEmitter} from '@stencil/core';
import {MenuItemVariants} from '../../utils/utils';

@Component({
  tag: 'hy-menu-item',
  styleUrl: 'menu-item.scss',
  shadow: true
})
export class MenuItem {
  @Element() el: HTMLElement;

  @Prop() variant: MenuItemVariants = MenuItemVariants.default;
  @Prop() inActiveTrail: boolean = false;
  @Prop() isActive: boolean = false;
  @Prop() isHeading: boolean = false;
  @Prop() menuItemAlternative: boolean = false;
  @Prop() menuLinkId: string = '';
  @Prop({mutable: true}) url: string = '';
  @Prop({mutable: true}) label: string = '';
  @Prop({mutable: true}) ariaExpanded: boolean = false;
  @Prop({mutable: true, reflect: true}) depth: number = 0;
  @Prop({mutable: true}) hasChildren: boolean = null;
  @Prop({mutable: true, reflect: true}) parentExpanded: boolean = false;
  @Prop({mutable: true}) parentAsHeading: string = '';

  @Event() routeClicked: EventEmitter;
  @Event() menuContainerToggled: EventEmitter;
  @Event() menuContainerActiveTrail: EventEmitter;
  @Event() addBreadcrumb: EventEmitter;

  @Listen('handleClick', {capture: true}) handleClick() {
    this.menuContainerToggled.emit({triggerItem: this.menuLinkId});
    const currentParent = this.el.parentNode;
    this.addBreadcrumb.emit({
      url: this.url,
      label: currentParent.parentElement.getAttribute('label'),
      bid: this.menuLinkId
    });
  }

  componentWillLoad() {
    // Notify breadcrumbs if item is in active trail.
    if (this.inActiveTrail && !this.isActive) {
      const currentParent = this.el.parentNode;
      this.addBreadcrumb.emit({
        url: this.url,
        label: currentParent.parentElement.getAttribute('label'),
        bid: this.menuLinkId
      });
    }

    // Trigger all parent menuLevelContainer elements in the same active-trail
    // to open the menu.
    if (this.isActive) {
      const getParents = (elem) => {
        let parents = [];
        while (elem.parentNode && elem.parentNode.nodeName.toLowerCase() != 'hy-menu-mobile') {
          elem = elem.parentNode;
          parents.push(elem);
        }
        return parents;
      };

      const parents = getParents(this.el);
      parents.forEach((element) => {
        if (element.tagName.toLowerCase() === 'hy-menu-item') {
          this.menuContainerActiveTrail.emit({triggerItem: element.getAttribute('menu-link-id')});
        }
      });
    }
  }

  componentWillRender() {
    this.hasChildren = !!this.el.hasChildNodes();
    let parentMenu = this.el.closest('hy-menu-item');
    let nextParentMenu;
    this.depth = 0;
    while (parentMenu) {
      nextParentMenu = parentMenu.parentElement.closest('hy-menu-item');
      if (nextParentMenu === parentMenu) {
        break;
      } else {
        if (nextParentMenu !== null) {
          this.parentAsHeading = nextParentMenu;
        }
        parentMenu = nextParentMenu;
        this.depth = this.depth + 1;
      }
    }
  }

  render() {
    return (
      <Host
        class={{
          'is-active': this.isActive,
          'menu-item--alternative': this.menuItemAlternative,
          'hy-menu-item': true
        }}
      >
        <a
          aria-current={this.isHeading.toString()}
          href={this.url}
          class={{
            'is-active': this.isActive,
            'in-active-trail': this.inActiveTrail,
            'is-heading': this.isHeading
          }}
        >
          <span class={'hy-menu-item__label'}>{this.label}</span>
        </a>

        {this.hasChildren && (
          <button
            // TODO: Fix aria-label translation.
            aria-haspopup={'true'}
            aria-label={`Open submenu for ${this.label}`}
            onClick={() => this.handleClick()}
            class={'hy-menu-item__button'}
          >
            <hy-icon icon={'hy-icon-caret-right'} size={12} />
          </button>
        )}

        {this.hasChildren && <slot />}
      </Host>
    );
  }
}