export interface SearchTools {
  label: string;
  url: string;
  description: string;
  menuLinkId: string;
  isExternal: string;
}

export interface SearchLabels {
  label?: string;
}

declare global {
  interface Window {
    CludoSayt: any;
  }
}

import {Component, Prop, h, Watch, State, Listen, Host, Event, EventEmitter, Element} from '@stencil/core';
import {ComponentLabels} from '../site-header';
import {ColorVariant} from '../../../utils/utils';

@Component({
  tag: 'hy-site-search',
  styleUrl: 'site-search.scss',
  shadow: true,
})
export class SiteSearch {
  @Element() el: HTMLElement;

  @Prop() color: ColorVariant = ColorVariant.black;
  @Prop() isAlternative: boolean = false;
  @Prop() isGroup: boolean = false;
  @Prop() labels?: ComponentLabels[] | string;
  @Prop() searchLabels: string;
  @Prop() searchTools: string;
  private _searchTools: SearchTools[];

  @Prop() showLabel: boolean = false;
  @Prop() size: number;
  @Prop() dataSearchSpecialTools: string;

  private _searchLabels: SearchLabels[];
  private searchTitleLabel: string;
  private searchCloseLabel: string;
  private searchToolsLabel: string;
  private searchDescriptionLabel: string;

  @State() isSearchPanelOpen: boolean = false;
  @Event() searchPanelToggled: EventEmitter;

  private _labels: ComponentLabels[];

  @Watch('labels') labelsWatcher(data: ComponentLabels[] | string) {
    this._labels = typeof data === 'string' ? JSON.parse(data) : data;
  }

  componentWillLoad() {
    // Special search tools.
    if (this.searchTools) {
      this._searchTools = JSON.parse(this.searchTools);
    }

    if (this.searchLabels) {
      this._searchLabels = JSON.parse(this.searchLabels);

      this.searchTitleLabel = this._searchLabels['search_label'];
      this.searchCloseLabel = this._searchLabels['search_close_label'];
      this.searchToolsLabel = this._searchLabels['search_tools_label'];
      this.searchDescriptionLabel = this._searchLabels['search_description'];
    }
  }

  componentWillRender() {
    this.labelsWatcher(this.labels);
  }

  // CLose the search panel if user opens the desktop menu panel.
  @Listen('menuDesktopToggled', {target: 'document'})
  desktopMenuToggled() {
    this.closeSearchPanel();
  }

  // CLose the search panel if user opens the mobile menu panel.
  @Listen('menuMobileToggled', {target: 'document'})
  mobileMenuToggled() {
    this.closeSearchPanel();
  }

  // CLose the search panel if user opens the language menu.
  @Listen('menuLanguageToggled', {target: 'document'})
  menuLanguageToggled() {
    this.closeSearchPanel();
  }

  // Close the search panel if user opens University main menu
  @Listen('universityMainMenuToggled', {target: 'document'})
  universityMainMenuPanelToggled() {
    this.closeSearchPanel();
  }

  // CLose the search panel on Scroll down.
  @Listen('headerScrollDown', {target: 'document'})
  headerScrollDown() {
    this.closeSearchPanel();
  }

  closeSearchPanel() {
    this.isSearchPanelOpen = false;

    let cludoSayt = document.querySelectorAll('stencil-cludo-sayt')[0] as HTMLElement;
    if (cludoSayt) {
      let CludoSayt = window.CludoSayt;
      if (typeof CludoSayt !== 'undefined') {
        CludoSayt.hide();
      }
    }

    this.showBackdropShadow();
  }

  handleSearchPanelToggle(event) {
    this.isSearchPanelOpen = !this.isSearchPanelOpen;

    if (this.isSearchPanelOpen) {
      //const searchPanelSelector = this.el as HTMLElement;

      // Close desktop menu panel and lang menu panel if they are open.
      this.searchPanelToggled.emit();

      let hyHeader = this.el.closest('.hy-site-header') as HTMLElement;
      const headerHeight = hyHeader.classList.contains('hy-site-header--sticky-active')
        ? `${hyHeader.offsetHeight}px`
        : `${hyHeader.offsetTop + hyHeader.offsetHeight}px`;
      const searchPanel = this.el.shadowRoot.querySelectorAll(`.site-search__panel`)[0] as HTMLElement;
      searchPanel.style.top = headerHeight;

      // Remove hidden class from cludo suggestions
      let cludoSayt = document.querySelectorAll('stencil-cludo-sayt')[0] as HTMLElement;
      if (cludoSayt) {
        cludoSayt.classList.remove('hidden');
      }

      // Add shadow backdrop
      let rect = searchPanel.getBoundingClientRect();

      let shadowTop = hyHeader.classList.contains('hy-site-header--sticky-active')
        ? hyHeader.offsetHeight + rect.height
        : hyHeader.offsetTop + hyHeader.offsetHeight + rect.height;
      this.showBackdropShadow('open', shadowTop);

      // Without setTimeout it will not focus the input because it hasn't rendered yet.
      setTimeout(() => {
        const searchInput = this.el.shadowRoot.querySelector('input#search') as HTMLElement;
        searchInput.focus();
      });
    } else {
      this.closeSearchPanel();
    }
    event.stopPropagation();
  }

