/**
 * List page tab bar — horizontal scroll behavior.
 * Keeps tabs on a single line, scrolls the active tab into view on mount,
 * and toggles has-overflow/at-start/at-end classes that drive the CSS
 * gradient fade masks.
 */
import { resolveHost } from '../core/app-dom.js';

const BOUND_ATTR = 'data-app-list-tabs-bound';
const EDGE_TOLERANCE = 1;

const updateOverflow = (el) => {
  const hasOverflow = el.scrollWidth - el.clientWidth > EDGE_TOLERANCE;
  el.classList.toggle('has-overflow', hasOverflow);
  if (!hasOverflow) {
    el.classList.remove('at-start', 'at-end');
    return;
  }
  const atStart = el.scrollLeft <= EDGE_TOLERANCE;
  const atEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - EDGE_TOLERANCE;
  el.classList.toggle('at-start', atStart);
  el.classList.toggle('at-end', atEnd);
};

const scrollActiveIntoView = (el) => {
  const active = el.querySelector('.is-active');
  if (!active) {
    return;
  }
  const activeCenter = active.offsetLeft + active.offsetWidth / 2;
  const target = activeCenter - el.clientWidth / 2;
  const max = el.scrollWidth - el.clientWidth;
  el.scrollLeft = Math.max(0, Math.min(target, max));
};

export function initListTabs(root = document, options = {}) {
  const selector = String(options.selector || '.app-list-tabs').trim() || '.app-list-tabs';
  const host = resolveHost(root);
  const cleanupFns = [];
  const bound = [];

  const tabs = Array.from(host.querySelectorAll(selector));
  tabs.forEach((el) => {
    if (el.getAttribute(BOUND_ATTR) === '1') {
      return;
    }
    el.setAttribute(BOUND_ATTR, '1');
    bound.push(el);

    // Initial scroll-into-view uses instant positioning (no smooth behavior
    // before the strip has finished layout — smooth kicks in on user scroll).
    const previousBehavior = el.style.scrollBehavior;
    el.style.scrollBehavior = 'auto';
    scrollActiveIntoView(el);
    el.style.scrollBehavior = previousBehavior;

    updateOverflow(el);

    const onScroll = () => updateOverflow(el);
    el.addEventListener('scroll', onScroll, { passive: true });
    cleanupFns.push(() => el.removeEventListener('scroll', onScroll));

    if (typeof ResizeObserver !== 'undefined') {
      const resizeObserver = new ResizeObserver(() => updateOverflow(el));
      resizeObserver.observe(el);
      cleanupFns.push(() => resizeObserver.disconnect());
    } else {
      const onResize = () => updateOverflow(el);
      window.addEventListener('resize', onResize, { passive: true });
      cleanupFns.push(() => window.removeEventListener('resize', onResize));
    }
  });

  const destroy = () => {
    cleanupFns.forEach((fn) => {
      try {
        fn();
      } catch {
        /* ignore */
      }
    });
    cleanupFns.length = 0;
    bound.forEach((el) => {
      el.removeAttribute(BOUND_ATTR);
      el.classList.remove('has-overflow', 'at-start', 'at-end');
    });
    bound.length = 0;
  };

  return { destroy };
}
