/**
 * Non-side-effect class export for `<radio-ui>`.
 *
 * Importing this file gives you the class(es) without auto-registering the tag.
 * Useful for test isolation, subclassing with tag-name override, or selective
 * composition.
 *
 * The auto-register path stays at `@adia-ai/web-components/components/radio`
 * (which imports this file + calls `defineIfFree()`).
 *
 * @see ../../USAGE.md#registration--auto-vs-explicit
 */

/**
 * <radio-ui> — Radio button. The host IS the control.
 * Pure CSS dot via [slot="dot"]::after inner circle. No SVG, no inset shadow hack.
 */

import { UIFormElement } from '../../core/form.js';
import { html } from '../../core/element.js';

export class UIRadio extends UIFormElement {
  static labelDeprecated = false;  // §170 (v0.5.4): label is first-class per radio.yaml
  static properties = {
    ...UIFormElement.properties,
    checked:  { type: Boolean, default: false, reflect: true },
    label:    { type: String,  default: '', reflect: true },
  };

  static template = () => html`<span slot="dot"></span>`;

  connected() {
    super.connected();
    this.setAttribute('role', 'radio');
    this.setAttribute('tabindex', '0');
    this.addEventListener('click', this.#select);
    this.addEventListener('keydown', this.#onKey);
  }

  render() {
    this.setAttribute('aria-checked', String(this.checked));
    if (this.label) this.setAttribute('aria-label', this.label);
    if (this.checked) this.syncValue(this.value || 'on');
  }

  #select = () => {
    if (this.disabled || this.checked) return;
    const group = this.closest('fieldset, [role="radiogroup"]') || this.parentElement;
    if (group) {
      for (const r of group.querySelectorAll(`radio-ui[name="${this.name}"]`)) {
        if (r !== this && r.checked) r.checked = false;
      }
    }
    this.checked = true;
    this.dispatchEvent(new CustomEvent('change', { bubbles: true, detail: { value: this.value, checked: this.checked } }));
  };

  #onKey = (e) => {
    if (e.key === ' ' || e.key === 'Enter') { e.preventDefault(); this.#select(); }
    if (e.key === 'ArrowDown' || e.key === 'ArrowRight') {
      e.preventDefault();
      const next = this.#sibling(1);
      if (next) { next.focus(); next.click(); }
    }
    if (e.key === 'ArrowUp' || e.key === 'ArrowLeft') {
      e.preventDefault();
      const prev = this.#sibling(-1);
      if (prev) { prev.focus(); prev.click(); }
    }
  };

  #sibling(dir) {
    const group = this.closest('fieldset, [role="radiogroup"]') || this.parentElement;
    const radios = [...(group?.querySelectorAll(`radio-ui[name="${this.name}"]`) || [])];
    const i = radios.indexOf(this);
    return radios[(i + dir + radios.length) % radios.length] || null;
  }

  disconnected() {
    super.disconnected();
    this.removeEventListener('click', this.#select);
    this.removeEventListener('keydown', this.#onKey);
  }
}
