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

/**
 * <description-list-ui> — Semantic dl/dt/dd wrapper for key-value metadata.
 *
 * Pure layout component. Renders terms and descriptions in a grid.
 *
 * Declarative use (recommended — preserves semantics for SSR + AT):
 *   <description-list-ui>
 *     <dt>Status</dt><dd>Active</dd>
 *     <dt>Plan</dt><dd>Pro</dd>
 *   </description-list-ui>
 *
 * Programmatic use:
 *   <description-list-ui
 *     items='[{"term":"Status","description":"Active"}]'></description-list-ui>
 *
 * Props:
 *   layout    — "stacked" (term above, default) | "inline" (term : value on one row)
 *   align     — "start" (default) | "between" (space-between for inline layout)
 *   items     — optional JSON array of {term, description} pairs
 */

import { UIElement } from '../../core/element.js';

export class UIDescriptionList extends UIElement {
  static properties = {
    layout: { type: String, default: 'stacked', reflect: true },
    align:  { type: String, default: 'start', reflect: true },
  };

  static template = () => null;

  connected() {
    // ARIA 1.2: list role requires listitem children, but <dt>/<dd>
    // aren't listitems. group role is the accurate fit for a
    // labeled-pairs grouping.
    this.setAttribute('role', 'group');
  }

  render() {
    const items = this.#resolveItems();
    if (!items.length) return; // preserve declarative children

    this.innerHTML = items.map(({ term, description }) => `
      <dt data-dl-term>${this.#escape(term)}</dt>
      <dd data-dl-desc>${this.#escape(description)}</dd>
    `).join('');
  }

  #resolveItems() {
    if (Array.isArray(this._items) && this._items.length) return this._items;
    const attr = this.getAttribute('items');
    if (attr) {
      try {
        const parsed = JSON.parse(attr);
        if (Array.isArray(parsed)) return parsed;
      } catch { /* fall through */ }
    }
    return [];
  }

  set items(v) {
    this._items = Array.isArray(v) ? v : [];
    this.render();
  }

  get items() {
    return this._items || [];
  }

  #escape(s) {
    return String(s == null ? '' : s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
  }
}
