/**
 * @module modules/suggest-input-sk
 * @description A custom element that implements regex and substring match
 * suggestions. These are selectable via click or up/down/enter.
 *
 * @attr {Boolean} accept-custom-value - Whether users can enter values not listed
 * in this.options.
 *
 * @event value-changed - Any time the user selected or inputted value is
 * committed. Event is of the form { value: <newValue> }
 */

import { html } from 'lit-html';
import { $$ } from '../../../infra-sk/modules/dom';
import { define } from '../../../elements-sk/modules/define';

import { ElementSk } from '../../../infra-sk/modules/ElementSk';

const DOWN_ARROW = '40';
const UP_ARROW = '38';
const ENTER = '13';

export class SuggestInputSk extends ElementSk {
  private _options: string[] = [];

  private _suggestions: string[] = [];

  private _suggestionSelected: number = -1;

  private _label: string = '';

  constructor() {
    super(SuggestInputSk.template);

    this._upgradeProperty('options');
    this._upgradeProperty('acceptCustomValue');
    this._upgradeProperty('label');
  }

  // TODO(westont): We should probably use input-sk here.
  private static template = (ele: SuggestInputSk) => html`
<div class=suggest-input-container>
<input class=suggest-input autocomplete=off required
  @focus=${ele._refresh}
  @input=${ele._refresh}
  @keyup=${ele._keyup}
  @blur=${ele._blur}>
</input>
<label class="suggest-label">${ele.label}</label>
<div class=suggest-underline-container>
  <div class=suggest-underline></div>
  <div class=suggest-underline-background ></div>
</div>
<div class=suggest-list
  ?hidden=${!(ele._suggestions && ele._suggestions.length > 0)}
  @click=${ele._suggestionClick}>
  <ul>
  ${ele._suggestions.map((s, i) =>
    ele._suggestionSelected === i
      ? SuggestInputSk.selectedOptionTemplate(s)
      : SuggestInputSk.optionTemplate(s)
  )}
  </ul>
</div>
</div>
`;

  // tabindex so the fields populate FocusEvent.relatedTarget on blur.
  private static optionTemplate = (option: string) => html`
    <li tabindex="-1" class="suggestion">${option}</li>
  `;

  private static selectedOptionTemplate = (option: string) => html`
    <li tabindex="-1" class="suggestion selected">${option}</li>
  `;

  connectedCallback(): void {
    super.connectedCallback();
    this._render();
  }

  /**
   * @prop {string} value - Content of the input element from typing,
   * selection, etc.
   */
  get value(): string {
    // We back our value with input.value directly, to avoid issues with the
    // input value changing without changing our value property, causing
    // element re-rendering to be skipped.
    return ($$('input', this) as HTMLInputElement).value;
  }

  set value(v: string) {
    ($$('input', this) as HTMLInputElement).value = v;
  }

  /**
   * @prop {Array<string>} options - Values for suggestion list.
   */
  get options(): string[] {
    return this._options;
  }

  set options(o: string[]) {
    this._options = o;
  }

  /**
   * @prop {Boolean} acceptCustomValue - Mirrors the
   * 'accept-custom-value' attribute.
   */
  get acceptCustomValue(): boolean {
    return this.hasAttribute('accept-custom-value');
  }

  set acceptCustomValue(val: boolean) {
    if (val) {
      this.setAttribute('accept-custom-value', '');
    } else {
      this.removeAttribute('accept-custom-value');
    }
  }

  /**
   * @prop string label - Label to display to guide user input.
   */
  get label(): string {
    return this._label;
  }

  set label(o: string) {
    this._label = o;
  }

  _blur(e: MouseEvent): void {
    // Ignore if this blur is preceding _suggestionClick.
    const blurredElem = e.relatedTarget as HTMLElement;
    if (blurredElem && blurredElem.classList.contains('suggestion')) {
      return;
    }
    this._commit();
  }

  _commit(): void {
    if (this._suggestionSelected > -1) {
      this.value = this._suggestions[this._suggestionSelected];
    } else if (!this._options.includes(this.value) && !this.acceptCustomValue) {
      this.value = '';
    }
    this._suggestions = [];
    this._suggestionSelected = -1;
    this._render();
    this.dispatchEvent(
      new CustomEvent('value-changed', {
        bubbles: true,
        detail: { value: this.value },
      })
    );
  }

  _keyup(e: KeyboardEvent): void {
    // Allow the user to scroll through suggestions using arrow keys.
    const len = this._suggestions.length;
    const key = e.key || e.code;
    if ((key === 'ArrowDown' || key === DOWN_ARROW) && len > 0) {
      this._suggestionSelected = (this._suggestionSelected + 1) % len;
      this._render();
    } else if ((key === 'ArrowUp' || key === UP_ARROW) && len > 0) {
      this._suggestionSelected = (this._suggestionSelected + len - 1) % len;
      this._render();
    } else if (key === 'Enter' || key === ENTER) {
      // This also commits the current selection (if present) or custom
      // value (if allowed).
      ($$('input', this) as HTMLInputElement).dispatchEvent(
        new Event('blur', { bubbles: true, cancelable: true })
      );
    }
  }

  _refresh(): void {
    const v = this.value;
    let re: { test: (str: string) => boolean };
    try {
      re = new RegExp(v, 'i'); // case-insensitive.
    } catch (err) {
      // If the user enters an invalid expression, just use substring
      // match.
      re = {
        test: function (str: string) {
          return str.indexOf(v) !== -1;
        },
      };
    }
    this._suggestions = this._options.filter((s) => re.test(s));
    this._suggestionSelected = -1;
    this._render();
  }

  _suggestionClick(e: Event): void {
    const item = e.target as HTMLElement;
    if (item.tagName !== 'LI') {
      return;
    }
    const index = Array.from(item.parentNode!.children).indexOf(item);
    this._suggestionSelected = index;
    this._commit();
  }
}

define('suggest-input-sk', SuggestInputSk);
