// search-modal.jsx — inline-поиск в строке topbar

const SEARCH_HISTORY_KEY = 'nordant_search_history';

const SEARCH_STATUS_OPTIONS = [
  { id: '', label: 'Любой статус' },
  { id: 'published', label: 'Опубликовано' },
  { id: 'draft', label: 'Черновик' },
  { id: 'review', label: 'На ревью' },
];

const STATUS_LABELS = {
  published: 'Опубликовано',
  draft: 'Черновик',
  review: 'На ревью',
};

const FilterPill = ({ label, selectedLabel, isActive, isOpen, onToggle }) => (
  <button
    type="button"
    className={`search-filter-btn${isActive ? ' is-active' : ''}${isOpen ? ' is-open' : ''}`}
    onMouseDown={(e) => e.preventDefault()}
    onClick={(e) => {
      e.stopPropagation();
      onToggle();
    }}
  >
    <span className="search-filter-label">{selectedLabel || label}</span>
    <Icon name="chevronDown" size={12} />
  </button>
);

const FilterOptionLabel = ({ opt }) => {
  if (opt.tag) {
    return (
      <span className="search-filter-option-label">
        <span className={`tag ${opt.tag.color}`}>
          <span className="tag-dot" />
          {opt.label}
        </span>
      </span>
    );
  }
  return <span className="search-filter-option-label">{opt.label || opt.name || opt.id}</span>;
};

const FilterPanel = ({ options, value, onChange, title }) => (
  <div className="search-filter-panel">
    {title && <div className="search-filter-panel-title">{title}</div>}
    {options.map((opt) => {
      const selected = value === opt.id;
      return (
        <button
          key={opt.id || '__all'}
          type="button"
          className={`search-filter-option${selected ? ' is-selected' : ''}`}
          onMouseDown={(e) => {
            e.preventDefault();
            e.stopPropagation();
          }}
          onClick={(e) => {
            e.stopPropagation();
            onChange(opt.id);
          }}
        >
          <FilterOptionLabel opt={opt} />
          {selected && (
            <span className="search-filter-option-check" aria-hidden="true">
              <Icon name="check" size={14} />
            </span>
          )}
        </button>
      );
    })}
  </div>
);

