// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import {LitElement, html} from 'lit-element';
import {NON_EDITING_KEY_EVENTS} from 'shared/dom-helpers.js';

/**
 * @type {RegExp} Autocomplete options are matched at word boundaries. This
 *   Regex specifies what counts as a boundary between words.
 */
const DELIMITER_REGEX = /[^a-z0-9]+/i;

/**
 * Specifies what happens to the input element an autocomplete
 * instance is attached to when a user selects an autocomplete option. This
 * constant specifies the default behavior where a form's entire value is
 * replaced with the selected value.
 * @param {HTMLInputElement} input An input element.
 * @param {string} value The value of the selected autocomplete option.
 */
const DEFAULT_REPLACER = (input, value) => {
  input.value = value;
};

/**
 * @type {number} The default maximum of completions to render at a time.
 */
const DEFAULT_MAX_COMPLETIONS = 200;

/**
 * @type {number} Globally shared counter for autocomplete instances to help
 *   ensure that no two <chops-autocomplete> options have the same ID.
 */
let idCount = 1;

/**
 * `<chops-autocomplete>` shared autocomplete UI code that inter-ops with
 * other code.
 *
 * chops-autocomplete inter-ops with any input element, whether custom or
 * native that can receive change handlers and has a 'value' property which
 * can be read and set.
 *
 * NOTE: This element disables ShadowDOM for accessibility reasons: to allow
 * aria attributes from the outside to reference features in this element.
 *
 * @customElement chops-autocomplete
 */
export class ChopsAutocomplete extends LitElement {
  /** @override */
  render() {
    const completions = this.completions;
    const currentValue = this._prefix.trim().toLowerCase();
    const index = this._selectedIndex;
    const currentCompletion = index >= 0 &&
      index < completions.length ? completions[index] : '';

    return html`
      <style>
        /*
         * Really specific class names are necessary because ShadowDOM
         * is disabled for this component.
         */
        .chops-autocomplete-container {
          position: relative;
        }
        .chops-autocomplete-container table {
          padding: 0;
          font-size: var(--chops-main-font-size);
          color: var(--chops-link-color);
          position: absolute;
          background: var(--chops-white);
          border: var(--chops-accessible-border);
          z-index: 999;
          box-shadow: 2px 3px 8px 0px hsla(0, 0%, 0%, 0.3);
          border-spacing: 0;
          border-collapse: collapse;
          /* In the case when the autocomplete extends the
           * height of the viewport, we want to make sure
           * there's spacing. */
          margin-bottom: 1em;
        }
        .chops-autocomplete-container tbody {
          display: block;
          min-width: 100px;
          max-height: 500px;
          overflow: auto;
        }
        .chops-autocomplete-container tr {
          cursor: pointer;
          transition: background 0.2s ease-in-out;
        }
        .chops-autocomplete-container tr[data-selected] {
          background: var(--chops-active-choice-bg);
          text-decoration: underline;
        }
        .chops-autocomplete-container td {
          padding: 0.25em 8px;
          white-space: nowrap;
        }
        .screenreader-hidden {
          clip: rect(1px, 1px, 1px, 1px);
          height: 1px;
          overflow: hidden;
          position: absolute;
          white-space: nowrap;
          width: 1px;
        }
      </style>
      <div class="chops-autocomplete-container">
        <span class="screenreader-hidden" aria-live="polite">
          ${currentCompletion}
        </span>
        <table
          ?hidden=${!completions.length}
        >
          <tbody>
            ${completions.map((completion, i) => html`
              <tr
                id=${completionId(this.id, i)}
                ?data-selected=${i === index}
                data-index=${i}
                data-value=${completion}
                @mouseover=${this._hoverCompletion}
                @mousedown=${this._clickCompletion}
                role="option"
                aria-selected=${completion.toLowerCase() ===
                  currentValue ? 'true' : 'false'}
              >
                <td class="completion">
                  ${this._renderCompletion(completion)}
                </td>
                <td class="docstring">
                  ${this._renderDocstring(completion)}
                </td>
              </tr>
            `)}
          </tbody>
        </table>
      </div>
    `;
  }

  /**
   * Renders a single autocomplete result.
   * @param {string} completion The string for the currently selected
   *   autocomplete value.
   * @return {TemplateResult}
   */
  _renderCompletion(completion) {
    const matchDict = this._matchDict;

    if (!(completion in matchDict)) return completion;

    const {index, matchesDoc} = matchDict[completion];

    if (matchesDoc) return completion;

    const prefix = this._prefix;
    const start = completion.substr(0, index);
    const middle = completion.substr(index, prefix.length);
    const end = completion.substr(index + prefix.length);

    return html`${start}<b>${middle}</b>${end}`;
  }

