import {
  SdRadio
} from "./chunk.BR5PPGBX.js";
import {
  FormControlController,
  customErrorValidityState,
  validValidityState,
  valueMissingValidityState
} from "./chunk.C3WIBDGG.js";
import {
  HasSlotController
} from "./chunk.IVMQWO2L.js";
import {
  watch
} from "./chunk.X2OQMWGY.js";
import {
  SolidElement,
  customElement
} from "./chunk.H53WQBDK.js";
import {
  __decorateClass
} from "./chunk.S3NI7NKU.js";

// src/components/radio-group/radio-group.ts
import { css, html } from "lit";
import { property, query, state } from "lit/decorators.js";
import cx from "classix";
var SdRadioGroup = class extends SolidElement {
  constructor() {
    super(...arguments);
    this.formControlController = new FormControlController(this);
    this.hasSlotController = new HasSlotController(this, "label", "error-text");
    this.customValidityMessage = "";
    this.hasButtonGroup = false;
    this.defaultValue = "";
    this.showInvalidStyle = false;
    this.size = "lg";
    this.required = false;
    this.orientation = "vertical";
    this.label = "";
    this.helpText = "";
    this.name = "option";
    this.value = "";
    this.form = "";
  }
  /** Gets the validity state object */
  get validity() {
    const isRequiredAndEmpty = this.required && !this.value;
    const hasCustomValidityMessage = this.customValidityMessage !== "";
    if (hasCustomValidityMessage) {
      return customErrorValidityState;
    } else if (isRequiredAndEmpty) {
      return valueMissingValidityState;
    }
    return validValidityState;
  }
  /** Gets the validation message */
  get validationMessage() {
    const isRequiredAndEmpty = this.required && !this.value;
    const hasCustomValidityMessage = this.customValidityMessage !== "";
    if (hasCustomValidityMessage) {
      return this.customValidityMessage;
    } else if (isRequiredAndEmpty) {
      return this.validationInput.validationMessage;
    }
    return "";
  }
  connectedCallback() {
    super.connectedCallback();
    this.defaultValue = this.value;
  }
  firstUpdated() {
    this.formControlController.updateValidity();
  }
  updated(changedProperties) {
    super.updated(changedProperties);
    this.syncAriaDescription();
  }
  // Set aria-description imperatively as a VoiceOver workaround here so static a11y linters do not reject role="radiogroup".
  syncAriaDescription() {
    var _a;
    const fieldset = (_a = this.shadowRoot) == null ? void 0 : _a.querySelector("fieldset");
    const message = this.showInvalidStyle ? this.validationMessage : "";
    if (message) {
      fieldset == null ? void 0 : fieldset.setAttribute("aria-description", message);
    } else {
      fieldset == null ? void 0 : fieldset.removeAttribute("aria-description");
    }
  }
  getAllRadios() {
    const radios = [...this.querySelectorAll("sd-6-22-0-radio, sd-6-22-0-radio-button")];
    if (radios.length === 0) {
      console.warn("No radios found in the radio group.");
    }
    return radios;
  }
  handleRadioClick(event) {
    const target = event.target.closest("sd-6-22-0-radio, sd-6-22-0-radio-button");
    const oldValue = this.value;
    const radios = this.getAllRadios();
    if (radios.length === 0) {
      return;
    }
    if (target.disabled) {
      return;
    }
    this.value = target.value;
    radios.forEach((radio) => radio.checked = radio === target);
    if (this.value !== oldValue) {
      this.emit("sd-change");
      this.emit("sd-input");
    }
  }
  handleKeyDown(event) {
    var _a;
    if (!["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", " "].includes(event.key)) {
      return;
    }
    const radios = this.getAllRadios().filter((radio) => !radio.disabled);
    if (radios.length === 0) {
      return;
    }
    const checkedRadio = (_a = radios.find((radio) => radio.checked)) != null ? _a : radios[0];
    const incr = event.key === " " ? 0 : ["ArrowUp", "ArrowLeft"].includes(event.key) ? -1 : 1;
    const oldValue = this.value;
    let index = radios.indexOf(checkedRadio) + incr;
    if (index < 0) {
      index = radios.length - 1;
    }
    if (index > radios.length - 1) {
      index = 0;
    }
    this.getAllRadios().forEach((radio) => {
      radio.checked = false;
      if (!this.hasButtonGroup) {
        radio.tabIndex = -1;
      }
    });
    this.value = radios[index].value;
    radios[index].checked = true;
    if (!this.hasButtonGroup) {
      radios[index].tabIndex = 0;
      radios[index].focus();
    } else {
      radios[index].shadowRoot.querySelector("button").focus();
    }
    if (this.value !== oldValue) {
      this.emit("sd-change");
      this.emit("sd-input");
    }
    event.preventDefault();
  }
  /** Move focus to the checked radio (or the first one if none are checked) */
  focus() {
    const radios = this.getAllRadios();
    if (radios.length === 0) {
      return;
    }
    const checked = radios.find((radio) => radio.checked);
    const radioToFocus = checked || radios[0];
    if (radioToFocus) {
      radioToFocus.focus();
    }
  }
  handleInvalid(event) {
    this.formControlController.setValidity(false);
    this.formControlController.emitInvalidEvent(event);
    this.invalidMessage.textContent = event.target.validationMessage;
  }
  async syncRadioElements() {
    var _a, _b;
    const radios = this.getAllRadios();
    if (radios.length === 0) {
      this.hasButtonGroup = false;
      return;
    }
    await Promise.all(
      // Sync the checked state and size
      radios.map(async (radio) => {
        await radio.updateComplete;
        radio.checked = radio.value === this.value;
        radio.size = this.size;
        if (radio instanceof SdRadio) {
          radio.invalid = this.showInvalidStyle;
        }
      })
    );
    this.hasButtonGroup = radios.some((radio) => radio.tagName.toLowerCase() === "sd-6-22-0-radio-button");
    if (!radios.some((radio) => radio.checked)) {
      if (this.hasButtonGroup) {
        const buttonRadio = (_a = radios[0].shadowRoot) == null ? void 0 : _a.querySelector("button");
        if (buttonRadio) {
          buttonRadio.tabIndex = 0;
        }
      } else {
        radios[0].tabIndex = 0;
      }
    }
    if (this.hasButtonGroup) {
      const buttonGroup = (_b = this.shadowRoot) == null ? void 0 : _b.querySelector("sd-6-22-0-button-group");
      if (buttonGroup) {
        buttonGroup.disableRole = true;
      }
    }
  }
  syncRadios() {
    if (customElements.get("sd-6-22-0-radio") && customElements.get("sd-6-22-0-radio-button")) {
      this.syncRadioElements();
      return;
    }
    if (customElements.get("sd-6-22-0-radio")) {
      this.syncRadioElements();
    } else {
      customElements.whenDefined("sd-6-22-0-radio").then(() => this.syncRadios());
    }
    if (customElements.get("sd-6-22-0-radio-button")) {
      this.syncRadioElements();
    } else {
      customElements.whenDefined("sd-6-22-0-radio-button").then(() => this.syncRadios());
    }
  }
  updateCheckedRadio() {
    const radios = this.getAllRadios();
    if (radios.length === 0) {
      return;
    }
    radios.forEach((radio) => radio.checked = radio.value === this.value);
    this.formControlController.setValidity(this.validity.valid);
  }
  handleSizeChange() {
    this.syncRadios();
  }
  handleInvalidChange() {
    this.syncRadios();
  }
  handleValueChange() {
    if (this.hasUpdated) {
      this.updateCheckedRadio();
      this.reportValidity();
    }
  }
  /** Checks for validity but does not show a validation message. Returns `true` when valid and `false` when invalid. */
  checkValidity() {
    const isRequiredAndEmpty = this.required && !this.value;
    const hasCustomValidityMessage = this.customValidityMessage !== "";
    if (isRequiredAndEmpty || hasCustomValidityMessage) {
      this.formControlController.emitInvalidEvent();
      return false;
    }
    return true;
  }
  /** Gets the associated form, if one exists. */
  getForm() {
    return this.formControlController.getForm();
  }
  /** Checks for validity and shows the browser's validation message if the control is invalid. */
  reportValidity() {
    const isValid = this.validity.valid;
    this.formControlController.setValidity(isValid);
    this.validationInput.hidden = true;
    clearTimeout(this.validationTimeout);
    this.formControlController.fakeUserInteraction();
    if (!isValid) {
      this.validationInput.hidden = false;
      this.validationInput.reportValidity();
      this.validationTimeout = setTimeout(() => this.validationInput.hidden = true, 1e4);
    }
    return isValid;
  }
  /** Sets a custom validation message. Pass an empty string to restore validity. */
  setCustomValidity(message = "") {
    this.customValidityMessage = message;
    this.validationInput.setCustomValidity(message);
    this.formControlController.updateValidity();
  }
  render() {
    const hasLabelSlot = this.hasSlotController.test("label");
    const hasLabel = this.label ? true : hasLabelSlot;
    const hasHelpTextSlot = this.hasSlotController.test("help-text");
    const hasHelpText = this.helpText ? true : !!hasHelpTextSlot;
    const hasTooltipSlot = this.hasSlotController.test("tooltip");
    const defaultSlot = html`<slot @slotchange="${this.syncRadios}" @click="${this.handleRadioClick}" @keydown="${this.handleKeyDown}"></slot>`;
    return html`<fieldset part="form-control" class="${cx(
      "border-0 p-0 m-0 flex flex-col",
      {
        /* sizes, fonts */
        sm: "text-sm",
        md: "text-base",
        lg: "text-base"
      }[this.size]
    )}" role="radiogroup" aria-describedby="invalid-message" aria-labelledby="label">${hasLabel || hasTooltipSlot ? html`<div class="flex items-center gap-1 mb-2"><legend part="form-control-label" id="label" class="${cx("p-0 font-bold leading-normal text-black text-left", hasLabel ? "inline-block" : "hidden")}" @click="${this.focus}" aria-hidden="${hasLabel ? "false" : "true"}"><slot name="label">${this.label}</slot></legend>${hasTooltipSlot ? html`<slot name="tooltip"></slot>` : ""}</div>` : null}<div part="form-control-input" class="${cx(
      "flex",
      {
        vertical: "flex-col",
        horizontal: "flex-row"
      }[this.orientation]
    )}"><div class="sr-only"><label><input id="validation-input" type="text" ?required="${this.required}" aria-labelledby="label" tabindex="-1" hidden @invalid="${this.handleInvalid}"></label></div>${this.hasButtonGroup ? html`<sd-6-22-0-button-group class="border border-primary sd-6-22-0-radio-button-group-border-radius sd-6-22-0-radio-button-group-border-width sd-6-22-0-radio-button-group-padding" part="button-group" exportparts="base:button-group__base" role="presentation">${defaultSlot}</sd-6-22-0-button-group>` : defaultSlot}</div></fieldset><slot name="help-text" part="form-control-help-text" id="help-text" class="${cx("text-sm text-neutral-700 mt-2", hasHelpText ? "block" : "hidden")}" aria-hidden="${!hasHelpText}">${this.helpText}</slot><div part="invalid-icon-message" class="flex items-center gap-2 mt-2">${this.showInvalidStyle ? html`<sd-6-22-0-icon part="invalid-icon" class="${cx("text-error")}" library="_internal" name="risk"></sd-6-22-0-icon>` : ""} ${this.formControlController.renderInvalidMessage(this.size)}</div>`;
  }
};
/**
 * Inherits Tailwind classes and includes additional styling.
 */
