/**
 * @license
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import '@polymer/iron-dropdown/iron-dropdown';
import '../gr-button/gr-button';
import {GrButton} from '../gr-button/gr-button';
import '../gr-cursor-manager/gr-cursor-manager';
import '../gr-tooltip-content/gr-tooltip-content';
import '../../../styles/shared-styles';
import {flush} from '@polymer/polymer/lib/legacy/polymer.dom';
import {PolymerElement} from '@polymer/polymer/polymer-element';
import {htmlTemplate} from './gr-dropdown_html';
import {getBaseUrl} from '../../../utils/url-util';
import {IronDropdownElement} from '@polymer/iron-dropdown/iron-dropdown';
import {GrCursorManager} from '../gr-cursor-manager/gr-cursor-manager';
import {property, customElement, observe} from '@polymer/decorators';
import {addShortcut, Key} from '../../../utils/dom-util';

const REL_NOOPENER = 'noopener';
const REL_EXTERNAL = 'external';

declare global {
  interface HTMLElementEventMap {
    'opened-changed': CustomEvent;
  }
  interface HTMLElementTagNameMap {
    'gr-dropdown': GrDropdown;
  }
}

export interface GrDropdown {
  $: {
    dropdown: IronDropdownElement;
    trigger: GrButton;
  };
}

export interface DropdownLink {
  url?: string;
  name?: string;
  external?: boolean;
  target?: string | null;
  download?: boolean;
  id?: string;
  tooltip?: string;
}

interface DisableIdsRecord {
  base: string[];
}

export interface DropdownContent {
  text: string;
  bold?: boolean;
}

@customElement('gr-dropdown')
export class GrDropdown extends PolymerElement {
  static get template() {
    return htmlTemplate;
  }

  /**
   * Fired when a non-link dropdown item with the given ID is tapped.
   *
   * @event tap-item-<id>
   */

  /**
   * Fired when a non-link dropdown item is tapped.
   *
   * @event tap-item
   */

  @property({type: Array})
  items?: DropdownLink[];

  @property({type: Boolean})
  downArrow = false;

  @property({type: Array})
  topContent?: DropdownContent[];

  @property({type: String})
  horizontalAlign = 'left';

  /**
   * Style the dropdown trigger as a link (rather than a button).
   */

  @property({type: Boolean})
  link = false;

  @property({type: Number})
  verticalOffset = 40;

  /** Propagates/Reflects the `opened` property of the <iron-dropdown> */
  @property({type: Boolean, notify: true})
  opened = false;

  /**
   * List the IDs of dropdown buttons to be disabled. (Note this only
   * disables buttons and not link entries.)
   */
  @property({type: Array})
  disabledIds: string[] = [];

  /** Called in disconnectedCallback. */
  private cleanups: (() => void)[] = [];

  // Used within the tests so needs to be non-private.
  cursor = new GrCursorManager();

  constructor() {
    super();
    this.cursor.cursorTargetClass = 'selected';
    this.cursor.focusOnMove = true;
  }

  override connectedCallback() {
    super.connectedCallback();
    this.cleanups.push(
      addShortcut(this, {key: Key.UP}, e => this._handleUp(e))
    );
    this.cleanups.push(
      addShortcut(this, {key: Key.DOWN}, e => this._handleDown(e))
    );
    this.cleanups.push(
      addShortcut(this, {key: Key.TAB}, e => this._handleTab(e))
    );
    this.cleanups.push(
      addShortcut(this, {key: Key.ENTER}, e => this._handleEnter(e))
    );
    this.cleanups.push(
      addShortcut(this, {key: Key.SPACE}, e => this._handleEnter(e))
    );
  }

  override disconnectedCallback() {
    this.cursor.unsetCursor();
    for (const cleanup of this.cleanups) cleanup();
    this.cleanups = [];
    super.disconnectedCallback();
  }

  /**
   * Handle the up key.
   */
  _handleUp(e: Event) {
    if (this.$.dropdown.opened) {
      e.preventDefault();
      e.stopPropagation();
      this.cursor.previous();
    } else {
      this._open();
    }
  }

  /**
   * Handle the down key.
   */
  _handleDown(e: Event) {
    if (this.$.dropdown.opened) {
      e.preventDefault();
      e.stopPropagation();
      this.cursor.next();
    } else {
      this._open();
    }
  }

  /**
   * Handle the tab key.
   */
  _handleTab(e: Event) {
    if (this.$.dropdown.opened) {
      // Tab in a native select is a no-op. Emulate this.
      e.preventDefault();
      e.stopPropagation();
    }
  }

  /**
   * Handle the enter key.
   */
  _handleEnter(e: Event) {
    e.preventDefault();
    e.stopPropagation();
    if (this.$.dropdown.opened) {
      // TODO(milutin): This solution is not particularly robust in general.
      // Since gr-tooltip-content click on shadow dom is not propagated down,
      // we have to target `a` inside it.
      if (this.cursor.target !== null) {
        const el = this.cursor.target.querySelector(':not([hidden]) a');
        if (el) {
          (el as HTMLElement).click();
        }
      }
    } else {
      this._open();
    }
  }

  /**
   * Handle a click on the iron-dropdown element.
   */
  _handleDropdownClick() {
    this._close();
  }

  handleOpenedChanged(e: CustomEvent) {
    this.opened = e.detail.value;
  }

  /**
   * Handle a click on the button to open the dropdown.
   */
  _dropdownTriggerTapHandler(e: MouseEvent) {
    e.preventDefault();
    e.stopPropagation();
    if (this.$.dropdown.opened) {
      this._close();
    } else {
      this._open();
    }
  }

  /**
   * Open the dropdown and initialize the cursor.
   */
  _open() {
    this.$.dropdown.open();
    this._resetCursorStops();
    this.cursor.setCursorAtIndex(0);
    if (this.cursor.target !== null) this.cursor.target.focus();
  }

  _close() {
    // async is needed so that that the click event is fired before the
    // dropdown closes (This was a bug for touch devices).
    setTimeout(() => {
      this.$.dropdown.close();
    }, 1);
  }

  /**
   * Get the class for a top-content item based on the given boolean.
   *
   * @param bold Whether the item is bold.
   * @return The class for the top-content item.
   */
  _getClassIfBold(bold?: boolean) {
    return bold ? 'bold-text' : '';
  }

  /**
   * Build a URL for the given host and path. The base URL will be only added,
   * if it is not already included in the path.
   *
   * @return The scheme-relative URL.
   */
  _computeURLHelper(host: string, path: string) {
    const base = path.startsWith(getBaseUrl()) ? '' : getBaseUrl();
    return '//' + host + base + path;
  }

  /**
   * Build a scheme-relative URL for the current host. Will include the base
   * URL if one is present. Note: the URL will be scheme-relative but absolute
   * with regard to the host.
   *
   * @param path The path for the URL.
   * @return The scheme-relative URL.
   */
  _computeRelativeURL(path: string) {
    const host = window.location.host;
    return this._computeURLHelper(host, path);
  }

  /**
   * Compute the URL for a link object.
   */
  _computeLinkURL(link: DropdownLink) {
    if (typeof link.url === 'undefined') {
      return '';
    }
    if (link.target || !link.url.startsWith('/')) {
      return link.url;
    }
    return this._computeRelativeURL(link.url);
  }

  /**
   * Compute the value for the rel attribute of an anchor for the given link
   * object. If the link has a target value, then the rel must be "noopener"
   * for security reasons.
   */
  _computeLinkRel(link: DropdownLink) {
    // Note: noopener takes precedence over external.
    if (link.target) {
      return REL_NOOPENER;
    }
    if (link.external) {
      return REL_EXTERNAL;
    }
    return null;
  }

  /**
   * Handle a click on an item of the dropdown.
   */
  _handleItemTap(e: MouseEvent) {
    if (e.target === null || !this.items) {
      return;
    }
    const id = (e.target as Element).getAttribute('data-id');
    const item = this.items.find(item => item.id === id);
    if (id && !this.disabledIds.includes(id)) {
      if (item) {
        this.dispatchEvent(
          new CustomEvent('tap-item', {
            detail: item,
            bubbles: true,
            composed: true,
          })
        );
      }
      this.dispatchEvent(new CustomEvent('tap-item-' + id));
    }
  }

  /**
   * If a dropdown item is shown as a button, get the class for the button.
   *
   * @param disabledIdsRecord The change record for the disabled IDs
   *     list.
   * @return The class for the item button.
   */
  _computeDisabledClass(disabledIdsRecord: DisableIdsRecord, id?: string) {
    return id && disabledIdsRecord.base.includes(id) ? 'disabled' : '';
  }

  /**
   * Recompute the stops for the dropdown item cursor.
   */
  @observe('items')
  _resetCursorStops() {
    if (this.items && this.items.length > 0 && this.$.dropdown.opened) {
      flush();
      this.cursor.stops =
        this.root !== null ? Array.from(this.root.querySelectorAll('li')) : [];
    }
  }

  _computeHasTooltip(tooltip?: string) {
    return !!tooltip;
  }

  _computeIsDownload(link: DropdownLink) {
    return !!link.download;
  }
}