  showBackdropShadow(state = 'close', top = 0) {
    let hyHeader = this.el.closest('.hy-site-header') as HTMLElement;
    let hyBackdropDiv = hyHeader.children[0] as HTMLElement;

    if (hyBackdropDiv) {
      if (state === 'open') {
        let me = window.outerHeight - top;
        hyBackdropDiv.style.height = `${me}px`;
        hyBackdropDiv.style.top = `${top}px`;
        hyBackdropDiv.style.position = 'absolute';
        hyBackdropDiv.classList.add('is-active');
      } else {
        hyBackdropDiv.removeAttribute('style');
        hyBackdropDiv.classList.remove('is-active');
      }
    }
  }

  render() {
    return (
      <Host
        class={{
          'site-search': true,
          'site-search__is-open': this.isSearchPanelOpen,
        }}
      >
        <button
          aria-label={this._labels['open']}
          aria-expanded={`${this.isSearchPanelOpen}`}
          class={{
            'button--search': true,
            group: this.isGroup,
            'is-open--menu': this.isAlternative,
            'is-open': this.isSearchPanelOpen,
          }}
          onClick={(e) => this.handleSearchPanelToggle(e)}
        >
          {this.showLabel ? (
            <span class={{'button--search__label': true, 'button--search__label__group': this.isGroup}}>
              {this._labels['label']}
            </span>
          ) : (
            ''
          )}
          <hy-icon icon={'hy-icon-search'} size={this.size} fill={this.color} />
        </button>
        <div
          class={{
            'site-search__panel': true,
            'site-search__panel__is-open': this.isSearchPanelOpen,
          }}
          aria-hidden={`${!this.isSearchPanelOpen}`}
        >
          <div class="site-search__panel__wrapper">
            <div class="site-search__panel__title">
              <div class="site-search__panel__title__group">
                <h1>{this.searchTitleLabel}</h1>
                <div class="description">{this.searchDescriptionLabel}</div>
              </div>
            </div>
            <div id="cludo-search-results" class="container_12">
              <div class="search-banner"></div>
              <div class="search-filters search-filters-mobile"></div>

              <div class="col-md-12">
                <div style={{margin: '20px 0 32px'}} id="cludo-search-content-form">
                  <hy-search-field input-id="search" label=""></hy-search-field>
                </div>
              </div>

              <div class="col-md-3">
                <div class="search-filters" aria-controls="search-results"></div>
              </div>
              <div class="col-md-9">
                <div class="search-results-container">
                  <hy-paragraph-text>
                    <div class="search-result-count"></div>
                  </hy-paragraph-text>
                  <div class="search-did-you-mean" role="Complementary"></div>
                  <div class="search-results" role="region" id="search-results" aria-live="polite"></div>
                </div>
              </div>
            </div>

            {this._searchTools && this._searchTools.length > 0 && (
              <div class="site-search__panel__tools">
                <div class="title">{this.searchToolsLabel}</div>
                <div class="list">
                  {this._searchTools.map((i) => {
                    let searchToolTarget = i.isExternal ? '_blank' : '_self';
                    return (
                      <a class="search-special-tool" href={i.url} target={searchToolTarget}>
                        <hy-icon icon={'hy-icon-arrow-to-right'} size={14} fill={ColorVariant.black} />
                        <span class="label">{i.label}</span>
                        <span class="description">{i.description}</span>
                      </a>
                    );
                  })}
                </div>
              </div>
            )}
            <button
              onClick={() => this.closeSearchPanel()}
              class={{
                'site-search__panel__panel-toggle': true,
              }}
              aria-label={this.searchCloseLabel}
              aria-expanded={`${this.isSearchPanelOpen}`}
            >
              <span class="site-search__panel__panel-toggle__label">
                <span class="site-search__panel__panel-toggle__label__title" tabindex="0">
                  {this.searchCloseLabel}
                </span>
                <hy-icon icon={'hy-icon-remove'} size={16} fill={ColorVariant.black} />
              </span>
            </button>
          </div>
        </div>
      </Host>
    );
  }
}