  /**
   * Finds the docstring for a given autocomplete result and renders it.
   * @param {string} completion The autocomplete result rendered.
   * @return {TemplateResult}
   */
  _renderDocstring(completion) {
    const matchDict = this._matchDict;
    const docDict = this.docDict;

    if (!completion in docDict) return '';

    const doc = docDict[completion];

    if (!(completion in matchDict)) return doc;

    const {index, matchesDoc} = matchDict[completion];

    if (!matchesDoc) return doc;

    const prefix = this._prefix;
    const start = doc.substr(0, index);
    const middle = doc.substr(index, prefix.length);
    const end = doc.substr(index + prefix.length);

    return html`${start}<b>${middle}</b>${end}`;
  }

  /** @override */
  static get properties() {
    return {
      /**
       * The input this element is for.
       */
      for: {type: String},
      /**
       * Generated id for the element.
       */
      id: {
        type: String,
        reflect: true,
      },
      /**
       * The role attribute, set for accessibility.
       */
      role: {
        type: String,
        reflect: true,
      },
      /**
       * Array of strings for possible autocompletion values.
       */
      strings: {type: Array},
      /**
       * A dictionary containing optional doc strings for each autocomplete
       * string.
       */
      docDict: {type: Object},
      /**
       * An optional function to compute what happens when the user selects
       * a value.
       */
      replacer: {type: Object},
      /**
       * An Array of the currently suggested autcomplte values.
       */
      completions: {type: Array},
      /**
       * Maximum number of completion values that can display at once.
       */
      max: {type: Number},
      /**
       * Dict of locations of matched substrings. Value format:
       * {index, matchesDoc}.
       */
      _matchDict: {type: Object},
      _selectedIndex: {type: Number},
      _prefix: {type: String},
      _forRef: {type: Object},
      _boundToggleCompletionsOnFocus: {type: Object},
      _boundNavigateCompletions: {type: Object},
      _boundUpdateCompletions: {type: Object},
      _oldAttributes: {type: Object},
    };
  }

  /** @override */
  constructor() {
    super();

    this.strings = [];
    this.docDict = {};
    this.completions = [];
    this.max = DEFAULT_MAX_COMPLETIONS;

    this.role = 'listbox';
    this.id = `chops-autocomplete-${idCount++}`;

    this._matchDict = {};
    this._selectedIndex = -1;
    this._prefix = '';
    this._boundToggleCompletionsOnFocus =
      this._toggleCompletionsOnFocus.bind(this);
    this._boundUpdateCompletions = this._updateCompletions.bind(this);
    this._boundNavigateCompletions = this._navigateCompletions.bind(this);
    this._oldAttributes = {};
  }

  // Disable shadow DOM to allow aria attributes to propagate.
  /** @override */
  createRenderRoot() {
    return this;
  }

  /** @override */
  disconnectedCallback() {
    super.disconnectedCallback();

    this._disconnectAutocomplete(this._forRef);
  }

  /** @override */
  updated(changedProperties) {
    if (changedProperties.has('for')) {
      const forRef = this.getRootNode().querySelector('#' + this.for);

      // TODO(zhangtiff): Make this element work with custom input components
      // in the future as well.
      this._forRef = (forRef.tagName || '').toUpperCase() === 'INPUT' ?
        forRef : undefined;
      this._connectAutocomplete(this._forRef);
    }
    if (this._forRef) {
      if (changedProperties.has('id')) {
        this._forRef.setAttribute('aria-owns', this.id);
      }
      if (changedProperties.has('completions')) {
        // a11y. Tell screenreaders whether the autocomplete is expanded.
        this._forRef.setAttribute('aria-expanded',
          this.completions.length ? 'true' : 'false');
      }

      if (changedProperties.has('_selectedIndex') ||
          changedProperties.has('completions')) {
        this._updateAriaActiveDescendant(this._forRef);

        this._scrollCompletionIntoView(this._selectedIndex);
      }
    }
  }

  /**
   * Sets the aria-activedescendant attribute of the element (ie: an input form)
   * that the autocomplete is attached to, in order to tell screenreaders about
   * which autocomplete option is currently selected.
   * @param {HTMLInputElement} element
   */
  _updateAriaActiveDescendant(element) {
    const i = this._selectedIndex;

    if (i >= 0 && i < this.completions.length) {
      const selectedId = completionId(this.id, i);

      // a11y. Set the ID of the currently selected element.
      element.setAttribute('aria-activedescendant', selectedId);

      // Scroll the container to make sure the selected element is in view.
    } else {
      element.setAttribute('aria-activedescendant', '');
    }
  }

