import React, { useEffect, useRef } from 'react';
import { Hit } from './Hit';
function getTypeLevel(type) {
    if (!type)
        return 1;
    const match = type.match(/^lvl(\d+)$/);
    return match ? parseInt(match[1], 10) : 1;
}
function isChildType(type) {
    return getTypeLevel(type) >= 2;
}
/** Build a stable grouping key from all hierarchy levels (lvl0 through lvl5). */
function getHierarchyKey(hit) {
    const h = hit.hierarchy ?? {};
    const parts = [
        h.lvl0 ?? '',
        h.lvl1 ?? '',
        h.lvl2 ?? '',
        h.lvl3 ?? '',
        h.lvl4 ?? '',
        h.lvl5 ?? '',
    ];
    return parts.join('\0');
}
/** Build a display breadcrumb from hierarchy, skipping consecutive duplicates (e.g. lvl0 === lvl1). */
function getHierarchyBreadcrumb(hit) {
    const h = hit.hierarchy ?? {};
    const parts = [h.lvl0, h.lvl1, h.lvl2, h.lvl3, h.lvl4, h.lvl5].filter((v) => typeof v === 'string' && v.length > 0);
    const deduped = [];
    for (const p of parts) {
        if (deduped[deduped.length - 1] !== p)
            deduped.push(p);
    }
    return deduped.join(' › ');
}
function groupHitsByHierarchy(hits) {
    const hitToIndex = new Map();
    hits.forEach((h, i) => hitToIndex.set(h, i));
    const groups = new Map();
    for (const hit of hits) {
        const key = getHierarchyKey(hit);
        if (!groups.has(key))
            groups.set(key, []);
        groups.get(key).push(hit);
    }
    const entries = Array.from(groups.entries());
    entries.sort(([, aHits], [, bHits]) => {
        const aMin = Math.min(...aHits.map(h => hitToIndex.get(h) ?? 0));
        const bMin = Math.min(...bHits.map(h => hitToIndex.get(h) ?? 0));
        return aMin - bMin;
    });
    const result = [];
    for (const [, groupHits] of entries) {
        const sortedHits = [...groupHits].sort((a, b) => {
            const aType = a.type;
            const bType = b.type;
            return getTypeLevel(aType) - getTypeLevel(bType);
        });
        const markedHits = sortedHits.map((hit, index) => {
            const suggestion = hit;
            const isChild = isChildType(suggestion.type);
            const nextHit = sortedHits[index + 1];
            const isLastChild = isChild && (!nextHit || !isChildType(nextHit.type));
            return { ...hit, isChild, isLastChild };
        });
        const category = getHierarchyBreadcrumb(groupHits[0]);
        result.push({ category: category || null, hits: markedHits });
    }
    return result;
}
function getGlobalIndexMulti(groups, groupIndex, hitIndex) {
    let index = 0;
    for (let i = 0; i < groupIndex; i++)
        index += groups[i].hits.length;
    return index + hitIndex;
}
function getHitKey(hit, index) {
    if ('objectID' in hit)
        return hit.objectID;
    return `suggestion-${hit.url}-${index}`;
}
export function Results({ hits, groupedHits, selectedIndex, onSelect, onHover, scrollSelectionIntoViewRef, query, isLoading, error, translations = {}, sources: _sources = [], }) {
    void _sources;
    const listRef = useRef(null);
    useEffect(() => {
        if (!listRef.current || hits.length === 0)
            return;
        // Only scroll when selection changed via keyboard (avoids scroll-to-selected on hover)
        if (scrollSelectionIntoViewRef && !scrollSelectionIntoViewRef.current)
            return;
        // listRef's direct children are groups (li.seekora-docsearch-results-group), not hits.
        // Find the actual hit element at flat selectedIndex.
        const groupEls = listRef.current.querySelectorAll('.seekora-docsearch-results-group');
        let idx = 0;
        for (const groupEl of groupEls) {
            const itemList = groupEl.querySelector('.seekora-docsearch-results-group-items');
            if (!itemList)
                continue;
            const items = itemList.children;
            for (let i = 0; i < items.length; i++) {
                if (idx === selectedIndex) {
                    items[i].scrollIntoView({ block: 'nearest' });
                    if (scrollSelectionIntoViewRef)
                        scrollSelectionIntoViewRef.current = false;
                    return;
                }
                idx++;
            }
        }
        if (scrollSelectionIntoViewRef)
            scrollSelectionIntoViewRef.current = false;
    }, [selectedIndex, hits.length, scrollSelectionIntoViewRef]);
    if (!query) {
        return (React.createElement("div", { className: "seekora-docsearch-empty" },
            React.createElement("p", { className: "seekora-docsearch-empty-text" }, translations.searchPlaceholder || 'Type to start searching...')));
    }
    if (isLoading && hits.length === 0) {
        return React.createElement("div", { className: "seekora-docsearch-empty" });
    }
    // When loading with previous hits, fall through and show them (no loading screen)
    if (error) {
        return (React.createElement("div", { className: "seekora-docsearch-error" },
            React.createElement("p", { className: "seekora-docsearch-error-text" }, translations.errorText || error)));
    }
    if (hits.length === 0 && query) {
        return (React.createElement("div", { className: "seekora-docsearch-no-results" },
            React.createElement("p", { className: "seekora-docsearch-no-results-text" }, translations.noResultsText || `No results found for "${query}"`)));
    }
    const displayGroups = groupedHits && groupedHits.length > 0
        ? groupedHits.map(g => ({ category: g.source.name, sourceId: g.source.id, openInNewTab: g.source.openInNewTab, hits: g.items }))
        : groupHitsByHierarchy(hits).map(g => ({ category: g.category, sourceId: 'default', openInNewTab: false, hits: g.hits }));
    return (React.createElement("div", { className: "seekora-docsearch-results" },
        React.createElement("ul", { ref: listRef, id: "seekora-docsearch-results", className: "seekora-docsearch-results-list", role: "listbox" }, displayGroups.map((group, groupIndex) => (React.createElement("li", { key: group.sourceId + '-' + groupIndex, className: "seekora-docsearch-results-group" },
            group.category && React.createElement("div", { className: "seekora-docsearch-results-group-header" }, group.category),
            React.createElement("ul", { className: "seekora-docsearch-results-group-items" }, group.hits.map((hit, hitIndex) => {
                const globalIndex = getGlobalIndexMulti(displayGroups, groupIndex, hitIndex);
                const extHit = hit;
                return (React.createElement("li", { key: getHitKey(hit, hitIndex) },
                    React.createElement(Hit, { hit: hit, isSelected: globalIndex === selectedIndex, onClick: () => onSelect(hit), onMouseEnter: () => onHover(globalIndex), openInNewTab: group.openInNewTab, isChild: extHit.isChild, isLastChild: extHit.isLastChild, hierarchyType: hit.type })));
            }))))))));
}
