import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/*
* Copyright (c) 2020-present SMC Treviso s.r.l. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
import React from "react";
import { useTranslation } from "react-i18next";
import { useInfiniteQuery } from "react-query";
import { Virtuoso } from "react-virtuoso";
import styled, { css } from "styled-components";
import { CustomVirtualScrollbar } from "./CustomScrollbar";
import { Logo } from "./Logo";
import { ResultMemo } from "./Result";
import { useOpenK9Client, } from "./client";
import { useRange, } from "./useRange";
import { useRenderers } from "./useRenderers";
function Results({ displayMode, onDetail, searchQuery, sort, setSortResult, isMobile, setDetailMobile, overChangeCard = false, language, setSortAfterKey, sortAfterKey, setTotalResult, numberOfResults, counterIsVisible = false, selectOptions, setIdPreview, memoryResults, viewButton, NoResultsCustom, setSelectedSort, setViewButtonDetail, templateCustom, }) {
    const renderers = useRenderers();
    if (!renderers)
        return null;
    switch (displayMode.type) {
        case "finite":
            return (_jsx(FiniteResults, { setTotalResult: setTotalResult, renderers: renderers, searchQuery: searchQuery, onDetail: onDetail, setDetailMobile: setDetailMobile, sort: sort, setSortResult: setSortResult, isMobile: isMobile, overChangeCard: overChangeCard, language: language, sortAfterKey: sortAfterKey, numberOfResults: numberOfResults, counterIsVisible: counterIsVisible, setIdPreview: setIdPreview, selectOptions: selectOptions, memoryResults: memoryResults, viewButton: viewButton, setViewButtonDetail: setViewButtonDetail }));
        case "infinite":
            return (_jsx(InfiniteResults, { setTotalResult: setTotalResult, renderers: renderers, searchQuery: searchQuery, onDetail: onDetail, setDetailMobile: setDetailMobile, sort: sort, setSortResult: setSortResult, isMobile: isMobile, overChangeCard: overChangeCard, language: language, setSortAfterKey: setSortAfterKey, sortAfterKey: sortAfterKey, numberOfResults: numberOfResults, setIdPreview: setIdPreview, memoryResults: memoryResults, viewButton: viewButton, setViewButtonDetail: setViewButtonDetail, noResultsCustom: NoResultsCustom, setSelectedSort: setSelectedSort, templateCustom: templateCustom }));
        case "virtual":
            return (_jsx(VirtualResults, { setTotalResult: setTotalResult, renderers: renderers, searchQuery: searchQuery, onDetail: onDetail, setDetailMobile: setDetailMobile, sort: sort, setSortResult: setSortResult, isMobile: isMobile, overChangeCard: overChangeCard, language: language, sortAfterKey: sortAfterKey, numberOfResults: numberOfResults, setIdPreview: setIdPreview, memoryResults: memoryResults, viewButton: viewButton, setViewButtonDetail: setViewButtonDetail }));
    }
}
export const ResultsMemo = React.memo(Results);
export function FiniteResults({ renderers, searchQuery, onDetail, setDetailMobile, sort, isMobile, overChangeCard = false, language, sortAfterKey, setTotalResult, numberOfResults, setIdPreview, memoryResults, viewButton, setViewButtonDetail, }) {
    const results = useInfiniteResults(searchQuery, sort, language, sortAfterKey, numberOfResults, memoryResults);
    React.useEffect(() => {
        if (results.data && results.data.pages[0].total) {
            setTotalResult(results.data.pages[0].total);
        }
    }, [results.data, setTotalResult]);
    return (_jsx("div", { className: "openk9-finite-result-container", css: css `
        height: 100%;
        overflow-y: auto;
        overflow-x: hidden;
      `, children: results.data?.pages[0].total && results.data.pages[0].total > 0 ? (_jsx("div", { className: "openk9-finite-result", css: css `
            width: 100%;
          `, children: results.data?.pages[0].result.map((result, index) => {
                return (_jsx(ResultMemo, { renderers: renderers, result: result, onDetail: onDetail, setDetailMobile: setDetailMobile, isMobile: isMobile, overChangeCard: overChangeCard, setIdPreview: setIdPreview, viewButton: viewButton, setViewButtonDetail: setViewButtonDetail }, index));
            }) })) : (_jsx(NoResults, {})) }));
}
export function InfiniteResults({ renderers, searchQuery, onDetail, setDetailMobile, sort, isMobile, overChangeCard = false, language, setSortAfterKey, sortAfterKey, setTotalResult, numberOfResults, setIdPreview, memoryResults, noResultsCustom, viewButton, templateCustom, setViewButtonDetail, }) {
    const { setNumberOfResults, setCorrection, overrideSearchWithCorrection, setOverrideSearchWithCorrection, } = useRange();
    const results = useInfiniteResults(searchQuery, sort, language, sortAfterKey, numberOfResults, memoryResults, overrideSearchWithCorrection, setOverrideSearchWithCorrection);
    React.useEffect(() => {
        if (results.data && results.data.pages[0].total) {
            setTotalResult(results.data.pages[0].total);
            setNumberOfResults(results.data.pages[0].total);
        }
        else {
            setNumberOfResults(0);
        }
        setCorrection(results?.data?.pages[0]?.autocorrection);
    }, [results.data, setTotalResult, setNumberOfResults, setCorrection]);
    React.useEffect(() => {
        const sak = results.data?.pages[results.data.pages.length - 1].result[results.data?.pages[0].result.length - 1]?.sortAfterKey;
        if (sort && sak && sortAfterKey !== sak) {
            setSortAfterKey(sak);
        }
    }, [results]);
    const { t } = useTranslation();
    return (_jsx("div", { className: "openk9-infinite-results-overlay-scrollbars", css: css `
        height: 100%;
        overflow-y: auto;
        overflow-x: hidden;
        ::-webkit-scrollbar {
          width: 6px;
          height: 6px;
        }

        ::-webkit-scrollbar-track {
          background-color: transparent;
        }

        ::-webkit-scrollbar-thumb {
          background: rgba(0, 0, 0, 0.4);
          border-radius: 10px;
          height: 5px;
        }

        ::-webkit-scrollbar-thumb:hover {
          background: rgba(0, 0, 0, 0.55);
          height: 5px;
        }
      `, children: results?.data?.pages[0].total && results.data.pages[0].total > 0 ? (_jsxs("div", { className: "openk9-infinite-results-container-wrapper", css: css `
            padding-bottom: 16px;
          `, children: [_jsx("ul", { role: "list", css: css `
              list-style-type: none;
              padding: 0;
              margin: 0;
              gap: 10px;
              display: flex;
              flex-direction: column;
            `, children: results.data?.pages.map((page, pageIndex) => {
                        return (_jsx(React.Fragment, { children: page.result.map((result, resultIndex) => {
                                return (_jsx("li", { role: "listitem", "aria-labelledby": "resultid", css: css `
                          background: white;
                          border: 2px solid transparent;
                          border-radius: 8px;
                          &:hover {
                            border: 2px solid gray;
                          }
                        `, children: _jsx(ResultMemo, { renderers: renderers, result: result, onDetail: onDetail, setDetailMobile: setDetailMobile, isMobile: isMobile, overChangeCard: overChangeCard, setIdPreview: setIdPreview, viewButton: viewButton, setViewButtonDetail: setViewButtonDetail, templateCustom: templateCustom }, resultIndex) }, resultIndex));
                            }) }, `page-${pageIndex}`));
                    }) }), results.hasNextPage && (_jsx("div", { className: "openk9-container-embeddable-result-button", css: css `
                padding-inline: 16px;
                margin-top: 10px;
                padding-bottom: 16px;
              `, children: _jsx("button", { className: "openk9-embeddable-result-list-button-load-more", onClick: () => {
                            if (!results.isFetching) {
                                results.fetchNextPage();
                            }
                        }, css: css `
                  border: 1px solid
                    var(--openk9-embeddable-search--secondary-active-color);
                  padding: 8px 16px;
                  background: inherit;
                  width: 100%;
                  padding-inline: 16px;
                  border-radius: 20px;
                  color: var(
                    --openk9-embeddable-search--secondary-active-color
                  );
                  cursor: pointer;
                `, children: results.isFetching
                            ? t("loading-more-results")
                            : t("load-more") }) }))] })) : (_jsx(React.Fragment, { children: noResultsCustom ? noResultsCustom : _jsx(NoResults, {}) })) }));
}
export function VirtualResults({ renderers, searchQuery, onDetail, setDetailMobile, sort, isMobile, overChangeCard = false, language, sortAfterKey, setTotalResult, numberOfResults, memoryResults, viewButton, setViewButtonDetail, }) {
    const results = useInfiniteResults(searchQuery, sort, language, sortAfterKey, numberOfResults, memoryResults);
    const resultsFlat = results.data?.pages.flatMap((page) => page.result);
    const thereAreResults = Boolean(results.data?.pages[0].total && results.data.pages[0].total > 0);
    setTotalResult(results.data?.pages[0].total ?? null);
    const StyledVirtuoso = styled(Virtuoso) `
    flex-grow: 1;
  `;
    return (_jsxs("div", { className: "openk9-virtual-results-container", css: css `
        display: flex;
        flex-direction: column;
        height: 100%;
      `, children: [_jsx(StyledVirtuoso, { hidden: !thereAreResults, totalCount: resultsFlat?.length ?? 0, itemContent: (index) => {
                    const result = resultsFlat?.[index];
                    if (result) {
                        return (_jsx(ResultMemo, { renderers: renderers, result: result, onDetail: onDetail, setDetailMobile: setDetailMobile, isMobile: isMobile, overChangeCard: overChangeCard, viewButton: viewButton, setViewButtonDetail: setViewButtonDetail }));
                    }
                    return null;
                }, endReached: () => {
                    if (results.hasNextPage) {
                        results.fetchNextPage();
                    }
                }, components: {
                    Scroller: CustomVirtualScrollbar,
                    Footer() {
                        return (_jsx("div", { className: "openk9-virtual-results-footer", css: css `
                  padding: 16px;
                  display: flex;
                  justify-content: center;
                  align-items: center;
                `, children: results.hasNextPage
                                ? "loading more results..."
                                : "all results loaded" }));
                    },
                } }), !thereAreResults && _jsx(NoResults, {})] }));
}
function NoResults() {
    const { t } = useTranslation();
    return (_jsxs("div", { className: "openk9-no-results-container", css: css `
        color: var(--openk9-embeddable-search--secondary-text-color);
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        height: 100%;
        padding: 30px;
        background: white;
      `, children: [_jsx(Logo, { size: 128 }), _jsx("h3", { children: t("no-results-were-found") }), _jsx("div", { children: t("try-with-another-query") })] }));
}
export function useInfiniteResults(searchQuery, sort, language, sortAfterKey, numberOfResults, memoryResults, overrideSearchWithCorrection, setOverrideSearchWithCorrection) {
    const pageSize = numberOfResults;
    const client = useOpenK9Client();
    const { setRange } = useRange();
    const hasSortData = sort && sort.length > 0;
    const sortData = hasSortData ? sort[0] : undefined;
    return useInfiniteQuery([
        "results",
        searchQuery,
        sortData,
        language,
        overrideSearchWithCorrection?.renderingCorrection,
    ], async ({ queryKey: [, searchQuery, sort], pageParam = 0 }) => {
        const RangePage = !(sortData && sortAfterKey)
            ? [pageParam * pageSize, pageSize]
            : [0, pageSize];
        const remappingSearchQuery = overrideSearchWithCorrection?.isAutocorrection === false
            ? searchQuery.map((token) => token.tokenType === "TEXT" && token.search
                ? { ...token, overrideSearchWithCorrection: false }
                : token)
            : searchQuery;
        setRange(RangePage);
        const data = client.doSearch({
            range: RangePage,
            language,
            searchQuery: remappingSearchQuery,
            sort: sortData ? [sortData] : [],
            sortAfterKey: (sortData && pageParam > 0 && sortAfterKey) || "",
        });
        if (overrideSearchWithCorrection?.isAutocorrection === false) {
            setOverrideSearchWithCorrection?.((ov) => ({
                ...ov,
                isAutocorrection: true,
            }));
        }
        return data;
    }, {
        keepPreviousData: true,
        cacheTime: memoryResults ? Infinity : 0,
        getNextPageParam(lastPage, pages) {
            const totalDownloaded = pages.reduce((total, page) => total + page.result.length, 0);
            if (totalDownloaded < lastPage.total) {
                return pages.length;
            }
        },
        suspense: true,
        notifyOnChangeProps: ["isFetching"],
    });
}
export function recoverySearchQueryAndSort(searchQuery) {
    const searchQueryData = searchQuery.filter((info) => !info.hasOwnProperty("isSort"));
    const sortData = searchQuery.find((info) => info.hasOwnProperty("isSort"));
    const sort = sortData && sortData.hasOwnProperty("sort")
        ? sortData.sort
        : undefined;
    return {
        searchQueryData,
        sortData: sort ? sort : undefined,
    };
}
