/**
 * Non-side-effect class export for `<switch-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/switch`
 * (which imports this file + calls `defineIfFree()`).
 *
 * @see ../../USAGE.md#registration--auto-vs-explicit
 */

/**
 * <switch-ui> — Toggle switch. The host IS the control.
 * Pure CSS track + thumb, no native <input>.
 */

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

export class UISwitch extends UIFormElement {
  static labelDeprecated = false;  // §170 (v0.5.4): label is first-class per switch.yaml
  static properties = {
    ...UIFormElement.properties,
    checked:  { type: Boolean, default: false, reflect: true },
    label:    { type: String,  default: '', reflect: true },
    size:     { type: String,  default: '', reflect: true },
    // §184 (v0.5.5, FEEDBACK-08 §7): caption beneath the toggle.
    // switch.yaml has declared `hint` since §170 but the template
    // never rendered it — this arc closes the spec-vs-impl gap +
    // wires aria-describedby on the host for screen readers.
    hint:     { type: String,  default: '', reflect: true },
  };

  // §184: per-instance hint id counter for aria-describedby wiring.
  static #hintSeq = 0;

  static template = (el) => {
    const hintId = el.hint ? `switch-hint-${++UISwitch.#hintSeq}` : '';
    if (hintId) el.setAttribute('aria-describedby', hintId);
    else el.removeAttribute('aria-describedby');
    return html`
      <span slot="track"><span slot="thumb"></span></span>
      ${el.label ? html`<span slot="label">${el.label}</span>` : null}
      ${el.hint ? html`<span slot="hint" id=${hintId}>${el.hint}</span>` : null}
    `;
  };

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

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

  #toggle = () => {
    if (this.disabled) return;
    this.checked = !this.checked;
    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.#toggle(); }
  };

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