// searchAutocomplete.js — universal search dropdown for the scan/search input. import { searchLocal } from './assetBrowser.js'; let _onLocalSelect = null; let _onRemoteSearch = null; let _input = null; let _dropdown = null; let _items = []; // { type:'asset'|'syncro', asset?, serial?, contact?, customerName?, query? } let _activeIdx = -1; let _inputTimer = null; let _blurTimer = null; // ── Init ────────────────────────────────────────────────────────────────────── export function initSearchAutocomplete({ onLocalSelect, onRemoteSearch }) { _onLocalSelect = onLocalSelect; _onRemoteSearch = onRemoteSearch; _input = document.getElementById('scan-input'); if (!_input) return; // Append dropdown inside scan-input-wrap so it's positioned relative to it _dropdown = document.createElement('div'); _dropdown.id = 'search-autocomplete'; _dropdown.className = 'search-autocomplete'; _dropdown.hidden = true; _input.closest('.scan-input-wrap').appendChild(_dropdown); _input.addEventListener('input', _onInput); _input.addEventListener('blur', () => { _blurTimer = setTimeout(_close, 150); }); _input.addEventListener('focus', () => { clearTimeout(_blurTimer); if (_input.value.trim().length >= 2) _onInput(); }); // Prevent blur when clicking a dropdown item _dropdown.addEventListener('mousedown', e => e.preventDefault()); _dropdown.addEventListener('click', e => { const item = e.target.closest('.ac-item'); if (item) _selectIdx(Number(item.dataset.idx)); }); } // ── Key handler — called by scanner's key interceptor ───────────────────────── export function handleAutocompleteKey(e) { if (_dropdown.hidden) return false; if (e.key === 'ArrowDown') { e.preventDefault(); _setActive(Math.min(_activeIdx + 1, _items.length - 1)); return true; } if (e.key === 'ArrowUp') { e.preventDefault(); _setActive(Math.max(_activeIdx - 1, 0)); return true; } if (e.key === 'Enter') { if (_activeIdx >= 0) { e.preventDefault(); _selectIdx(_activeIdx); return true; } _close(); // close but let scanner handle Enter return false; } if (e.key === 'Escape') { _close(); return true; // prevent scanner's clearInput } return false; } // ── Internal ────────────────────────────────────────────────────────────────── function _onInput() { clearTimeout(_inputTimer); _inputTimer = setTimeout(() => { const query = _input.value.trim(); if (query.length < 2) { _close(); return; } _renderDropdown(query); }, 200); } function _renderDropdown(query) { const localResults = searchLocal(query); _items = [ ...localResults.map(r => ({ type: 'asset', ...r })), { type: 'syncro', query }, ]; _activeIdx = -1; _dropdown.innerHTML = _items.map((item, i) => { if (item.type === 'syncro') { return `