import { Component, Element, Event, Host, Listen, Prop, State, Watch, forceUpdate, h } from '@stencil/core';
import { Utils } from '../../utils/utils';
import { IGC_DEFAULT_PANE_SIZE, IgcContextMenuOrientation, IgcTabHeadersPosition } from '../dockmanager/dockmanager.interfaces';
/**
 * @hidden
 */
let NEXT_TAB_ID = 0;
/**
 * @hidden
 */
export class IgcTabsComponent {
  constructor() {
    this.forcedUpdate = false;
    this.hasHiddenTabs = false;
    this.tabHeadersPosition = IgcTabHeadersPosition.top;
    this.hasHeaders = true;
    this.showHiddenTabsMenu = true;
    this.resizeObserver = new ResizeObserver(this.tabHeadersDivResized.bind(this));
    this.slotChanged = () => {
      this.updateSelectedIndex();
      this.setTabsAttributes();
      this.forceUpdate();
    };
    this.onTabKeyDown = (ev) => {
      const tabHeaders = this.tabHeaders;
      if (Utils.isAltPressed(ev) || Utils.isControlOrMetaPressed(ev) || ev.shiftKey) {
        return;
      }
      if (ev.key === 'ArrowRight') {
        for (let i = this.selectedIndex; i < tabHeaders.length - this.hiddenTabHeaders.length - 1; i++) {
          if (!tabHeaders[i + 1].disabled) {
            this.selectedIndex = i + 1;
            tabHeaders[i + 1].focus();
            return;
          }
        }
      }
      else if (ev.key === 'ArrowLeft') {
        for (let i = this.selectedIndex; i > 0; i--) {
          if (!tabHeaders[i - 1].disabled) {
            this.selectedIndex = i - 1;
            tabHeaders[i - 1].focus();
            return;
          }
        }
      }
    };
  }
  selectedIndexPropertyChanged(newValue) {
    this.handleSelectedIndexChanged(newValue);
    this.selectedIndexChanged.emit(newValue);
  }
  componentWillLoad() {
    this.hiddenTabsMenuMeta = null;
    this.updateSelectedIndex();
  }
  componentDidLoad() {
    this.setTabsAttributes();
    this.tabHeadersDiv = this.el.shadowRoot.querySelector('div.tabs');
    if (this.tabHeadersDiv) {
      this.resizeObserver.observe(this.tabHeadersDiv);
    }
  }
  componentDidUpdate() {
    if (this.forcedUpdate) {
      this.forcedUpdate = false;
      this.setHasHiddenTabs();
    }
  }
  setTabsAttributes() {
    const tabHeaders = this.tabHeaders;
    const tabPanels = this.tabPanels;
    for (let i = 0; i < tabHeaders.length; i++) {
      if (!tabHeaders[i].getAttribute('id')) {
        const tabHeaderId = `tab-item-${NEXT_TAB_ID}`;
        const tabPanelId = `tab-panel-${NEXT_TAB_ID++}`;
        tabPanels[i].setAttribute('id', tabPanelId);
        tabHeaders[i].setAttribute('id', tabHeaderId);
        tabPanels[i].setAttribute('aria-labelledby', tabHeaderId);
        tabHeaders[i].setAttribute('aria-controls', tabPanelId);
      }
    }
  }
  disconnectedCallback() {
    this.resizeObserver.disconnect();
  }
  forceUpdate() {
    this.forcedUpdate = true;
    forceUpdate(this);
  }
  updateSelectedIndex() {
    const tabPanels = this.tabPanels;
    if (tabPanels.length === 0) {
      return;
    }
    if (this.selectedIndex > tabPanels.length - 1) {
      this.selectedIndex = tabPanels.length - 1;
    }
    else {
      this.handleSelectedIndexChanged(this.selectedIndex);
    }
  }
  get tabPanels() {
    return Array.from(this.el.querySelectorAll('igc-tab-panel-component'));
  }
  get tabHeaders() {
    return Array.from(this.el.querySelectorAll('igc-tab-header-component'));
  }
  get hiddenTabHeaders() {
    var _a;
    const containerTop = (_a = this.tabHeaders[0]) === null || _a === void 0 ? void 0 : _a.offsetTop;
    return this.tabHeaders.filter(t => t.offsetTop !== containerTop);
  }
  handleSelectedIndexChanged(newValue) {
    const tabHeaders = this.tabHeaders;
    const tabPanels = this.tabPanels;
    tabHeaders.forEach((t, i) => {
      t.selected = i === newValue;
    });
    tabPanels.forEach((t, i) => {
      t.selected = i === newValue;
    });
  }
  handleTabMouseDown(ev) {
    const tabHeader = ev.target;
    const tabHeaders = this.tabHeaders;
    const headerIndex = tabHeaders.indexOf(tabHeader);
    if (headerIndex >= 0) {
      this.selectedIndex = headerIndex;
    }
  }
  tabHeadersDivResized() {
    var _a;
    const containerTop = (_a = this.tabHeaders[0]) === null || _a === void 0 ? void 0 : _a.offsetTop;
    const selectedTabHeader = this.tabHeaders.filter(t => t.selected)[0];
    if ((selectedTabHeader === null || selectedTabHeader === void 0 ? void 0 : selectedTabHeader.offsetTop) !== containerTop) {
      const index = this.selectedIndex;
      this.selectedTabOutOfView.emit(index);
    }
    this.setHasHiddenTabs();
  }
  setHasHiddenTabs() {
    this.hasHiddenTabs = this.hiddenTabHeaders.length > 0;
  }
  handleHiddenTabsMenuClick(ev) {
    const button = ev.currentTarget;
    const items = this.hiddenTabHeaders.map(header => ({
      displayText: header.header,
      disabled: header.disabled,
      iconName: null,
      clickHandler: () => {
        const index = this.tabHeaders.indexOf(header);
        this.hiddenTabSelected.emit(index);
      }
    }));
    this.hiddenTabsMenuMeta = { target: button, menuItems: items };
  }
  handleContextMenuClosed() {
    this.hiddenTabsMenuMeta = null;
  }
  renderHiddenTabsMenu() {
    return this.hiddenTabsMenuMeta && (h("igc-context-menu-component", { onMenuClosed: this.handleContextMenuClosed.bind(this), orientation: this.tabHeadersPosition === IgcTabHeadersPosition.top ? IgcContextMenuOrientation.bottom : IgcContextMenuOrientation.top, items: this.hiddenTabsMenuMeta.menuItems, target: this.hiddenTabsMenuMeta.target }));
  }
  renderTabHeaders(top) {
    const classes = {
      'tabs': true,
      'tabs--top': top,
      'tabs--bottom': !top
    };
    const commontParts = { top, bottom: !top };
    const tabStripParts = Utils.partNameMap(Object.assign({ 'tab-strip-area': true }, commontParts));
    const tabStripActionsParts = Utils.partNameMap(Object.assign({ 'tab-strip-actions': true }, commontParts));
    return (h("div", { part: tabStripParts, style: {
        display: this.hasHeaders ? 'flex' : 'none'
      }, class: classes, onKeyDown: this.onTabKeyDown },
      h("div", { class: {
          'tab-headers-container': true,
          'tab-headers-container--wrapped': this.showHiddenTabsMenu
        } },
        h("slot", { name: "tabHeader" })),
      h("div", { part: tabStripActionsParts, class: "tab-header-icon-container" },
        this.showHiddenTabsMenu && this.hasHiddenTabs &&
          h("igc-button-component", { onClick: this.handleHiddenTabsMenuClick.bind(this) },
            h("igc-icon-component", { name: "more", "aria-label": this.resourceStrings.moreTabs, title: this.resourceStrings.moreTabs, style: {
                display: 'block'
              } })),
        h("slot", { name: "tabHeaderIcon" }))));
  }
  render() {
    const size = this.size || this.size === 0 ? this.size : IGC_DEFAULT_PANE_SIZE;
    const top = this.tabHeadersPosition === IgcTabHeadersPosition.top;
    const bottom = this.tabHeadersPosition === IgcTabHeadersPosition.bottom;
    const tabsContentParts = Utils.partNameMap({ 'tabs-content': true, document: top });
    const exportParts = Utils.partNameMap({
      'tab-strip-area': true,
      'tab-strip-actions': true,
      'tabs-content': true,
      document: top,
      top,
      bottom
    }, ',');
    return (h(Host, { role: "tablist", style: {
        flex: `${size} 1 ${size}px`
      }, exportparts: exportParts },
      top && this.renderTabHeaders(top),
      h("div", { part: tabsContentParts, class: "content" },
        h("slot", { onSlotchange: this.slotChanged })),
      bottom && this.renderTabHeaders(top),
      this.renderHiddenTabsMenu()));
  }
  static get is() { return "igc-tabs-component"; }
  static get encapsulation() { return "shadow"; }
  static get originalStyleUrls() { return {
    "$": ["tabs-component.scss"]
  }; }
  static get styleUrls() { return {
    "$": ["tabs-component.css"]
  }; }
  static get properties() { return {
    "size": {
      "type": "number",
      "mutable": false,
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "size",
      "reflect": false
    },
    "tabHeadersPosition": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "IgcTabHeadersPosition",
        "resolved": "IgcTabHeadersPosition.bottom | IgcTabHeadersPosition.top",
        "references": {
          "IgcTabHeadersPosition": {
            "location": "import",
            "path": "../dockmanager/dockmanager.interfaces"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "tab-headers-position",
      "reflect": false,
      "defaultValue": "IgcTabHeadersPosition.top"
    },
    "selectedIndex": {
      "type": "number",
      "mutable": true,
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "selected-index",
      "reflect": false
    },
    "hasHeaders": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "has-headers",
      "reflect": false,
      "defaultValue": "true"
    },
    "showHiddenTabsMenu": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "show-hidden-tabs-menu",
      "reflect": false,
      "defaultValue": "true"
    },
    "resourceStrings": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "IgcDockManagerResourceStrings",
        "resolved": "IgcDockManagerResourceStrings",
        "references": {
          "IgcDockManagerResourceStrings": {
            "location": "import",
            "path": "../dockmanager/dockmanager.public-interfaces"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      }
    }
  }; }
  static get states() { return {
    "hiddenTabsMenuMeta": {},
    "hasHiddenTabs": {}
  }; }
  static get events() { return [{
      "method": "selectedIndexChanged",
      "name": "selectedIndexChanged",
      "bubbles": false,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      }
    }, {
      "method": "hiddenTabSelected",
      "name": "hiddenTabSelected",
      "bubbles": false,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      }
    }, {
      "method": "selectedTabOutOfView",
      "name": "selectedTabOutOfView",
      "bubbles": false,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      }
    }]; }
  static get elementRef() { return "el"; }
  static get watchers() { return [{
      "propName": "selectedIndex",
      "methodName": "selectedIndexPropertyChanged"
    }]; }
  static get listeners() { return [{
      "name": "tabMouseDown",
      "method": "handleTabMouseDown",
      "target": undefined,
      "capture": false,
      "passive": false
    }]; }
}
