import { Component, Prop, h, Element, Host } from '@stencil/core';
export class TeliaFocusTrap {
  constructor() {
    /** Tracking id is used to identify and count Component usage */
    this.dataTrackingId = 'telia-focus-trap';
    this.focusableSelectors = [
      'a[href]',
      'audio[controls]',
      'video[controls]',
      '[contenteditable]',
      '[tabindex="0"]:not([disabled])',
      'button:not([disabled])',
      'iframe',
      "input:not([disabled]):not([type='hidden'])",
      'select:not([disabled])',
      'summary',
      'textarea:not([disabled])',
    ].join(', ');
    this.handleKeyDown = event => {
      const path = event.path || (event.composedPath && event.composedPath());
      const currentIndex = this.getCurrentIndex(path[0]);
      if (event.key === 'Tab') {
        if (currentIndex === this.focusableEls.length - 1 && !event.shiftKey) {
          //When tabbing forward from the last focusable element will focus on first element
          event.preventDefault();
          this.focusableEls[0].focus();
        }
        if (currentIndex === 0 && event.shiftKey) {
          //When tabbing backwards from the first focusable element will focus on the last element
          event.preventDefault();
          this.focusableEls[this.focusableEls.length - 1].focus();
        }
      }
    };
  }
  componentDidLoad() {
    document.addEventListener('keydown', this.handleKeyDown);
    this.findFocusableElements();
  }
  disconnectedCallback() {
    document.removeEventListener('keydown', this.handleKeyDown);
  }
  /**
   * Finds all focusable elements inside the slot
   * @private
   */
  findFocusableElements() {
    let arr = [];
    Array.from(this.element.querySelectorAll('*')).forEach(el => {
      this.traverseFocusable(el, arr);
    });
    this.focusableEls = arr;
  }
  traverseFocusable(el, arr) {
    if (el.matches(this.focusableSelectors)) {
      arr.push(el);
    }
    else if (el.shadowRoot) {
      Array.from(el.shadowRoot.querySelectorAll(this.focusableSelectors)).forEach(elem => {
        this.traverseFocusable(elem, arr);
      });
    }
  }
  /**
   * Get the index of the current focused element
   * @param path
   * @private
   */
  getCurrentIndex(path) {
    let index;
    this.focusableEls.map((el, i) => {
      if (el === path) {
        index = i;
      }
    });
    return index;
  }
  render() {
    return (h(Host, { "data-testid": this.dataTestid },
      h("slot", null),
      h("telia-vst", { dataTrackingId: this.dataTrackingId })));
  }
  static get is() { return "telia-focus-trap"; }
  static get encapsulation() { return "shadow"; }
  static get properties() { return {
    "dataTestid": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Test id set for web component host"
      },
      "attribute": "data-testid",
      "reflect": false
    }
  }; }
  static get elementRef() { return "element"; }
}
