import { Component, Element, Event, h, Host, Listen, Prop, State, Watch } from '@stencil/core';
const progressScales = {
  small: {
    size: 14,
    strokeWidth: 2,
  },
  medium: {
    size: 16,
    strokeWidth: 2,
  },
  large: {
    size: 18,
    strokeWidth: 2,
  },
};
const getProgressScale = ({ scale = 'medium' }) => progressScales[scale];
export class DvnSelect {
  constructor() {
    this.scale = 'medium';
    this.leaned = false;
    this.disabled = false;
    this.multiple = false;
    this.progressing = false;
    this.hideCaret = false;
    this.hideCheck = false;
    this.hideScrollbar = false;
    this.expanded = false;
    this.hasDefaultValue = false;
  }
  componentWillLoad() {
    this.internalValue = this.value;
    this.toggleSelectedValues();
    if (this.dataProvider) {
      this.optionsFromProvider = this.dataProvider.getInitialData();
    }
  }
  watchHandler(newValue) {
    this.internalValue = newValue;
    this.toggleSelectedValues();
  }
  click(event) {
    if (event.target['nodeName'].toLowerCase() === 'dvn-select' && !this.expanded) {
      // select border :) is clicked, expand the options
      this.expandOptions();
      return;
    }
    if (event.target['nodeName'].toLowerCase() !== 'dvn-select-option') {
      // ignore if the clicked item is not the option
      return;
    }
    if (!this.expanded) {
      // selected option is clicked to expand the options
      this.expandOptions();
      return;
    }
    const clickedOptionValue = event.target['value'];
    if (clickedOptionValue === undefined) {
      // placeholder is clicked
      this.expanded = false;
      return;
    }
    if (!this.multiple) {
      if (this.internalValue === clickedOptionValue) {
        this.internalValue = undefined;
        this.change.emit(undefined);
      }
      else {
        // set the only value and close options
        this.internalValue = clickedOptionValue;
        this.change.emit(clickedOptionValue);
      }
      this.expanded = false;
    }
    else {
      // add/remove the clicked option from the value
      let newValue;
      if (this.internalValue && this.internalValue.includes(clickedOptionValue)) {
        newValue = this.internalValue.filter(v => v !== clickedOptionValue);
      }
      else {
        newValue = [...(this.internalValue || []), clickedOptionValue];
      }
      this.internalValue = newValue;
      this.change.emit(newValue);
      if (this.enableSearch) {
        this.focusOnSearchInput();
      }
    }
    this.toggleSelectedValues();
  }
  toggleSelectedValues() {
    this.el.querySelectorAll('dvn-select-option').forEach((option) => {
      option.selected = false;
      if (!this.placeholder && option.value === undefined && option.slot !== 'multiple-value') {
        // remove empty option from its' parent and show it as placeholder outside of options container
        this.hasDefaultValue = true;
        option.remove();
        this.placeholder = h("dvn-select-option", { key: "placeholder", innerHTML: option.innerHTML });
        // show default value if there is no internal value
        option.selected = !this.internalValue;
      }
      else if (!this.multiple && this.internalValue && this.internalValue !== '') {
        option.selected = option.value === this.internalValue;
      }
      else if (this.multiple && this.internalValue && this.internalValue !== []) {
        option.selected = this.internalValue.includes(option.value);
      }
    });
  }
  getMultipleValueLabel() {
    if (!this.value) {
      return '';
    }
    const labels = [];
    // search through the options child elements and get the labels from them
    this.el.querySelectorAll('dvn-select-option').forEach((option) => {
      if (this.value.includes(option.value)) {
        labels.push(option.textContent);
      }
    });
    return labels.join(', ');
  }
  expandOptions() {
    if (this.disabled) {
      return;
    }
    this.expanded = true;
    if (this.dataProvider) {
      this.fetchOptions();
    }
    if (this.enableSearch || (this.dataProvider && this.dataProvider.isQuickSearchEnabled())) {
      this.focusOnSearchInput();
    }
  }
  focusOnSearchInput() {
    setTimeout(() => {
      const input = this.el.getElementsByTagName('dvn-input').item(0);
      if (input) {
        input.focusOnInput();
      }
    }, 100);
  }
  fetchOptions() {
    this.progressing = true;
    this.dataProvider.getData().then(options => {
      this.progressing = false;
      this.optionsFromProvider = options;
    });
  }
  render() {
    const { enableClear, enableSearch = (this.dataProvider && this.dataProvider.isQuickSearchEnabled()), } = this;
    const vars = {};
    if (this.width) {
      vars['--width'] = this.width;
      vars['--min-width'] = this.width;
    }
    return (h(Host, { class: {
        leaned: this.leaned,
        multiple: this.multiple,
        disabled: this.disabled,
        expanded: this.expanded,
        'clear-shown': enableClear,
        progressing: this.progressing,
        'with-value': !!this.internalValue,
        'with-caret': !this.hideCaret,
        'without-check': this.hideCheck,
        [this.scale]: true,
        [this.feedback]: !!this.feedback,
      }, onFocus: () => {
        if (this.hasDefaultValue || !!this.internalValue) {
          // let option click event to handle expand
          return;
        }
        this.expandOptions();
      }, onBlur: (e) => {
        const targetNode = e.relatedTarget;
        if (!targetNode || targetNode.closest('dvn-select') !== this.el) {
          // some node outside of this component is focused
          this.expanded = false;
        }
      }, tabindex: this.disabled ? -1 : 0, style: vars },
      this.placeholder,
      (this.multiple && !this.expanded) &&
        h("dvn-select-option", { class: "multiple-value", slot: "multiple-value" }, this.getMultipleValueLabel()),
      enableSearch &&
        h("div", { class: "search-input-container" },
          h("dvn-input", { enableClear: enableClear, feedback: this.feedback, leaned: true, onBlur: (e) => {
              e.stopPropagation();
              if (e.type !== 'blur') {
                return;
              }
              const focusedNode = e.detail.relatedTarget;
              let clickedSomethingInsideSelect = false;
              if (focusedNode) {
                const closestSelectToFocusedNode = focusedNode.closest('dvn-select');
                const closestSelectToInput = e.target.closest('dvn-select');
                clickedSomethingInsideSelect = closestSelectToFocusedNode === null || closestSelectToFocusedNode === void 0 ? void 0 : closestSelectToFocusedNode.isSameNode(closestSelectToInput);
              }
              if (!focusedNode || !clickedSomethingInsideSelect) {
                // focused target doesn't belong to the same dvn-select
                this.expanded = false;
              }
            }, onChange: (e) => {
              e.stopPropagation();
              this.filterOptions(e.detail);
            }, value: this.dataProvider.getQuickSearchText() })),
      h("div", { class: {
          'options-container': true,
          expanded: this.expanded,
          'no-scrollbar': this.hideScrollbar,
        } },
        h("slot", null),
        (this.optionsFromProvider && this.dataAdapter) && this.optionsFromProvider.map(option => (h("dvn-select-option", { key: this.dataAdapter.value(option), value: this.dataAdapter.value(option), selected: this.dataAdapter.value(option) === this.internalValue }, this.dataAdapter.label(option))))),
      this.progressing &&
        h("div", { class: "progress-container" },
          h("dvn-progress", { indefinite: true, leaned: true, tint: "neutral", size: getProgressScale(this).size, strokeWidth: getProgressScale(this).strokeWidth }))));
  }
  filterOptions(query) {
    if (!query && !!this.dataProvider.getQuickSearchText()) {
      // filter is cleared
      this.dataProvider.setQuickSearchText(undefined);
      this.change.emit(undefined);
      this.expanded = false;
    }
    if (this.dataProvider) {
      clearTimeout(this.quickSearchDelayTimer);
      this.quickSearchDelayTimer = setTimeout(() => {
        this.dataProvider.setQuickSearchText(query);
        this.fetchOptions();
      }, 500);
      return;
    }
    this.el.querySelectorAll('dvn-select-option').forEach(option => {
      if (query && query !== '' && option.innerHTML.toLocaleLowerCase().indexOf(query.toLocaleLowerCase()) < 0) {
        option.classList.add('filtered');
      }
      else {
        option.classList.remove('filtered');
      }
    });
  }
  static get is() { return "dvn-select"; }
  static get originalStyleUrls() { return {
    "$": ["dvn-select.scss"]
  }; }
  static get styleUrls() { return {
    "$": ["dvn-select.css"]
  }; }
  static get properties() { return {
    "scale": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "Scale",
        "resolved": "\"large\" | \"medium\" | \"small\"",
        "references": {
          "Scale": {
            "location": "import",
            "path": "../../theme"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "scale",
      "reflect": false,
      "defaultValue": "'medium'"
    },
    "feedback": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "'error' | 'warning'",
        "resolved": "\"error\" | \"warning\"",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "feedback",
      "reflect": false
    },
    "leaned": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "leaned",
      "reflect": false,
      "defaultValue": "false"
    },
    "disabled": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "disabled",
      "reflect": false,
      "defaultValue": "false"
    },
    "value": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string | string[]",
        "resolved": "string | string[]",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "value",
      "reflect": false
    },
    "width": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "width",
      "reflect": false
    },
    "enableClear": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "enable-clear",
      "reflect": false
    },
    "enableSearch": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "enable-search",
      "reflect": false
    },
    "multiple": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "multiple",
      "reflect": false,
      "defaultValue": "false"
    },
    "progressing": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "progressing",
      "reflect": false,
      "defaultValue": "false"
    },
    "dataProvider": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "DvnSelectDataProvider<any>",
        "resolved": "DvnSelectDataProvider<any>",
        "references": {
          "DvnSelectDataProvider": {
            "location": "import",
            "path": "./data-provider"
          }
        }
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [],
        "text": ""
      }
    },
    "dataAdapter": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "DvnSelectDataAdapter<any>",
        "resolved": "DvnSelectDataAdapter<any>",
        "references": {
          "DvnSelectDataAdapter": {
            "location": "import",
            "path": "./data-adapter"
          }
        }
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [],
        "text": ""
      }
    },
    "internalValue": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string | string[]",
        "resolved": "string | string[]",
        "references": {}
      },
      "required": false,
      "optional": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "internal-value",
      "reflect": false
    },
    "hideCaret": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "hide-caret",
      "reflect": false,
      "defaultValue": "false"
    },
    "hideCheck": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "hide-check",
      "reflect": false,
      "defaultValue": "false"
    },
    "hideScrollbar": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": ""
      },
      "attribute": "hide-scrollbar",
      "reflect": false,
      "defaultValue": "false"
    }
  }; }
  static get states() { return {
    "expanded": {},
    "hasDefaultValue": {},
    "optionsFromProvider": {}
  }; }
  static get events() { return [{
      "method": "change",
      "name": "change",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": ""
      },
      "complexType": {
        "original": "any",
        "resolved": "any",
        "references": {}
      }
    }]; }
  static get elementRef() { return "el"; }
  static get watchers() { return [{
      "propName": "value",
      "methodName": "watchHandler"
    }]; }
  static get listeners() { return [{
      "name": "click",
      "method": "click",
      "target": undefined,
      "capture": false,
      "passive": false
    }]; }
}
