import { defineTrait } from '../define.js';

const BUFFER_TIMEOUT = 500;

export const typeahead = defineTrait({
  name: 'typeahead',
  category: 'keyboard-navigation',
  description: 'Incremental search within a collection',
  attributes: ['data-typeahead-match'],
  events: ['typeahead-match'],
  config: [],
  setup({ host }) {
    let buffer = '';
    let timerId = null;
    let lastMatch = null;

    function clearBuffer() {
      buffer = '';
      timerId = null;
    }

    function clearMatchAttribute() {
      if (lastMatch) {
        lastMatch.removeAttribute('data-typeahead-match');
        lastMatch = null;
      }
    }

    function onKeyDown(e) {
      // Ignore modifier keys, special keys
      if (e.key.length !== 1 || e.ctrlKey || e.metaKey || e.altKey) return;

      buffer += e.key.toLowerCase();

      if (timerId !== null) clearTimeout(timerId);
      timerId = setTimeout(clearBuffer, BUFFER_TIMEOUT);

      // Search children by textContent prefix match
      const children = [...host.children];
      const match = children.find((child) => {
        const text = (child.textContent || '').trim().toLowerCase();
        return text.startsWith(buffer);
      });

      clearMatchAttribute();

      if (match) {
        lastMatch = match;
        match.setAttribute('data-typeahead-match', '');
        host.dispatchEvent(new CustomEvent('typeahead-match', {
          bubbles: true,
          detail: { element: match, query: buffer },
        }));
      }
    }

    host.addEventListener('keydown', onKeyDown);

    return () => {
      host.removeEventListener('keydown', onKeyDown);
      if (timerId !== null) clearTimeout(timerId);
      clearMatchAttribute();
    };
  },
});
