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

/**
 * <action-list-ui>
 *   <action-item-ui icon="plus"     text="New Project" value="new"></action-item-ui>
 *   <action-item-ui icon="users"    text="Invite Team" value="invite"></action-item-ui>
 *   <action-item-ui icon="download" text="Export Data" value="export"></action-item-ui>
 * </action-list-ui>
 *
 * Inline (non-dropdown) list of command actions. Think of it as a menu that
 * stays open — useful for quick-actions cards, settings rails, sidebar shortcuts.
 *
 * Differs from <menu-ui> (which renders in a popover) and <list-ui> (which is
 * passive — no hover/click semantics).
 *
 * Fires `action` CustomEvent with { value, text, item } when an item is clicked
 * or activated via keyboard (Enter / Space). Keyboard nav: ArrowUp/Down, Home/End.
 */

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

export class UIActionList extends UIElement {
  static properties = {};
  static template = () => null;

  #bound = false;

  connected() {
    this.setAttribute('role', 'list');
    if (!this.#bound) {
      this.#bound = true;
      this.addEventListener('click', this.#onClick);
      this.addEventListener('keydown', this.#onKey);
    }
  }

  disconnected() {
    this.removeEventListener('click', this.#onClick);
    this.removeEventListener('keydown', this.#onKey);
    this.#bound = false;
  }

  #items() {
    return Array.from(this.querySelectorAll(':scope > action-item-ui:not([disabled])'));
  }

  #onClick = (e) => {
    const item = e.target.closest('action-item-ui');
    if (!item || item.hasAttribute('disabled')) return;
    if (!this.contains(item)) return;
    this.dispatchEvent(new CustomEvent('action', {
      bubbles: true,
      detail: { value: item.getAttribute('value') || '', text: item.getAttribute('text') || item.textContent.trim(), item },
    }));
  };

  #onKey = (e) => {
    const items = this.#items();
    if (!items.length) return;
    const active = document.activeElement?.closest?.('action-item-ui');
    const i = active ? items.indexOf(active) : -1;
    const focus = (idx) => {
      const next = items[(idx + items.length) % items.length];
      next?.focus?.({ preventScroll: true });
    };
    switch (e.key) {
      case 'ArrowDown': e.preventDefault(); focus(i + 1); break;
      case 'ArrowUp':   e.preventDefault(); focus(i - 1); break;
      case 'Home':      e.preventDefault(); focus(0); break;
      case 'End':       e.preventDefault(); focus(items.length - 1); break;
      case 'Enter':
      case ' ': {
        if (active) { e.preventDefault(); active.click(); }
        break;
      }
    }
  };
}

export class UIActionItem extends UIElement {
  static properties = {
    icon:     { type: String,  default: '', reflect: true },
    text:     { type: String,  default: '', reflect: true },
    value:    { type: String,  default: '', reflect: true },
    variant:  { type: String,  default: 'default', reflect: true },
    disabled: { type: Boolean, default: false, reflect: true },
  };

  static template = () => null;

  connected() {
    this.setAttribute('role', 'listitem');
    if (!this.hasAttribute('tabindex')) this.setAttribute('tabindex', '0');
    this.#stamp();
    this.#syncAria();
  }

  #stamp() {
    if (this.querySelector('[slot="text"]')) return;

    if (this.icon) {
      const iconEl = document.createElement('icon-ui');
      iconEl.setAttribute('slot', 'icon');
      iconEl.setAttribute('name', this.icon);
      this.appendChild(iconEl);
    }

    if (this.text) {
      const span = document.createElement('span');
      span.setAttribute('slot', 'text');
      span.textContent = this.text;
      this.appendChild(span);
    }
  }

  #syncAria() {
    if (this.disabled) {
      this.setAttribute('aria-disabled', 'true');
      this.setAttribute('tabindex', '-1');
    } else {
      this.removeAttribute('aria-disabled');
      this.setAttribute('tabindex', '0');
    }
  }

  render() {
    const iconEl = this.querySelector('[slot="icon"]');
    if (this.icon) {
      if (iconEl) iconEl.setAttribute('name', this.icon);
      else {
        const el = document.createElement('icon-ui');
        el.setAttribute('slot', 'icon');
        el.setAttribute('name', this.icon);
        this.prepend(el);
      }
    } else if (iconEl) {
      iconEl.remove();
    }

    const textEl = this.querySelector('[slot="text"]');
    if (textEl) textEl.textContent = this.text;

    this.#syncAria();
  }
}