const TopbarSearch = ({ onOpenArticle }) => {
  const [query, setQuery] = React.useState('');
  const [section, setSection] = React.useState('');
  const [tag, setTag] = React.useState('');
  const [status, setStatus] = React.useState('');
  const [results, setResults] = React.useState([]);
  const [suggestions, setSuggestions] = React.useState([]);
  const [loading, setLoading] = React.useState(false);
  const [openFilter, setOpenFilter] = React.useState(null);
  const rootRef = React.useRef(null);
  const inputRef = React.useRef(null);

  const sectionOptions = React.useMemo(() => [
    { id: '', label: 'Все разделы' },
    ...(window.SECTIONS || [])
      .filter((s) => s.id !== 'all')
      .map((s) => ({
        id: s.id,
        label: window.getSectionLabel?.(s.id) || s.name,
      })),
  ], []);

  const tagOptions = React.useMemo(() => [
    { id: '', label: 'Все теги' },
    ...(window.TAGS || []).map((t) => ({
      id: t.id,
      label: t.name,
      tag: t,
    })),
  ], []);

  const selectedSection = sectionOptions.find((o) => o.id === section);
  const selectedTag = tagOptions.find((o) => o.id === tag);
  const selectedStatus = SEARCH_STATUS_OPTIONS.find((o) => o.id === status);

  const toggleFilter = (name) => {
    setOpenFilter((prev) => (prev === name ? null : name));
  };

  const hasQuery = Boolean(query.trim());
  const hasFilters = Boolean(section || tag || status);
  const hasActiveSearch = hasQuery || hasFilters;

  const saveHistory = (q) => {
    if (!q.trim()) return;
    try {
      const hist = JSON.parse(localStorage.getItem(SEARCH_HISTORY_KEY) || '[]');
      const next = [q.trim(), ...hist.filter((h) => h !== q.trim())].slice(0, 8);
      localStorage.setItem(SEARCH_HISTORY_KEY, JSON.stringify(next));
    } catch { /* ignore */ }
  };

  const runSearch = React.useCallback(async () => {
    if (!hasActiveSearch) {
      setResults([]);
      setLoading(false);
      return;
    }
    setLoading(true);
    try {
      const data = await window.KB.searchArticles({
        q: query.trim() || undefined,
        section: section || undefined,
        tag: tag || undefined,
        status: status || undefined,
      });
      setResults(data.results || []);
      if (query.trim()) saveHistory(query.trim());
    } catch {
      setResults([]);
    } finally {
      setLoading(false);
    }
  }, [query, section, tag, status, hasActiveSearch]);

  const [open, setOpen] = React.useState(false);

  React.useEffect(() => {
    if (!open) return undefined;
    const t = setTimeout(runSearch, 260);
    return () => clearTimeout(t);
  }, [open, runSearch]);

  React.useEffect(() => {
    if (!open || query.trim().length < 2) {
      setSuggestions([]);
      return undefined;
    }
    let cancelled = false;
    window.KB.searchSuggest(query).then((s) => {
      if (!cancelled) setSuggestions(s);
    }).catch(() => {});
    return () => { cancelled = true; };
  }, [query, open]);

  const applyFilter = (name, value) => {
    if (name === 'section') setSection(value);
    else if (name === 'tag') setTag(value);
    else if (name === 'status') setStatus(value);
    setOpenFilter(null);
    setOpen(true);
    requestAnimationFrame(() => inputRef.current?.focus());
  };

  React.useEffect(() => {
    const onDocClick = (e) => {
      const target = e.target;
      if (!(target instanceof Node) || !target.isConnected) return;
      if (!rootRef.current?.contains(target)) {
        setOpen(false);
        setOpenFilter(null);
      }
    };
    document.addEventListener('click', onDocClick);
    return () => document.removeEventListener('click', onDocClick);
  }, []);

  React.useEffect(() => {
    const onKey = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {
        e.preventDefault();
        inputRef.current?.focus();
        setOpen(true);
      }
      if (e.key === 'Escape' && open) {
        setOpen(false);
        inputRef.current?.blur();
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open]);

  const history = (() => {
    try {
      return JSON.parse(localStorage.getItem(SEARCH_HISTORY_KEY) || '[]');
    } catch {
      return [];
    }
  })();

  const clearFilters = () => {
    setSection('');
    setTag('');
    setStatus('');
    setOpenFilter(null);
  };

  const openResult = (article) => {
    onOpenArticle?.(article);
    setOpen(false);
    setQuery('');
    setResults([]);
    clearFilters();
  };

  const showDropdown = open;

  const openFilterConfig = openFilter === 'section'
    ? { title: 'Раздел', options: sectionOptions, value: section, onChange: (v) => applyFilter('section', v) }
    : openFilter === 'tag'
      ? { title: 'Тег', options: tagOptions, value: tag, onChange: (v) => applyFilter('tag', v) }
      : openFilter === 'status'
        ? { title: 'Статус', options: SEARCH_STATUS_OPTIONS, value: status, onChange: (v) => applyFilter('status', v) }
        : null;

  return (
    <div className={`topbar-search${open ? ' is-open' : ''}`} ref={rootRef}>
      <Icon name="search" className="topbar-search-icon" />
      <input
        ref={inputRef}
        type="search"
        className="topbar-search-input"
        placeholder="Поиск по базе знаний…"
        value={query}
        onChange={(e) => {
          setQuery(e.target.value);
          setOpen(true);
        }}
        onFocus={() => setOpen(true)}
        autoComplete="off"
        spellCheck={false}
      />
      {(hasQuery || hasFilters) && (
        <button
          type="button"
          className="topbar-search-clear"
          aria-label="Очистить"
          onClick={() => {
            setQuery('');
            clearFilters();
            setResults([]);
            inputRef.current?.focus();
          }}
        >
          ×
        </button>
      )}
      <span className="topbar-kbd">⌘ K</span>

      {showDropdown && (
        <div className="topbar-search-dropdown" onMouseDown={(e) => e.stopPropagation()}>
          <div className="topbar-search-filters">
            <FilterPill
              label="Раздел"
              selectedLabel={selectedSection?.id ? selectedSection.label : null}
              isActive={Boolean(section)}
              isOpen={openFilter === 'section'}
              onToggle={() => toggleFilter('section')}
            />
            <FilterPill
              label="Тег"
              selectedLabel={selectedTag?.id ? selectedTag.label : null}
              isActive={Boolean(tag)}
              isOpen={openFilter === 'tag'}
              onToggle={() => toggleFilter('tag')}
            />
            <FilterPill
              label="Статус"
              selectedLabel={selectedStatus?.id ? selectedStatus.label : null}
              isActive={Boolean(status)}
              isOpen={openFilter === 'status'}
              onToggle={() => toggleFilter('status')}
            />
            {hasFilters && (
              <button
                type="button"
                className="search-filter-reset"
                onMouseDown={(e) => e.stopPropagation()}
                onClick={(e) => {
                  e.stopPropagation();
                  clearFilters();
                  inputRef.current?.focus();
                }}
              >
                Сбросить
              </button>
            )}
          </div>

          <div className={`topbar-search-body${openFilterConfig ? ' topbar-search-body--filter' : ''}`}>
            {openFilterConfig ? (
              <FilterPanel {...openFilterConfig} />
            ) : !hasActiveSearch && history.length > 0 ? (
              <div className="topbar-search-section">
                <div className="topbar-search-section-title">Недавние запросы</div>
                <div className="search-history-list">
                  {history.map((h) => (
                    <button key={h} type="button" className="search-history-item" onClick={() => setQuery(h)}>
                      <Icon name="clock" size={13} />
                      {h}
                    </button>
                  ))}
                </div>
              </div>
            ) : !hasActiveSearch ? (
              <div className="topbar-search-empty topbar-search-hint">
                <Icon name="search" size={20} />
                <span>Введите запрос или выберите фильтр</span>
              </div>
            ) : null}

            {!openFilterConfig && hasQuery && query.trim().length >= 2 && suggestions.length > 0 && results.length === 0 && !loading && (
              <div className="topbar-search-section">
                <div className="topbar-search-section-title">Подсказки</div>
                {suggestions.map((s) => (
                  <button key={s} type="button" className="search-suggest-item" onClick={() => setQuery(s)}>
                    <Icon name="search" size={13} />
                    {s}
                  </button>
                ))}
              </div>
            )}

            {!openFilterConfig && loading && (
              <div className="topbar-search-empty">
                <span className="search-spinner" />
                Поиск…
              </div>
            )}

            {!openFilterConfig && !loading && hasActiveSearch && results.length === 0 && (
              <div className="topbar-search-empty">
                <Icon name="search" size={20} />
                <span>Ничего не найдено</span>
              </div>
            )}

            {!openFilterConfig && !loading && results.length > 0 && (
              <>
                <div className="topbar-search-results-head">
                  {results.length} {results.length === 1 ? 'результат' : results.length < 5 ? 'результата' : 'результатов'}
                </div>
                <ul className="search-results-list">
                  {results.map((a) => {
                    const sectionName = window.findSection(a.section)?.name || '—';
                    const tags = (a.tags || []).map((t) => window.findTag(t)).filter(Boolean);
                    return (
                      <li key={a.id}>
                        <button type="button" className="search-result-item" onClick={() => openResult(a)}>
                          <span className="search-result-icon">
                            <Icon name="file" size={16} />
                          </span>
                          <span className="search-result-body">
                            <span
                              className="search-result-title"
                              dangerouslySetInnerHTML={{ __html: a.highlightTitle || a.title }}
                            />
                            {a.highlightDesc && (
                              <span
                                className="search-result-snippet"
                                dangerouslySetInnerHTML={{ __html: a.highlightDesc }}
                              />
                            )}
                            <span className="search-result-meta">
                              <span className="search-result-section">{sectionName}</span>
                              <span className="search-result-status">
                                {STATUS_LABELS[a.status] || a.status}
                              </span>
                              {tags.slice(0, 2).map((t) => (
                                <span key={t.id} className={`tag ${t.color}`}>{t.name}</span>
                              ))}
                            </span>
                          </span>
                        </button>
                      </li>
                    );
                  })}
                </ul>
              </>
            )}
          </div>
        </div>
      )}
    </div>
  );
};

window.TopbarSearch = TopbarSearch;