  /**
   * When a user moves up or down from an autocomplete option that's at the top
   * or bottom of the autocomplete option container, we must scroll the
   * container to make sure the user always sees the option they've selected.
   * @param {number} i The index of the autocomplete option to put into view.
   */
  _scrollCompletionIntoView(i) {
    const selectedId = completionId(this.id, i);

    const container = this.querySelector('tbody');
    const completion = this.querySelector(`#${selectedId}`);

    if (!completion) return;

    const distanceFromTop = completion.offsetTop - container.scrollTop;

    // If the completion is above the viewport for the container.
    if (distanceFromTop < 0) {
      // Position the completion at the top of the container.
      container.scrollTop = completion.offsetTop;
    }

    // If the compltion is below the viewport for the container.
    if (distanceFromTop > (container.offsetHeight - completion.offsetHeight)) {
      // Position the compltion at the bottom of the container.
      container.scrollTop = completion.offsetTop - (container.offsetHeight -
        completion.offsetHeight);
    }
  }

  /**
   * Changes the input's value according to the rules of the replacer function.
   * @param {string} value - the value to swap in.
   * @return {undefined}
   */
  completeValue(value) {
    if (!this._forRef) return;

    const replacer = this.replacer || DEFAULT_REPLACER;
    replacer(this._forRef, value);

    this.hideCompletions();
  }

  /**
   * Computes autocomplete values matching the current input in the field.
   * @return {boolean} Whether any completions were found.
   */
  showCompletions() {
    if (!this._forRef) {
      this.hideCompletions();
      return false;
    }
    this._prefix = this._forRef.value.trim().toLowerCase();
    // Always select the first completion by default when recomputing
    // completions.
    this._selectedIndex = 0;

    const matchDict = {};
    const accepted = [];
    matchDict;
    for (let i = 0; i < this.strings.length &&
        accepted.length < this.max; i++) {
      const s = this.strings[i];
      let matchIndex = this._matchIndex(this._prefix, s);
      let matches = matchIndex >= 0;
      if (matches) {
        matchDict[s] = {index: matchIndex, matchesDoc: false};
      } else if (s in this.docDict) {
        matchIndex = this._matchIndex(this._prefix, this.docDict[s]);
        matches = matchIndex >= 0;
        if (matches) {
          matchDict[s] = {index: matchIndex, matchesDoc: true};
        }
      }
      if (matches) {
        accepted.push(s);
      }
    }

    this._matchDict = matchDict;

    this.completions = accepted;

    return !!this.completions.length;
  }

  /**
   * Finds where a given user input matches an autocomplete option. Note that
   * a match is only found if the substring is at either the beginning of the
   * string or the beginning of a delimited section of the string. Hence, we
   * refer to the "needle" in this function a "prefix".
   * @param {string} prefix The value that the user inputed into the form.
   * @param {string} s The autocomplete option that's being compared.
   * @return {number} An integer for what index the substring is found in the
   *   autocomplete option. Returns -1 if no match.
   */
  _matchIndex(prefix, s) {
    const matchStart = s.toLowerCase().indexOf(prefix.toLocaleLowerCase());
    if (matchStart === 0 ||
        (matchStart > 0 && s[matchStart - 1].match(DELIMITER_REGEX))) {
      return matchStart;
    }
    return -1;
  }

  /**
   * Hides autocomplete options.
   */
  hideCompletions() {
    this.completions = [];
    this._prefix = '';
    this._selectedIndex = -1;
  }

  /**
   * Sets an autocomplete option that a user hovers over as the selected option.
   * @param {MouseEvent} e
   */
  _hoverCompletion(e) {
    const target = e.currentTarget;

    if (!target.dataset || !target.dataset.index) return;

    const index = Number.parseInt(target.dataset.index);
    if (index >= 0 && index < this.completions.length) {
      this._selectedIndex = index;
    }
  }

  /**
   * Sets the value of the form input that the user is editing to the
   * autocomplete option that the user just clicked.
   * @param {MouseEvent} e
   */
  _clickCompletion(e) {
    e.preventDefault();
    const target = e.currentTarget;
    if (!target.dataset || !target.dataset.value) return;

    this.completeValue(target.dataset.value);
  }

  /**
   * Hides and shows the autocomplete completions when a user focuses and
   * unfocuses a form.
   * @param {FocusEvent} e
   */
  _toggleCompletionsOnFocus(e) {
    const target = e.target;

    // Check if the input is focused or not.
    if (target.matches(':focus')) {
      this.showCompletions();
    } else {
      this.hideCompletions();
    }
  }

