import { apiFetch, basePath, debounce, escapeHtml } from 'ect/site';

const form = document.querySelector('.brewer-search-form');
const root = document.querySelector('[data-brewer-search-combobox]');
const input = document.getElementById('brewer-search-input');
const options = document.getElementById('brewer-search-options');
let controller = null;

function profileImageUrl(value) {
  const path = String(value || '').trim();
  if (!path) return '';
  if (/^https?:\/\//i.test(path)) return path;
  return `${basePath}/${path.replace(/^\/+/, '')}`;
}
function closeOptions() {
  if (!options || !input || !root) return;
  options.hidden = true;
  input.setAttribute('aria-expanded', 'false');
  root.classList.remove('is-open');
}
function renderOptions(items) {
  if (!options || !input || !root) return;
  options.innerHTML = items.map((item, index) => {
    const nickname = String(item.nickname || '').trim();
    const label = nickname && nickname !== item.username ? `${item.username} (${nickname})` : item.username;
    const image = profileImageUrl(item.profileImage);
    const initial = String(nickname || item.username || '?').slice(0, 1).toUpperCase();
    const avatar = image ? `<img src="${escapeHtml(image)}" alt="">` : escapeHtml(initial);
    const meta = `${Number(item.publicDecks || 0).toLocaleString()} public deck${Number(item.publicDecks || 0) === 1 ? '' : 's'}`;
    return `<button class="search-combobox-option brewer-search-option" type="button" role="option" data-brewer-value="${escapeHtml(item.username)}" aria-selected="${index === 0}"><span class="brewer-search-option-avatar" aria-hidden="true">${avatar}</span><span class="brewer-search-option-copy"><strong>${escapeHtml(label)}</strong><small>${escapeHtml(meta)}</small></span></button>`;
  }).join('');
  const open = items.length > 0;
  options.hidden = !open;
  input.setAttribute('aria-expanded', String(open));
  root.classList.toggle('is-open', open);
}
async function searchBrewers() {
  const query = input?.value.trim() || '';
  if (query.length < 2) { closeOptions(); return; }
  controller?.abort();
  controller = new AbortController();
  try {
    const params = new URLSearchParams({ q: query, pageSize: '12' });
    const payload = await apiFetch(`/api/v1/users/search?${params}`, { signal: controller.signal });
    renderOptions(payload.data.items || []);
  } catch (error) {
    if (error?.name !== 'AbortError') closeOptions();
  }
}
function choose(option, submit = true) {
  if (!option || !input) return;
  input.value = option.dataset.brewerValue || '';
  closeOptions();
  if (submit) form?.requestSubmit();
}
function moveSelection(delta) {
  const items = [...(options?.querySelectorAll('[role="option"]') || [])];
  if (!items.length) return;
  const current = items.findIndex((item) => item.getAttribute('aria-selected') === 'true');
  const next = (current + delta + items.length) % items.length;
  items.forEach((item, index) => item.setAttribute('aria-selected', String(index === next)));
  items[next].scrollIntoView({ block: 'nearest' });
}

const scheduleSearch = debounce(searchBrewers, 220);
input?.addEventListener('input', scheduleSearch);
input?.addEventListener('focus', () => { if ((input.value.trim() || '').length >= 2) searchBrewers(); });
input?.addEventListener('keydown', (event) => {
  if (event.key === 'ArrowDown') { event.preventDefault(); moveSelection(1); }
  else if (event.key === 'ArrowUp') { event.preventDefault(); moveSelection(-1); }
  else if (event.key === 'Escape') closeOptions();
  else if (event.key === 'Enter' && !options?.hidden) {
    const active = options.querySelector('[aria-selected="true"]') || options.querySelector('[role="option"]');
    if (active) { event.preventDefault(); choose(active); }
  }
});
options?.addEventListener('mousedown', (event) => {
  const option = event.target.closest('[data-brewer-value]');
  if (!option) return;
  event.preventDefault();
  choose(option);
});
document.addEventListener('click', (event) => { if (!event.target.closest('[data-brewer-search-combobox]')) closeOptions(); });
