export interface Breadcrumb {
  url: string;
  text: string;
}
let breadcrumbsWidth = null;
import {Component, Element, h, Listen, Prop, State, Watch} from '@stencil/core';
import {BreadcrumbVariants} from '../../utils/utils';

@Component({
  tag: 'hy-breadcrumbs',
  styleUrl: 'hy-breadcrumbs.scss',
  shadow: false,
})
export class HyBreadcrumbs {
  private _dataItems: Breadcrumb[];
  @Prop() dataItems: Breadcrumb[] | string;
  @Prop() variant: BreadcrumbVariants = BreadcrumbVariants.default as any;
  @Prop() headerstyle: string = 'with-sidebar';

  @State() menuOpen: boolean = false;
  @Element() el: HTMLElement;

  @Watch('dataItems')
  arrayDataWatcher(newValue: Breadcrumb[] | string) {
    if (typeof newValue === 'string') {
      this._dataItems = JSON.parse(newValue);
    } else {
      this._dataItems = newValue;
    }
  }
  componentWillLoad() {
    this.arrayDataWatcher(this.dataItems);
  }

  componentDidLoad() {
    let hyMainDiv = this.el.closest('.hy-main');
    if (hyMainDiv) {
      if (!hyMainDiv.classList.contains('with-sidebar')) {
        this.headerstyle = 'without-sidebar';
      }
    }

    // Set breadcumbs width + paddings.
    breadcrumbsWidth = this.el.offsetWidth + 64;
    const layoutContentElement = document.getElementsByClassName('layout-content')[0] as HTMLElement;
    const moreButton = document.querySelectorAll('.breadcrumb-item-dropdown-button')[0];
    if (layoutContentElement) {
      if (breadcrumbsWidth >= layoutContentElement.offsetWidth) {
        moreButton.setAttribute('aria-hidden', 'false');
        this.adjustBreadcrumbsMenuVisibility();
      }
    }
  }

  adjustBreadcrumbsMenuVisibility(showMenu = true) {
    // Show ... and Hide intermediate links
    if (!showMenu) {
      this.closeMoreMenu();
    }

    const crumbContainer = document.querySelectorAll('.hy-breadcrumbs')[0];
    const moreDotsItem = document.querySelectorAll('#more')[0];
    const moreDotsItemWrapper = document.querySelectorAll('.breadcrumb-item__more')[0];
    if (moreDotsItem) {
      if (showMenu) {
        crumbContainer.classList.add('is-condensed');
        moreDotsItem.classList.add('visible');
        moreDotsItemWrapper.classList.add('visible');
      } else {
        crumbContainer.classList.remove('is-condensed');
        moreDotsItem.classList.remove('visible');
        moreDotsItemWrapper.classList.remove('visible');
      }
    }

    const intermediateItems = document.querySelectorAll('.intermediate');
    if (intermediateItems) {
      for (let i = 0; i < intermediateItems.length; i++) {
        if (showMenu) {
          intermediateItems[i].classList.add('hidden');
        } else {
          intermediateItems[i].classList.remove('hidden');
        }
      }
    }
  }

  HomeItem(url) {
    const homeItemClass = ['hy-icon-wrapper', this.variant].join(' ');
    return (
      <li class="breadcrumb-item home">
        <a href={url} class={homeItemClass}>
          <hy-icon icon={'hy-icon-home'} class={`${this.variant}`} size={16} />
        </a>
        <span class="breadcrumb-item__divider">/</span>
      </li>
    );
  }

  BreadcrumbItem(label, url, className = '', withCaret = true) {
    const breadcrumbClass = ['breadcrumb-item', className].join(' ');
    if (url) {
      if (withCaret) {
        return (
          <li class={breadcrumbClass}>
            <a href={url} class={`${this.variant}`}>
              {label}
            </a>
            <span class="breadcrumb-item__divider">/</span>
          </li>
        );
      } else {
        return (
          <li class={breadcrumbClass}>
            <a href={url} class={`${this.variant}`}>
              {label}
            </a>
          </li>
        );
      }
    } else {
      return (
        <li class={`${breadcrumbClass} breadcrumb-item__current`}>
          <a aria-current="page" href={url} class={`${this.variant}`}>
            {label.length > 20 ? `${label.substring(0, 19)}...` : label}
          </a>
        </li>
      );
    }
  }

  BreadcrumbTextItem(label, className = '') {
    const breadcrumbClass = ['breadcrumb-item', className].join(' ');
    return <li class={breadcrumbClass}>{label}</li>;
  }

  DropdownMenuItem(items) {
    return (
      <li class="breadcrumb-item__more">
        <button
          type="button"
          aria-hidden="true"
          aria-expanded="false"
          id="more"
          key="more"
          class="breadcrumb-item-dropdown-button"
          aria-label="Open breadcrumb navigation"
        >
          <span class="breadcrumb-item-dropdown-button__content">
            {/* Span is for ... */}
            <span></span>
            <hy-icon
              icon={'hy-icon-caret-right'}
              class={'breadcrumb-item-caret__drop breadcrumb-item__more__icon'}
              size={10}
            />
          </span>
        </button>
        <ol class="breadcrumb-hidden-items" aria-hidden="true">
          {items}
        </ol>
        <span class="breadcrumb-item__divider">/</span>
      </li>
    );
  }