  /**
   * Implements hotkeys to allow the user to navigate autocomplete options with
   * their keyboard. ie: pressing up and down to select options or Esc to close
   * the form.
   * @param {KeyboardEvent} e
   */
  _navigateCompletions(e) {
    const completions = this.completions;
    if (!completions.length) return;

    switch (e.key) {
      // TODO(zhangtiff): Throttle or control keyboard navigation so the user
      // can't navigate faster than they can can perceive.
      case 'ArrowUp':
        e.preventDefault();
        this._navigateUp();
        break;
      case 'ArrowDown':
        e.preventDefault();
        this._navigateDown();
        break;
      case 'Enter':
      // TODO(zhangtiff): Add Tab to this case as well once all issue detail
      // inputs use chops-autocomplete.
        e.preventDefault();
        if (this._selectedIndex >= 0 &&
            this._selectedIndex <= completions.length) {
          this.completeValue(completions[this._selectedIndex]);
        }
        break;
      case 'Escape':
        e.preventDefault();
        this.hideCompletions();
        break;
    }
  }

  /**
   * Selects the completion option above the current one.
   */
  _navigateUp() {
    const completions = this.completions;
    this._selectedIndex -= 1;
    if (this._selectedIndex < 0) {
      this._selectedIndex = completions.length - 1;
    }
  }

  /**
   * Selects the completion option below the current one.
   */
  _navigateDown() {
    const completions = this.completions;
    this._selectedIndex += 1;
    if (this._selectedIndex >= completions.length) {
      this._selectedIndex = 0;
    }
  }

  /**
   * Recomputes autocomplete completions when the user types a new input.
   * Ignores KeyboardEvents that don't change the input value of the form
   * to prevent excess recomputations.
   * @param {KeyboardEvent} e
   */
  _updateCompletions(e) {
    if (NON_EDITING_KEY_EVENTS.has(e.key)) return;
    this.showCompletions();
  }

  /**
   * Initializes the input element that this autocomplete instance is
   * attached to with aria attributes required for accessibility.
   * @param {HTMLInputElement} node The input element that the autocomplete is
   *   attached to.
   */
  _connectAutocomplete(node) {
    if (!node) return;

    node.addEventListener('keyup', this._boundUpdateCompletions);
    node.addEventListener('keydown', this._boundNavigateCompletions);
    node.addEventListener('focus', this._boundToggleCompletionsOnFocus);
    node.addEventListener('blur', this._boundToggleCompletionsOnFocus);

    this._oldAttributes = {
      'aria-owns': node.getAttribute('aria-owns'),
      'aria-autocomplete': node.getAttribute('aria-autocomplete'),
      'aria-expanded': node.getAttribute('aria-expanded'),
      'aria-haspopup': node.getAttribute('aria-haspopup'),
      'aria-activedescendant': node.getAttribute('aria-activedescendant'),
    };
    node.setAttribute('aria-owns', this.id);
    node.setAttribute('aria-autocomplete', 'both');
    node.setAttribute('aria-expanded', 'false');
    node.setAttribute('aria-haspopup', 'listbox');
    node.setAttribute('aria-activedescendant', '');
  }

  /**
   * When <chops-autocomplete> is disconnected or moved to a difference form,
   * this function removes the side effects added by <chops-autocomplete> on the
   * input element that <chops-autocomplete> is attached to.
   * @param {HTMLInputElement} node The input element that the autocomplete is
   *   attached to.
   */
  _disconnectAutocomplete(node) {
    if (!node) return;

    node.removeEventListener('keyup', this._boundUpdateCompletions);
    node.removeEventListener('keydown', this._boundNavigateCompletions);
    node.removeEventListener('focus', this._boundToggleCompletionsOnFocus);
    node.removeEventListener('blur', this._boundToggleCompletionsOnFocus);

    for (const key of Object.keys(this._oldAttributes)) {
      node.setAttribute(key, this._oldAttributes[key]);
    }
    this._oldAttributes = {};
  }
}

/**
 * Generates a unique HTML ID for a given autocomplete option, for use by
 * aria-activedescendant. Note that because the autocomplete element has
 * ShadowDOM disabled, we need to make sure the ID is specific enough to be
 * globally unique across the entire application.
 * @param {string} prefix A unique prefix to differentiate this autocomplete
 *   instance from other autocomplete instances.
 * @param {number} i The index of the autocomplete option.
 * @return {string} A unique HTML ID for a given autocomplete option.
 */
function completionId(prefix, i) {
  return `${prefix}-option-${i}`;
}

customElements.define('chops-autocomplete', ChopsAutocomplete);
