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

/**
 * <breadcrumb-ui separator="/">
 *   <a href="/"><icon-ui name="house"></icon-ui></a>
 *   <a href="#">Workspace</a>
 *   <span>Current page</span>
 * </breadcrumb-ui>
 *
 * Trail with auto-inserted separators. Items can be plain elements or
 * `<a href>` links; the last item is marked `aria-current="page"`.
 *
 * Variants:
 *   • Default — text-only crumbs
 *   • Icon-leading — first child is `<icon-ui>` (or a link wrapping one)
 *   • Collapsed — `[collapse]` hides middle crumbs into a `…` overflow
 *     popover; keeps `[collapse-keep-leading]` (default 1) and
 *     `[collapse-keep-trailing]` (default 2) visible at the edges.
 *
 * The overflow uses `<popover-ui>` so it rides the top-layer (no
 * z-index battles inside scrolling containers).
 */

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

export class UIBreadcrumb extends UIElement {
  static properties = {
    separator:            { type: String,  default: '/', reflect: true },
    collapse:             { type: Boolean, default: false, reflect: true },
    collapseKeepLeading:  { type: Number,  default: 1, attribute: 'collapse-keep-leading', reflect: true },
    collapseKeepTrailing: { type: Number,  default: 2, attribute: 'collapse-keep-trailing', reflect: true },
  };

  static template = () => null;

  connected() {
    this.setAttribute('role', 'navigation');
    this.setAttribute('aria-label', 'Breadcrumb');
  }

  render() {
    // Strip prior chrome so render is idempotent across attribute changes.
    this.querySelectorAll('[data-sep], [data-overflow]').forEach(el => el.remove());

    const items = Array.from(this.children).filter(c =>
      !c.hasAttribute('data-sep') && !c.hasAttribute('data-overflow')
    );
    const last = items.length - 1;

    // Reset per-item chrome
    items.forEach((child, i) => {
      child.setAttribute('data-item', '');
      child.removeAttribute('data-collapsed');
      if (i === last) child.setAttribute('aria-current', 'page');
      else child.removeAttribute('aria-current');
    });

    const keepLeading  = Math.max(0, this.collapseKeepLeading | 0);
    const keepTrailing = Math.max(0, this.collapseKeepTrailing | 0);
    const minLen = keepLeading + keepTrailing + 1;
    const shouldCollapse = this.collapse && items.length >= Math.max(minLen, 4);

    if (shouldCollapse) {
      const collapsed = items.slice(keepLeading, items.length - keepTrailing);
      collapsed.forEach(el => el.setAttribute('data-collapsed', ''));

      const overflow = this.#buildOverflow(collapsed);
      if (keepLeading > 0) items[keepLeading - 1].after(overflow);
      else this.prepend(overflow);
    }

    // Stamp separators between every consecutive visible sibling.
    const visible = Array.from(this.children).filter(c =>
      !c.hasAttribute('data-sep') && !c.hasAttribute('data-collapsed')
    );
    for (let i = 0; i < visible.length - 1; i++) {
      const sep = document.createElement('span');
      sep.setAttribute('data-sep', '');
      sep.setAttribute('aria-hidden', 'true');
      sep.textContent = this.separator;
      visible[i].after(sep);
    }
  }

  #buildOverflow(collapsedItems) {
    // Use <menu-ui> as the canonical popover-list primitive — same surface
    // tokens as select-ui's listbox + menu-ui's action menu, with keyboard
    // nav, top-layer rendering, and anchor positioning for free.
    const menu = document.createElement('menu-ui');
    menu.setAttribute('data-overflow', '');
    menu.setAttribute('data-item', '');
    menu.setAttribute('placement', 'bottom-start');

    const trigger = document.createElement('button-ui');
    trigger.setAttribute('slot', 'trigger');
    trigger.setAttribute('text', '…');
    trigger.setAttribute('variant', 'ghost');
    trigger.setAttribute('size', 'sm');
    trigger.setAttribute('aria-label', 'Show collapsed crumbs');
    menu.appendChild(trigger);

    for (const item of collapsedItems) {
      const mi = document.createElement('menu-item-ui');
      mi.setAttribute('text', item.textContent.trim());
      // Encode the link target as the menu-item value; navigated on action.
      if (item.tagName === 'A' && item.hasAttribute('href')) {
        mi.setAttribute('value', item.getAttribute('href'));
      }
      menu.appendChild(mi);
    }

    // menu-ui dispatches `action` with `detail: { value, text }` on item
    // activation. Navigate to the encoded href; ignore placeholder `#`.
    menu.addEventListener('action', (e) => {
      const href = e.detail?.value;
      if (href && href !== '#') window.location.href = href;
    });

    return menu;
  }
}
