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

/**
 * <nav-group-ui> — Collapsible labeled group of nav items inside <nav-ui>.
 *
 * Consolidates the prior `app-nav-group-ui` + `section-nav-group-ui`
 * per ADR-0015 § Nav consolidation. Behavior is unified; the parent
 * <nav-ui>'s [variant] drives the visual treatment.
 *
 * Has icon, label, optional badge, and a caret indicating open/closed.
 * When the parent <nav-ui> is collapsed (primary variant), clicking the
 * group opens a popover with its children instead of toggling inline
 * expansion. When [collapsible] (or always for primary variant), inline
 * click + keyboard toggle is supported.
 */

import { UIElement } from '../../core/element.js';
import { anchorPopover } from '../../core/anchor.js';
import { logicalSlotted } from '../../core/logical-children.js';

export class UINavGroup extends UIElement {
  static properties = {
    text:        { type: String,  default: '',    reflect: true },
    icon:        { type: String,  default: '',    reflect: true },
    badge:       { type: String,  default: '',    reflect: true },
    open:        { type: Boolean, default: false, reflect: true },
    collapsible: { type: Boolean, default: true,  reflect: true },
    variant:     { type: String,  default: '',    reflect: true },
  };

  static template = () => null;

  #popover = null;
  #anchorCleanup = null;
  #headerEl = null;

  #onHeaderKey = (e) => {
    if (!this.collapsible) return;
    if (e.key === 'Enter' || e.key === ' ') {
      e.preventDefault();
      this.open = !this.open;
      this.dispatchEvent(new CustomEvent('group-toggle', {
        bubbles: true,
        detail: { text: this.text, open: this.open },
      }));
    }
  };

  connected() {
    this.setAttribute('role', 'group');

    if (!logicalSlotted(this, 'header').length) {
      this.#headerEl = document.createElement('div');
      this.#headerEl.setAttribute('slot', 'header');
      this.#headerEl.setAttribute('tabindex', '0');
      this.#headerEl.innerHTML = `
        <span slot="icon">${this.icon ? `<icon-ui name="${this.icon}"></icon-ui>` : ''}</span>
        <span slot="text">${this.text}</span>
        ${this.badge ? `<span slot="badge">${this.badge}</span>` : ''}
        <icon-ui slot="caret" name="caret-right"></icon-ui>
      `;
      this.prepend(this.#headerEl);
    } else {
      this.#headerEl = logicalSlotted(this, 'header')[0];
    }

    this.#headerEl?.addEventListener('keydown', this.#onHeaderKey);
  }

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

    const badgeEl = this.querySelector('[slot="header"] [slot="badge"]');
    if (badgeEl) badgeEl.textContent = this.badge;

    this.setAttribute('aria-expanded', String(this.open));
  }

  showPopover() {
    if (!this.#popover) {
      this.#popover = document.createElement('div');
      this.#popover.setAttribute('slot', 'popover');
      this.#popover.setAttribute('popover', 'auto');

      const label = document.createElement('div');
      label.setAttribute('slot', 'popover-label');
      label.textContent = this.text;
      this.#popover.appendChild(label);

      for (const child of this.querySelectorAll(':scope > nav-item-ui')) {
        const opt = document.createElement('div');
        opt.setAttribute('role', 'option');
        opt.dataset.sourceValue = child.getAttribute('value') || '';
        opt.textContent = child.text;
        opt.addEventListener('click', () => {
          const nav = this.closest('nav-ui');
          if (nav) nav.select(child);
          this.#popover.hidePopover();
        });
        this.#popover.appendChild(opt);
      }

      this.appendChild(this.#popover);

      this.#popover.addEventListener('toggle', (e) => {
        if (e.newState === 'closed') {
          this.#anchorCleanup?.();
          this.#anchorCleanup = null;
        }
      });
    }

    for (const opt of this.#popover.querySelectorAll('[role="option"]')) {
      const srcValue = opt.dataset.sourceValue;
      const src = srcValue
        ? this.querySelector(`:scope > nav-item-ui[value="${srcValue}"]`)
        : null;
      if (src?.hasAttribute('selected')) {
        opt.setAttribute('aria-current', 'page');
        opt.setAttribute('aria-selected', 'true');
      } else {
        opt.removeAttribute('aria-current');
        opt.removeAttribute('aria-selected');
      }
    }

    this.#popover.showPopover();

    this.#anchorCleanup?.();
    this.#anchorCleanup = anchorPopover(this, this.#popover, {
      placement: 'right', gap: 4,
    });
  }

  disconnected() {
    this.#headerEl?.removeEventListener('keydown', this.#onHeaderKey);
    this.#anchorCleanup?.();
    this.#anchorCleanup = null;
    this.#popover?.hidePopover?.();
  }
}