SdRadioGroup.styles = [
  ...SolidElement.styles,
  css`/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */@layer theme,base,components,utilities;
:host{display:block}:host([orientation=vertical]) ::slotted(sd-6-22-0-radio){margin-bottom:var(--sd-spacing-2);display:flex}:host([orientation=vertical]) ::slotted(sd-6-22-0-radio:last-of-type){margin-bottom:calc(var(--sd-spacing-1) * 0)}:host([orientation=horizontal]) ::slotted(sd-6-22-0-radio){margin-right:var(--sd-spacing-6)}:host([orientation=horizontal]) ::slotted(sd-6-22-0-radio:last-of-type){margin-right:calc(var(--sd-spacing-1) * 0)}:host([orientation=horizontal]):host([size=sm]) ::slotted(sd-6-22-0-radio){margin-right:var(--sd-spacing-4)}:host([orientation=horizontal]):host([size=sm]) ::slotted(sd-6-22-0-radio:last-of-type){margin-right:calc(var(--sd-spacing-1) * 0)}:host([required]) #label::after{content:' *'}:host:has(sd-6-22-0-button-group){display:inline-flex}`
];
__decorateClass([
  query("slot:not([name])")
], SdRadioGroup.prototype, "defaultSlot", 2);
__decorateClass([
  query("#validation-input")
], SdRadioGroup.prototype, "validationInput", 2);
__decorateClass([
  query("#invalid-message")
], SdRadioGroup.prototype, "invalidMessage", 2);
__decorateClass([
  state()
], SdRadioGroup.prototype, "hasButtonGroup", 2);
__decorateClass([
  state()
], SdRadioGroup.prototype, "defaultValue", 2);
__decorateClass([
  state()
], SdRadioGroup.prototype, "showInvalidStyle", 2);
__decorateClass([
  property({ type: String, reflect: true })
], SdRadioGroup.prototype, "size", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], SdRadioGroup.prototype, "required", 2);
__decorateClass([
  property({ type: String, reflect: true })
], SdRadioGroup.prototype, "orientation", 2);
__decorateClass([
  property({ type: String, reflect: true })
], SdRadioGroup.prototype, "label", 2);
__decorateClass([
  property({ type: String, attribute: "help-text", reflect: true })
], SdRadioGroup.prototype, "helpText", 2);
__decorateClass([
  property({ type: String, reflect: true })
], SdRadioGroup.prototype, "name", 2);
__decorateClass([
  property()
], SdRadioGroup.prototype, "value", 2);
__decorateClass([
  property({ type: String, reflect: true })
], SdRadioGroup.prototype, "form", 2);
__decorateClass([
  watch("size", { waitUntilFirstUpdate: true })
], SdRadioGroup.prototype, "handleSizeChange", 1);
__decorateClass([
  watch("showInvalidStyle", { waitUntilFirstUpdate: true })
], SdRadioGroup.prototype, "handleInvalidChange", 1);
__decorateClass([
  watch("value")
], SdRadioGroup.prototype, "handleValueChange", 1);
SdRadioGroup = __decorateClass([
  customElement("sd-6-22-0-radio-group")
], SdRadioGroup);

export {
  SdRadioGroup
};
