import {
  __decorateClass,
  __privateAdd,
  __privateGet,
  __privateMethod,
  __privateSet
} from "../../chunks/chunk.QU3DSPNU.js";
var _isValueInitialized, _Select_instances, shouldShowFooter_fn, _handleSelectElementChange, setValueFromSelectElement_fn, renderFieldContents_fn, renderSlotLead_fn, renderMainLabel_fn, renderMainSlot_fn, renderChevron_fn;
import { localized } from "@lit/localize";
import { property, query } from "lit/decorators.js";
import { classMap } from "lit/directives/class-map.js";
import { when } from "lit/directives/when.js";
import { GdsFieldBase } from "../../primitives/field-base/field-base.component.js";
import { GdsFormControlFooter } from "../../primitives/form-control-footer/form-control-footer.component.js";
import { GdsFormControlHeader } from "../../primitives/form-control-header/form-control-header.component.js";
import formControlHostStyles from "../../shared-styles/form-control-host.style.js";
import { tokens } from "../../tokens.style.js";
import { observeLightDOM } from "../../utils/decorators/observe-light-dom.js";
import { watch } from "../../utils/decorators/watch.js";
import {
  gdsCustomElement,
  html
} from "../../utils/helpers/custom-element-scoping.js";
import {
  withLayoutChildProps,
  withMarginProps,
  withSizeXProps
} from "../../utils/mixins/declarative-layout-mixins.js";
import { GdsFormControlElement } from "../form/form-control.js";
import { IconChevronBottom } from "../icon/icons/chevron-bottom.component.js";
import SelectStyles from "./select.styles.js";
let Select = class extends GdsFormControlElement {
  constructor() {
    super(...arguments);
    __privateAdd(this, _Select_instances);
    this.supportingText = "";
    this.showExtendedSupportingText = false;
    this.size = "large";
    this.plain = false;
    __privateAdd(this, _isValueInitialized, false);
    __privateAdd(this, _handleSelectElementChange, (e) => {
      e.stopPropagation();
      __privateMethod(this, _Select_instances, setValueFromSelectElement_fn).call(this);
      requestAnimationFrame(() => {
        this.dispatchCustomEvent("input", {
          detail: { value: this.value },
          bubbles: true,
          composed: true
        });
        this.dispatchCustomEvent("change", {
          detail: { value: this.value },
          bubbles: true,
          composed: true
        });
      });
    });
  }
  get value() {
    return this._internalValue;
  }
  set value(value) {
    __privateGet(this, _isValueInitialized) || __privateSet(this, _isValueInitialized, true);
    this._internalValue = value;
  }
  /**
   * Returns the display value for the select component.
   * For single-select mode, this is the selected option text.
   * For multi-select mode, this is a comma-separated list of selected option texts.
   */
  get displayValue() {
    if (!this.selectElement) return "";
    return Array.from(this.selectElement.selectedOptions).map((o) => o.text).join(", ");
  }
  /**
   * Wheter the select element is in multiple selection mode.
   */
  get multiple() {
    return this.selectElement?.multiple ?? false;
  }
  connectedCallback() {
    super.connectedCallback();
    this.updateComplete.then(() => {
      this._captureDOM();
      this._handleValueChange();
    });
  }
  focus(options) {
    this._getValidityAnchor()?.focus(options);
  }
  render() {
    const CLASSES = {
      multiple: this.multiple
    };
    this.selectElement && (this.selectElement.disabled = this.disabled);
    return html`
      ${when(
      !this.plain,
      () => html`<gds-form-control-header
            class="size-${this.size}"
            .showExtendedSupportingText=${this.showExtendedSupportingText}
          >
            <label for="select" slot="label" id="label-text">
              ${this.label}
            </label>
            <span slot="supporting-text" id="supporting-text">
              ${this.supportingText}
            </span>
            <slot
              name="extended-supporting-text"
              slot="extended-supporting-text"
            ></slot>
          </gds-form-control-header>`
    )}

      <gds-field-base
        .size=${this.size}
        .disabled=${this.disabled}
        .invalid=${this.invalid}
        .multiline=${this.multiple}
        align-items=${this.multiple ? "flex-start" : "center"}
        class=${classMap(CLASSES)}
      >
        ${__privateMethod(this, _Select_instances, renderFieldContents_fn).call(this)}
      </gds-field-base>

      ${when(
      __privateMethod(this, _Select_instances, shouldShowFooter_fn).call(this),
      () => html`<gds-form-control-footer
            class="size-${this.size}"
            .errorMessage=${this.invalid ? this.errorMessage : void 0}
          ></gds-form-control-footer>`
    )}
    `;
  }
  _captureDOM() {
    if (!this.shadowRoot || this.childNodes.length === 0 || !this._elSelectContainer)
      return;
    const cloned = Array.from(this.children).filter((n) => n.nodeName === "SELECT").map((node) => {
      const clone = node.cloneNode(true);
      clone.addEventListener("change", __privateGet(this, _handleSelectElementChange));
      clone.addEventListener("input", __privateGet(this, _handleSelectElementChange));
      clone.setAttribute(
        "aria-describedby",
        "supporting-text extended-supporting-text sub-label message"
      );
      clone.ariaLabel = this.label;
      clone.setAttribute("id", "select");
      clone.disabled = this.disabled;
      clone.className = "native-control";
      if (!__privateGet(this, _isValueInitialized))
        this._internalValue = clone.value;
      else clone.value = this.value;
      return clone;
    });
    this._elSelectContainer.replaceChildren(...cloned);
  }
  /**
   * Handles form reset events by selecting the first option.
   */
  formResetCallback() {
    if (!this.selectElement) return;
    if (this.selectElement.multiple) {
      Array.from(this.selectElement.options).forEach((option) => {
        option.selected = false;
      });
      this.value = [];
    } else {
      const firstOption = this.selectElement.options[0];
      if (firstOption) {
        this.value = firstOption.value;
        this.selectElement.value = firstOption.value;
      }
    }
  }
  _getValidityAnchor() {
    return this.selectElement;
  }
  _handleValueChange() {
    if (!this.selectElement) return;
    if (this.multiple) {
      const valArr = this.value || [];
      Array.from(this.selectElement.options).forEach((option) => {
        option.selected = valArr.includes(option.value);
      });
    } else this.selectElement.value = this.value;
    this.requestUpdate();
  }
};
_isValueInitialized = new WeakMap();
_Select_instances = new WeakSet();
shouldShowFooter_fn = function() {
  return !this.plain && this.invalid;
};
_handleSelectElementChange = new WeakMap();
setValueFromSelectElement_fn = function() {
  if (!this.selectElement) return;
  if (this.multiple) {
    const selectedOptions = Array.from(this.selectElement.selectedOptions);
    this.value = selectedOptions.map((o) => o.value);
  } else {
    this.value = this.selectElement.value;
  }
};
/**
 * Renders the main content area of the select field.
 * Composes the field from various sub-elements.
 */
