<script>
// Generic "type to search" item picker. Expects markup like:
// <div class="item-autocomplete relative">
//   <input type="text" class="item-search ...">
//   <input type="hidden" class="item-id-input" name="item_id[]">
//   <div class="item-dropdown hidden ..."></div>  <!-- kept in markup for backwards compat, unused for rendering -->
// </div>
// `window.ITEMS_DATA` must be set to an array of {id, name, cost?} before this runs.
//
// IMPORTANT: the dropdown is rendered as a single shared element attached
// directly to <body> and positioned with `position: fixed` from the active
// input's on-screen coordinates. This is deliberate - earlier versions
// rendered the dropdown `position: absolute` inside each row, which got
// silently clipped whenever the row lived inside a horizontally-scrollable
// table wrapper (`overflow-x: auto` forces the browser to clip the Y axis
// too, per the CSS spec, even though only X scrolling was intended). Fixed
// positioning off a shared element sidesteps that entirely.
(function () {
  let activeWrapper = null;
  let activeInput = null;

  const dd = document.createElement('div');
  dd.id = 'sharedItemDropdown';
  dd.style.cssText = 'display:none;position:fixed;z-index:9999;background:#fff;border:1px solid #e2e8f0;border-radius:0.5rem;margin-top:4px;max-height:220px;overflow-y:auto;box-shadow:0 10px 25px rgba(0,0,0,.15);font-size:0.875rem;';
  document.addEventListener('DOMContentLoaded', () => document.body.appendChild(dd));
  if (document.readyState !== 'loading') document.body.appendChild(dd);

  function positionDropdown(input) {
    const rect = input.getBoundingClientRect();
    dd.style.left = rect.left + 'px';
    dd.style.top = rect.bottom + 'px';
    dd.style.width = Math.max(rect.width, 220) + 'px';
  }

  function renderDropdown(wrapper, input, query) {
    const q = query.trim().toLowerCase();
    if (!q) { hideDropdown(); return; }

    const matches = (window.ITEMS_DATA || []).filter(it => it.name.toLowerCase().includes(q)).slice(0, 25);
    if (matches.length === 0) {
      dd.innerHTML = '<div class="px-3 py-2 text-slate-400">No matching items</div>';
    } else {
      dd.innerHTML = matches.map(it =>
        `<div class="item-option px-3 py-2 hover:bg-blue-50 cursor-pointer" data-id="${it.id}" data-name="${it.name.replace(/"/g,'&quot;')}" data-cost="${it.cost !== undefined && it.cost !== null ? it.cost : ''}">${it.name}</div>`
      ).join('');
    }
    activeWrapper = wrapper;
    activeInput = input;
    positionDropdown(input);
    dd.style.display = 'block';
  }

  function hideDropdown() {
    dd.style.display = 'none';
    activeWrapper = null;
    activeInput = null;
  }

  document.addEventListener('input', function (e) {
    if (!e.target.matches('.item-search')) return;
    const wrapper = e.target.closest('.item-autocomplete');
    wrapper.querySelector('.item-id-input').value = ''; // clear selection until they pick again
    renderDropdown(wrapper, e.target, e.target.value);
  });

  document.addEventListener('focus', function (e) {
    if (!e.target.matches('.item-search')) return;
    const wrapper = e.target.closest('.item-autocomplete');
    if (e.target.value) renderDropdown(wrapper, e.target, e.target.value);
  }, true);

  // Keep the dropdown aligned with its input while the page/table scrolls or resizes
  window.addEventListener('scroll', function () { if (activeInput && dd.style.display === 'block') positionDropdown(activeInput); }, true);
  window.addEventListener('resize', function () { if (activeInput && dd.style.display === 'block') positionDropdown(activeInput); });

  document.addEventListener('click', function (e) {
    const option = e.target.closest('.item-option');
    if (option && dd.contains(option)) {
      if (activeWrapper) {
        activeWrapper.querySelector('.item-search').value = option.dataset.name;
        activeWrapper.querySelector('.item-id-input').value = option.dataset.id;

        if (option.dataset.cost !== undefined && option.dataset.cost !== '') {
          const row = activeWrapper.closest('tr') || activeWrapper.parentElement;
          const costInput = row ? (row.querySelector('.line-cost') || row.querySelector('.item-cost-input')) : null;
          if (costInput && !costInput.value) {
            costInput.value = option.dataset.cost;
            costInput.dispatchEvent(new Event('input', { bubbles: true }));
          }
        }
      }
      hideDropdown();
      return;
    }
    // clicked outside the dropdown and outside any search box - close it
    if (!e.target.matches('.item-search')) hideDropdown();
  });
})();
</script>
