"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Results = void 0;
const react_1 = __importDefault(require("react"));
const ReactiveList_1 = __importDefault(require("@usereactify/search-internals/lib/components/result/ReactiveList"));
const ResultCardCallout_1 = require("./ResultCardCallout");
const ResultCardProduct_1 = require("./ResultCardProduct");
const ResultPaginationNumbered_1 = require("./ResultPaginationNumbered");
const ResultPaginationLoadMore_1 = require("./ResultPaginationLoadMore");
const ResultPaginationNextPrev_1 = require("./ResultPaginationNextPrev");
const ResultPaginationInfiniteScroll_1 = require("./ResultPaginationInfiniteScroll");
const types_1 = require("../../types");
const hooks_1 = require("../../hooks");
const props_1 = require("../../utility/props");
const firestore_1 = require("../../types/firestore");
const Results = (props) => {
    const reactifySearchContext = (0, hooks_1.useReactifySearchContext)();
    const filtersHook = (0, hooks_1.useFilters)();
    const reactiveProps = (0, props_1.getPropsResults)({
        provider: reactifySearchContext.options,
        config: reactifySearchContext.config,
        filterGroup: filtersHook.filterStack,
        scrollTarget: props.infiniteScrollContainer,
        pageSize: props.pageSize,
        onData: props.onData,
    });
    const { track } = (0, hooks_1.useAnalytics)();
    const { searchTerm } = (0, hooks_1.useSearch)();
    const handleData = (renderProps) => {
        var _a;
        if (renderProps.resultStats.numberOfResults === 0) {
            let trimmedSearchTerm = searchTerm.trim();
            if (!trimmedSearchTerm || (trimmedSearchTerm && trimmedSearchTerm.length < 3))
                return;
            track({ eventName: "zeroResults", payload: { searchTerm: trimmedSearchTerm } });
            (_a = props.onData) === null || _a === void 0 ? void 0 : _a.call(props, renderProps);
        }
    };
    return (react_1.default.createElement(ReactiveList_1.default, Object.assign({}, reactiveProps, { render: (reactivesearchResultProps) => (react_1.default.createElement(ResultsInner, Object.assign({}, props, { reactivesearchResultProps: reactivesearchResultProps }))), onData: handleData, renderPagination: (reactivesearchPaginationProps) => (react_1.default.createElement(ResultsPaginationStack, Object.assign({}, props, reactivesearchPaginationProps))) })));
};
exports.Results = Results;
const ResultsRenderErrorComponent = (props) => {
    return (react_1.default.createElement("div", null,
        "Error: ",
        props.error.statusText));
};
const ResultsRenderLoadingComponent = () => {
    return react_1.default.createElement("div", null, "Loading");
};
const ResultsRenderNoResultsComponent = () => {
    return react_1.default.createElement("div", null, "No results");
};
const ResultsInner = (props) => {
    var _a, _b, _c, _d, _e, _f, _g;
    const context = (0, hooks_1.useReactifySearchContext)();
    const filtersHook = (0, hooks_1.useFilters)();
    const resultsHook = (0, hooks_1.useResults)();
    const initialSearchHasRun = react_1.default.useMemo(() => "undefined" !== typeof props.reactivesearchResultProps.resultStats.numberOfResults, [props.reactivesearchResultProps]);
    const listStyle = react_1.default.useMemo(() => {
        var _a;
        return (_a = props.listStyle) !== null && _a !== void 0 ? _a : {
            display: "grid",
            gap: "8px",
            gridTemplateColumns: "repeat(4, minmax(0, 1fr))",
        };
    }, [props.listStyle]);
    const infiniteScrollPosition = react_1.default.useMemo(() => {
        var _a, _b, _c, _d;
        if (!props.infiniteScrollPosition) {
            return NaN;
        }
        const scrollPositionOffset = props.reactivesearchResultProps.resultStats.displayedResults -
            ((_c = (_a = props.pageSize) !== null && _a !== void 0 ? _a : (_b = filtersHook.filterStack) === null || _b === void 0 ? void 0 : _b.pageSize) !== null && _c !== void 0 ? _c : 0);
        return scrollPositionOffset + ((_d = props.infiniteScrollPosition) !== null && _d !== void 0 ? _d : 0);
    }, [
        (_a = props.pageSize) !== null && _a !== void 0 ? _a : (_b = filtersHook.filterStack) === null || _b === void 0 ? void 0 : _b.pageSize,
        props.reactivesearchResultProps.resultStats.displayedResults,
        props.infiniteScrollPosition,
    ]);
    react_1.default.useEffect(() => {
        resultsHook.setResults(props.reactivesearchResultProps.data);
        resultsHook.setResultStats(props.reactivesearchResultProps.resultStats);
    }, [
        props.reactivesearchResultProps.resultStats.numberOfResults,
        props.reactivesearchResultProps.data.map((item) => item._id).join(""),
    ]);
    const calculateGridOverflow = react_1.default.useCallback((results) => {
        if (!props.gridColumns)
            return;
        let total = results.length;
        for (const result of results) {
            if (result.type === types_1.ElasticDocumentType.Product)
                continue;
            total += parseInt(result.callout.displayColumns) * parseInt(result.callout.displayRows) - 1;
        }
        const overflow = props.gridColumns - (total % props.gridColumns);
        if (overflow === props.gridColumns)
            return;
        return overflow === props.gridColumns ? undefined : overflow;
    }, [props.gridColumns]);
    const gridOverflowCallout = react_1.default.useMemo(() => {
        // check if there are more results
        if (props.reactivesearchResultProps.resultStats.displayedResults ===
            props.reactivesearchResultProps.resultStats.numberOfResults) {
            // check if we should only autofill when there are more results
            if (context.config.merchandising.calloutAutofillBehaviour ===
                firestore_1.MerchandisingCalloutAutofillBehaviour.MoreResults) {
                return;
            }
        }
        const overflow = calculateGridOverflow(props.reactivesearchResultProps.data);
        const callout = context.config.callouts.find((item) => item.displayColumns === `${overflow}`);
        if (!callout) {
            return;
        }
        return {
            _id: callout.id,
            _score: 0,
            type: types_1.ElasticDocumentType.Callout,
            key: Math.random().toString(16),
            callout: Object.assign(Object.assign({}, callout), { enabled: true }),
            published: true,
            curations: [],
        };
    }, [
        props.reactivesearchResultProps.resultStats,
        props.reactivesearchResultProps.data,
        context.config.callouts,
    ]);
    const results = react_1.default.useMemo(() => [
        ...props.reactivesearchResultProps.data,
        ...(gridOverflowCallout ? [gridOverflowCallout] : []),
    ], [props.reactivesearchResultProps.data, gridOverflowCallout]);
    if (props.reactivesearchResultProps.error) {
        const RenderErrorComponent = (_c = props.renderError) !== null && _c !== void 0 ? _c : ResultsRenderErrorComponent;
        return react_1.default.createElement(RenderErrorComponent, { error: props.reactivesearchResultProps.error });
    }
    if (!initialSearchHasRun) {
        const RenderLoadingComponent = (_d = props.renderLoading) !== null && _d !== void 0 ? _d : ResultsRenderLoadingComponent;
        return react_1.default.createElement(RenderLoadingComponent, null);
    }
    if (props.showSubsequentLoadingStates === true) {
        if (props.reactivesearchResultProps.loading) {
            const RenderLoadingComponent = (_e = props.renderLoading) !== null && _e !== void 0 ? _e : ResultsRenderLoadingComponent;
            return react_1.default.createElement(RenderLoadingComponent, null);
        }
    }
    if (!props.reactivesearchResultProps.loading &&
        !props.reactivesearchResultProps.resultStats.numberOfResults) {
        const RenderNoResultsComponent = (_f = props.renderNoResults) !== null && _f !== void 0 ? _f : ResultsRenderNoResultsComponent;
        return react_1.default.createElement(RenderNoResultsComponent, null);
    }
    if (["search", "instant-search"].includes(context.options.mode)) {
        if (!context.search.searchTerm) {
            const RenderNoResultsComponent = (_g = props.renderNoResults) !== null && _g !== void 0 ? _g : ResultsRenderNoResultsComponent;
            return react_1.default.createElement(RenderNoResultsComponent, null);
        }
    }
    return (react_1.default.createElement(react_1.default.Fragment, null,
        react_1.default.createElement("section", { style: listStyle, className: props.listClassName }, results.map((item, key) => {
            if (types_1.ElasticDocumentType.Product === item.type) {
                return (react_1.default.createElement(ResultCardProduct_1.ResultCardProduct, Object.assign({ key: item._id, product: item, document: item, pagePosition: key + 1, render: props.renderResultCardProduct }, (infiniteScrollPosition === key + 1
                    ? {
                        onView: () => props.reactivesearchResultProps.loadMore(),
                    }
                    : {}))));
            }
            if (types_1.ElasticDocumentType.Callout === item.type) {
                return (react_1.default.createElement(ResultCardCallout_1.ResultCardCallout, Object.assign({ key: item._id, document: item, pagePosition: key + 1, callout: item.callout, render: props.renderResultCardCallout }, (infiniteScrollPosition === key + 1
                    ? {
                        onView: () => props.reactivesearchResultProps.loadMore(),
                    }
                    : {}))));
            }
            return null;
        })),
        react_1.default.createElement(ResultsPaginationStackLoadable, Object.assign({}, props, props.reactivesearchResultProps))));
};
/** Handles rendering pagination for types that use "pagination props" */
const ResultsPaginationStack = (props) => {
    const { options } = (0, hooks_1.useReactifySearchContext)();
    const { filterStack } = (0, hooks_1.useFilters)();
    if (options.mode === "instant-search") {
        return null;
    }
    if ("pagination" === (filterStack === null || filterStack === void 0 ? void 0 : filterStack.paginationType)) {
        return react_1.default.createElement(ResultPaginationNumbered_1.ResultPaginationNumbered, Object.assign({}, props, { render: props.renderPaginationNumbered }));
    }
    if ("next_prev" === (filterStack === null || filterStack === void 0 ? void 0 : filterStack.paginationType)) {
        return react_1.default.createElement(ResultPaginationNextPrev_1.ResultPaginationNextPrev, Object.assign({}, props, { render: props.renderPaginationNextPrev }));
    }
    return null;
};
/** Handles rendering pagination for types that use "result props" */
const ResultsPaginationStackLoadable = (props) => {
    const { options } = (0, hooks_1.useReactifySearchContext)();
    const { filterStack } = (0, hooks_1.useFilters)();
    if (options.mode === "instant-search") {
        return null;
    }
    if ("load_more" === (filterStack === null || filterStack === void 0 ? void 0 : filterStack.paginationType)) {
        return (react_1.default.createElement(ResultPaginationLoadMore_1.ResultPaginationLoadMore, Object.assign({}, props.reactivesearchResultProps, { render: props.renderPaginationLoadMore })));
    }
    if ("infinite_scroll" === (filterStack === null || filterStack === void 0 ? void 0 : filterStack.paginationType)) {
        return (react_1.default.createElement(ResultPaginationInfiniteScroll_1.ResultPaginationInfiniteScroll, Object.assign({}, props.reactivesearchResultProps, { render: props.renderPaginationInfiniteScroll })));
    }
    return null;
};
//# sourceMappingURL=Results.js.map