import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useRef, useState, useEffect } from "react";
import { Button, Divider, ErrorBox, SidePanel, Spinner, useIntersectionObserver, useToast, FilterProvider, FilterBtn, FilterBar, FilterClear } from '@vertesia/ui/core';
import { useNavigate } from "@vertesia/ui/router";
import { useUserSession } from '@vertesia/ui/session';
import { Download, RefreshCw, ExternalLink } from 'lucide-react';
import { useDocumentFilterGroups, useDocumentFilterHandler } from "../../facets/DocumentsFacetsNav";
import { VectorSearchWidget } from './components/VectorSearchWidget';
import { ContentDispositionButton } from './components/ContentDispositionButton';
import { DocumentTable } from './DocumentTable';
import { useDocumentSearch, useWatchDocumentSearchFacets, useWatchDocumentSearchResult } from './search/DocumentSearchContext';
import { useDocumentUploadHandler } from './upload/useUploadHandler';
import { ContentOverview } from './components/ContentOverview';
import { useDownloadDocument } from './components/useDownloadObject';
const defaultLayout = [
    { name: "ID", field: "id", type: "objectId?slice=-7" },
    { name: "Name", field: ".", type: "objectName" },
    { name: "Type", field: "type.name", type: "string" },
    { name: "Status", field: "status", type: "string" },
    { name: "Updated At", field: "updated_at", type: "date" },
];
function getTableLayout(registry, type) {
    const layout = type ? registry.getTypeLayout(type) : defaultLayout;
    console.log('[DEBUG] getTableLayout called with type:', type);
    console.log('[DEBUG] Layout from registry:', layout);
    console.log('[DEBUG] Using defaultLayout?', layout === defaultLayout);
    const result = layout ?? defaultLayout;
    console.log('[DEBUG] Final layout:', result);
    console.log('[DEBUG] Has Status field?', result.some(col => col.field === 'status'));
    return result;
}
export function DocumentSearchResultsWithDropZone({ onUploadDone = async () => { }, layout }) {
    const search = useDocumentSearch();
    const toast = useToast();
    // Create a wrapper around the onUploadDone callback that also refreshes the search
    const handleUploadDone = async (objectIds) => {
        // First, call the original callback
        await onUploadDone(objectIds);
        // Use a timeout to let the backend catch up, then refresh the search results
        setTimeout(() => {
            console.log('Delayed refresh after upload to ensure backend consistency');
            search.search().then(() => {
                // Notify the user that the list has been refreshed
                toast({
                    title: "Document list refreshed",
                    description: "The document list has been updated with your uploaded files.",
                    status: "info",
                    duration: 3000,
                });
            }).catch(err => {
                console.error('Failed to refresh search results:', err);
            });
        }, 1000); // 1-second delay for backend processing
    };
    // Use the enhanced standard upload handler with smart processing
    const uploadHandler = useDocumentUploadHandler(handleUploadDone);
    // Wrap the uploadHandler to ensure the collectionId is passed
    const wrappedUploadHandler = (files, type) => {
        // Get the collection ID from the search context
        const collectionId = search.collectionId;
        return uploadHandler(files, type, collectionId);
    };
    return _jsx(DocumentSearchResults, { layout: layout, onUpload: wrappedUploadHandler });
}
export function DocumentSearchResults({ layout, onUpload, allowFilter = true, allowSearch = true }) {
    // Get the search context to access collectionId
    const searchContext = useDocumentSearch();
    const [isReady, setIsReady] = useState(false);
    const [selectedObject, setSelectedObject] = useState(null);
    const { typeRegistry } = useUserSession();
    const { search, isLoading, error, objects, hasMore } = useWatchDocumentSearchResult();
    const [actualLayout, setActualLayout] = useState(typeRegistry ? layout || getTableLayout(typeRegistry, search.query.type) : defaultLayout);
    console.log('[DEBUG] DocumentSearchResults - actualLayout:', actualLayout);
    console.log('[DEBUG] DocumentSearchResults - actualLayout has Status?', actualLayout.some(col => col.field === 'status'));
    //TODO _setRefreshTrigger state not used
    const [refreshTrigger, _setRefreshTrigger] = useState(0);
    const [loaded, setLoaded] = useState(0);
    const [isGridView, setIsGridView] = useState(localStorage.getItem(ContentDispositionButton.LAST_DISPLAYED_VIEW) === "grid");
    const [filters, setFilters] = useState([]);
    const loadMoreRef = useRef(null);
    // Trigger initial search when component mounts
    useEffect(() => {
        if (!isReady && objects.length === 0) {
            setLoaded(0);
            // Manually set loading state to show spinner during initial load
            search._updateRunningState(true);
            search.search().then(() => {
                setIsReady(true);
            }).catch(err => {
                console.error('Initial search failed:', err);
                search._updateRunningState(false);
            });
        }
    }, []);
    useEffect(() => {
        if (objects.length < loaded) {
            setLoaded(objects.length);
        }
    }, [objects.length, loaded]);
    useIntersectionObserver(loadMoreRef, () => {
        if (isReady && objects.length > 0 && objects.length != loaded) {
            setIsReady(false);
            search.loadMore().finally(() => {
                setLoaded(objects.length);
                setIsReady(true);
            });
        }
    }, { deps: [isReady, objects.length] });
    // Handler for vector search widget
    const handleVectorSearch = (query) => {
        if (query && query.vector) {
            search.query.vector = query.vector;
            search.query.full_text = query.full_text;
            search.query.weights = query.weights;
            search.query.score_aggregation = query.score_aggregation;
            search.query.dynamic_scaling = query.dynamic_scaling;
            if (!actualLayout.find((c) => c.name === "Search Score")) {
                const layout = [
                    ...actualLayout,
                    {
                        name: "Search Score",
                        field: "score",
                        render: (item) => item.score?.toFixed(4) || "0.0000"
                    },
                ];
                setActualLayout(layout);
            }
            search.search().then(() => setIsReady(true));
        }
        else if (query && query.full_text) {
            search.query.full_text = query.full_text;
            search.search().then(() => setIsReady(true));
        }
        else if (query === undefined) {
            // Only clear search if this is a user-initiated clear (not initialization)
            // The VectorSearchWidget calls onChange(undefined) during initialization
            if (isReady) {
                delete search.query.vector;
                delete search.query.full_text;
                search.search().then(() => setIsReady(true));
            }
        }
    };
    const facets = useWatchDocumentSearchFacets();
    const facetSearch = useDocumentSearch();
    const handleRefetch = () => {
        search.search().then(() => setIsReady(true));
    };
    // Use DocumentsFacetsNav hooks for cleaner organization
    const filterGroups = useDocumentFilterGroups(facets);
    const handleFilterLogic = useDocumentFilterHandler(facetSearch);
    const handleFilterChange = (value) => {
        const newFilters = typeof value === 'function' ? value(filters) : value;
        setFilters(newFilters);
        handleFilterLogic(newFilters);
    };
    const url = new URL(window.location.href);
    const filtersParam = url.searchParams.get('filters');
    if (filtersParam) {
        try {
            const filterPairs = filtersParam.split(';');
            const validFilterPairs = filterPairs.filter(pair => {
                const [encodedName] = pair.split(':');
                const name = decodeURIComponent(encodedName);
                return name !== 'start' && name !== 'end';
            });
            if (validFilterPairs.length !== filterPairs.length) {
                const newFiltersParam = validFilterPairs.length > 0 ? validFilterPairs.join(';') : '';
                if (newFiltersParam) {
                    url.searchParams.set('filters', newFiltersParam);
                }
                else {
                    url.searchParams.delete('filters');
                }
                window.history.replaceState(window.history.state || {}, '', url.toString());
            }
        }
        catch (error) {
            console.error("Failed to clean start/end filters from URL:", error);
        }
    }
    const navigate = useNavigate();
    const onRowClick = (object) => {
        navigate(`/objects/${object.id}`);
    };
    const previewObject = (objectId) => {
        const obj = objects.find(o => o.id === objectId) || null;
        setSelectedObject(obj);
    };
    return (_jsxs("div", { className: "flex flex-col gap-y-2", children: [_jsx(OverviewDrawer, { object: selectedObject, onClose: () => setSelectedObject(null) }), error && _jsx(ErrorBox, { title: "Error", children: error.message }), _jsx(Toolsbar, { isLoading: isLoading, refreshTrigger: refreshTrigger, allowFilter: allowFilter, allowSearch: allowSearch, filterGroups: filterGroups, filters: filters, handleFilterChange: handleFilterChange, handleVectorSearch: handleVectorSearch, handleRefetch: handleRefetch, setIsGridView: setIsGridView }), _jsx(DocumentTable, { objects: objects, isLoading: !objects.length && isLoading, layout: actualLayout, onRowClick: onRowClick, previewObject: previewObject, selectedObject: selectedObject, onUpload: onUpload, isGridView: isGridView, collectionId: searchContext.collectionId }), hasMore ? (_jsx("div", { ref: loadMoreRef, className: "w-full flex justify-center", children: _jsx(Spinner, { size: 'xl' }) })) : (_jsx("div", { className: "text-muted text-center text-sm py-1", children: `All ${objects.length} objects loaded.` }))] }));
}
function Toolsbar(props) {
    const { isLoading, refreshTrigger, allowFilter, allowSearch, filterGroups, filters, handleFilterChange, handleVectorSearch, handleRefetch, setIsGridView } = props;
    return (_jsxs("div", { className: "sticky top-0 z-10 bg-background py-2", children: [allowFilter && (_jsxs(FilterProvider, { filterGroups: filterGroups, filters: filters, setFilters: handleFilterChange, children: [_jsxs("div", { className: "flex flex-row gap-4 items-center justify-between w-full", children: [_jsxs("div", { className: "flex gap-2 items-center w-2/3", children: [allowSearch && _jsx(VectorSearchWidget, { onChange: handleVectorSearch, isLoading: isLoading, refresh: refreshTrigger, className: "w-full" }), _jsx(FilterBtn, {})] }), _jsxs("div", { className: "flex gap-1 items-center", children: [_jsx(Button, { variant: "outline", onClick: handleRefetch, alt: "Refresh", children: _jsx(RefreshCw, { size: 16 }) }), _jsx(ContentDispositionButton, { onUpdate: setIsGridView })] })] }), _jsxs("div", { className: "flex gap-2 items-center pt-2", children: [_jsx(FilterBar, {}), _jsx(FilterClear, {})] })] })), !allowFilter && (_jsxs("div", { className: "flex flex-row gap-4 items-center justify-between w-full", children: [_jsx("div", { className: "flex gap-2 items-center w-2/3", children: allowSearch && _jsx(VectorSearchWidget, { onChange: handleVectorSearch, isLoading: isLoading, refresh: refreshTrigger }) }), _jsxs("div", { className: "flex gap-1 items-center", children: [_jsx(Button, { variant: "outline", onClick: handleRefetch, alt: "Refresh", children: _jsx(RefreshCw, { size: 16 }) }), _jsx(ContentDispositionButton, { onUpdate: setIsGridView })] })] }))] }));
}
function OverviewDrawer({ object, onClose }) {
    const { store } = useUserSession();
    const toast = useToast();
    const navigate = useNavigate();
    const onDownload = useDownloadDocument(store, toast, object?.content?.source, object?.name || object?.content?.name);
    return object ? (_jsxs(SidePanel, { title: object.properties?.title || object.name, isOpen: true, onClose: onClose, children: [_jsxs("div", { className: "flex items-center gap-x-2", children: [_jsx(Button, { variant: "ghost", size: "sm", title: "Open Object", onClick: () => navigate(`/objects/${object.id}`), children: _jsx(ExternalLink, { className: "size-4" }) }), object.content?.source && (_jsx(Button, { variant: "ghost", size: "sm", title: "Download", onClick: onDownload, children: _jsx(Download, { className: "size-4" }) }))] }), _jsx(Divider, { className: "my-2" }), _jsx("div", { className: "pt-2", children: _jsx(ContentOverview, { object: object, loadText: true }, object.id) })] })) : null;
}
//# sourceMappingURL=DocumentSearchResults.js.map