renderFieldContents_fn = function() {
  const elements = [
    __privateMethod(this, _Select_instances, renderSlotLead_fn).call(this),
    __privateMethod(this, _Select_instances, renderMainSlot_fn).call(this),
    __privateMethod(this, _Select_instances, renderMainLabel_fn).call(this),
    __privateMethod(this, _Select_instances, renderChevron_fn).call(this)
  ];
  return elements.map((element) => html`${element}`);
};
/**
 * Renders the leading slot content if provided.
 */
renderSlotLead_fn = function() {
  return html`<slot name="lead" slot="lead"></slot>`;
};
/**
 * Renders the main label text for single-select mode.
 * Shows either selected option text or placeholder.
 */
renderMainLabel_fn = function() {
  if (!this.multiple) {
    return html`<label id="placeholder" class="native-control"
        >${this.displayValue}</label
      >`;
  }
};
/**
 * Renders the main slot and select container.
 * The select container is where the native select is moved to.
 */
renderMainSlot_fn = function() {
  return html`<div class="select-container"></div>`;
};
/**
 * Renders the chevron icon button for single-select mode.
 * Provides visual indication of dropdown functionality.
 */
renderChevron_fn = function() {
  if (!this.multiple) {
    return html`
        <gds-icon-chevron-bottom slot="action"></gds-icon-chevron-bottom>
      `;
  }
};
Select.styles = [tokens, formControlHostStyles, SelectStyles];
__decorateClass([
  property({ attribute: "supporting-text" })
], Select.prototype, "supportingText", 2);
__decorateClass([
  property({
    attribute: "show-extended-supporting-text",
    type: Boolean,
    reflect: true
  })
], Select.prototype, "showExtendedSupportingText", 2);
__decorateClass([
  property({ type: String })
], Select.prototype, "size", 2);
__decorateClass([
  property({ type: Boolean })
], Select.prototype, "plain", 2);
__decorateClass([
  query("select")
], Select.prototype, "selectElement", 2);
__decorateClass([
  property()
], Select.prototype, "value", 1);
__decorateClass([
  query(".select-container")
], Select.prototype, "_elSelectContainer", 2);
__decorateClass([
  observeLightDOM({
    childList: true,
    subtree: true,
    attributes: true,
    characterData: true
  })
], Select.prototype, "_captureDOM", 1);
__decorateClass([
  watch("value")
], Select.prototype, "_handleValueChange", 1);
Select = __decorateClass([
  localized()
], Select);
let GdsSelect = class extends withLayoutChildProps(
  withSizeXProps(withMarginProps(Select))
) {
};
GdsSelect = __decorateClass([
  gdsCustomElement("gds-select", {
    dependsOn: [
      GdsFormControlHeader,
      GdsFormControlFooter,
      GdsFieldBase,
      IconChevronBottom
    ]
  })
], GdsSelect);
export {
  GdsSelect
};