  adjustHiddenMenuWidth() {
    // set width to the menu area equal to the widest link + paddings
    const moreMenu = document.querySelectorAll('.breadcrumb-hidden-items')[0];
    if (moreMenu) {
      if (document.body.scrollWidth < 480) {
        (moreMenu as HTMLElement).style.width = '100%';
      } else {
        //maxIntermediateLinkWidth
        var maxIntermediateLinkWidth = 0;
        const moreMenuLinks = document.querySelectorAll('.breadcrumb-hidden-items .breadcrumb-item a');
        if (moreMenuLinks) {
          for (let i = 0; i < moreMenuLinks.length; i++) {
            if (maxIntermediateLinkWidth < (moreMenuLinks[i] as HTMLElement).offsetWidth) {
              maxIntermediateLinkWidth = (moreMenuLinks[i] as HTMLElement).offsetWidth;
            }
          }
          maxIntermediateLinkWidth = maxIntermediateLinkWidth + 32 + 64;
        }
        (moreMenu as HTMLElement).style.width = maxIntermediateLinkWidth.toString().concat('px');
      }
    }
  }

  closeMoreMenu() {
    const moreMenu = document.querySelectorAll('.breadcrumb-hidden-items')[0];
    if (moreMenu) {
      moreMenu.classList.remove('breadcrumb-hidden-items__is-open');
      this.menuOpen = false;
    }
    const moreBreadcrumb = document.querySelectorAll('#more')[0];
    if (moreBreadcrumb) {
      moreBreadcrumb.classList.remove('is-open');
    }
  }

  // When a ... is clicked, show/hide the Menu with hidden breadcrumbs
  @Listen('click')
  clickEventListener(event) {
    if (!event) return;

    const target = event.target;
    const moreMenu = document.querySelectorAll('.breadcrumb-hidden-items')[0];
    const moreButton = document.querySelectorAll('.breadcrumb-item-dropdown-button')[0];

    // Trigger if target is button or svg icon
    // TODO: Make this if prettier
    if (
      target &&
      (target.id === 'more' ||
        ((target.tagName == 'svg' || 'path') &&
          target.closest('hy-icon').classList.contains('breadcrumb-item__more__icon')))
    ) {
      //@todo Show the menu on the right place of the screen
      if (moreMenu) {
        if (this.menuOpen) {
          moreMenu.classList.remove('breadcrumb-hidden-items__is-open');
          moreMenu.setAttribute('aria-hidden', 'true');
          moreButton.classList.remove('is-open');
          moreButton.setAttribute('aria-expanded', 'false');
        } else {
          moreMenu.classList.add('breadcrumb-hidden-items__is-open');
          moreButton.classList.add('is-open');
          moreMenu.setAttribute('aria-hidden', 'false');
          moreButton.setAttribute('aria-expanded', 'true');
        }
        this.menuOpen = !this.menuOpen;
      }
    } else {
      this.closeMoreMenu();
    }

    event.stopPropagation();
    event.stopImmediatePropagation();
  }

  @Listen('resize', {target: 'window'})
  resizeEventListener(event) {
    if (!event) return;

    const breadcrumbsElement = document.querySelectorAll('.hy-breadcrumbs')[0];
    const moreButton = document.querySelectorAll('.breadcrumb-item-dropdown-button')[0];

    if (breadcrumbsElement) {
      if (breadcrumbsWidth + 64 >= document.body.scrollWidth) {
        moreButton.setAttribute('aria-hidden', 'false');
        this.adjustBreadcrumbsMenuVisibility();
      } else {
        moreButton.setAttribute('aria-hidden', 'true');
        this.adjustBreadcrumbsMenuVisibility(false);
      }
    }
  }

  render() {
    //@todo Accesibility
    const TOTAL_ITEMS = this._dataItems.length;
    const MAX_ITEMS_TO_SHOW = 3;

    let isMenuNeeded = TOTAL_ITEMS > MAX_ITEMS_TO_SHOW;

    let itemsBreadcrumbs = [];
    let itemsToShowInMenu = [];

    if (this.variant == BreadcrumbVariants.landingLarge) {
      // Landing pages, Large variant
      this._dataItems.map((x, index) => {
        if (index < 2) {
          if (index == 0) {
            itemsBreadcrumbs.push(this.HomeItem(x.url));
          } else {
            itemsBreadcrumbs.push(this.BreadcrumbItem(x.text, '', 'main'));
          }
        }
      });
    } else {
      // Landing and Content pages, Standard variant
      this._dataItems.map((x, index) => {
        let breadcrumbEl = this.BreadcrumbItem(x.text, x.url, '', false);

        if (isMenuNeeded && index > 0 && index < TOTAL_ITEMS - 1) {
          itemsToShowInMenu.push(<li>{breadcrumbEl}</li>);
          itemsBreadcrumbs.push(this.BreadcrumbItem(x.text, x.url, 'intermediate'));
          return;
        } else {
          if (index == 0) {
            itemsBreadcrumbs.push(this.HomeItem(x.url));
          } else {
            itemsBreadcrumbs.push(this.BreadcrumbItem(x.text, x.url, 'main'));
          }
        }
      });
    }

    // Add items to show in breadcrumb popup in correct DOM position.
    itemsBreadcrumbs.splice(1, 0, this.DropdownMenuItem(itemsToShowInMenu));

    const breadcrumbsClass = ['hy-breadcrumbs', this.variant, this.headerstyle].join(' ');

    return (
      <nav aria-label="Breadcrumb" role="navigation" aria-labelledby="system-breadcrumb" class={breadcrumbsClass}>
        <ol class="breadcrumb-container">{itemsBreadcrumbs}</ol>
      </nav>
    );
  }
}