"use strict";
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Filter = void 0;
const react_1 = __importDefault(require("react"));
const ReactiveComponent_1 = __importDefault(require("@usereactify/search-internals/lib/components/basic/ReactiveComponent"));
const MultiList_1 = __importDefault(require("@usereactify/search-internals/lib/components/list/MultiList"));
const SingleList_1 = __importDefault(require("@usereactify/search-internals/lib/components/list/SingleList"));
const SingleRange_1 = __importDefault(require("@usereactify/search-internals/lib/components/range/SingleRange"));
const MultiRange_1 = __importDefault(require("@usereactify/search-internals/lib/components/range/MultiRange"));
const hooks_1 = require("../../hooks");
const components_1 = require("../../components");
const props_1 = require("../../utility/props");
const Filter = (props) => {
    if ("single" === props.filter.displayType) {
        if ("range" === props.filter.displayView) {
            return react_1.default.createElement(FilterRangeSingle, Object.assign({}, props));
        }
        return react_1.default.createElement(FilterSingleList, Object.assign({}, props));
    }
    if ("multi" === props.filter.displayType) {
        if ("range" === props.filter.displayView) {
            return react_1.default.createElement(FilterRangeMulti, Object.assign({}, props));
        }
        return react_1.default.createElement(FilterMultiList, Object.assign({}, props));
    }
    if ("slider" === props.filter.displayType) {
        return react_1.default.createElement(FilterSlider, Object.assign({}, props));
    }
    // TODO: Legacy range filter, migrate to new single and multi ranges
    if ("range" === props.filter.displayType) {
        return react_1.default.createElement(FilterRangeSingle, Object.assign({}, props));
    }
    console.warn(`filter with display type "${props.filter.displayType}" not yet supported`);
    return null;
};
exports.Filter = Filter;
const FilterSingleList = (props) => {
    const reactifySearchContext = (0, hooks_1.useReactifySearchContext)();
    const filtersHook = (0, hooks_1.useFilters)();
    const sharedProps = (0, props_1.getPropsShared)({
        provider: reactifySearchContext.options,
        config: reactifySearchContext.config,
        filterGroup: filtersHook.filterStack,
    }, props.filter);
    const reactiveProps = (0, props_1.getPropsFilterList)(props.filter);
    return (react_1.default.createElement(SingleList_1.default, Object.assign({}, sharedProps, reactiveProps, { render: (reactivesearchFilterProps) => (react_1.default.createElement(FilterListInner, Object.assign({}, props, { reactivesearchFilterProps: reactivesearchFilterProps }))) })));
};
const FilterMultiList = (props) => {
    const reactifySearchContext = (0, hooks_1.useReactifySearchContext)();
    const filtersHook = (0, hooks_1.useFilters)();
    const sharedProps = (0, props_1.getPropsShared)({
        provider: reactifySearchContext.options,
        config: reactifySearchContext.config,
        filterGroup: filtersHook.filterStack,
    }, props.filter);
    const reactiveProps = (0, props_1.getPropsFilterList)(props.filter);
    return (react_1.default.createElement(MultiList_1.default, Object.assign({}, sharedProps, reactiveProps, { render: (reactivesearchFilterProps) => (react_1.default.createElement(FilterListInner, Object.assign({}, props, { reactivesearchFilterProps: reactivesearchFilterProps }))) })));
};
const FilterRangeSingle = (props) => {
    var _a;
    const reactifySearchContext = (0, hooks_1.useReactifySearchContext)();
    const filtersHook = (0, hooks_1.useFilters)();
    const sharedProps = (0, props_1.getPropsShared)({
        provider: reactifySearchContext.options,
        config: reactifySearchContext.config,
        filterGroup: filtersHook.filterStack,
    }, props.filter);
    const reactiveProps = (0, props_1.getPropsFilterRange)(props.filter);
    const filterRangeProps = (0, hooks_1.useFilterRangeProps)(props.filter);
    const RenderRangeComponent = (_a = props.renderFilterRange) !== null && _a !== void 0 ? _a : components_1.ExampleFilterRange;
    return (react_1.default.createElement(react_1.default.Fragment, null,
        react_1.default.createElement("div", { style: {
                display: "none",
            } },
            react_1.default.createElement(SingleRange_1.default, Object.assign({}, sharedProps, reactiveProps, { value: filterRangeProps.values[0], onChange: filterRangeProps.handleChange }))),
        react_1.default.createElement(RenderRangeComponent, { filterRangeProps: filterRangeProps, filter: props.filter })));
};
const FilterRangeMulti = (props) => {
    var _a;
    const reactifySearchContext = (0, hooks_1.useReactifySearchContext)();
    const filtersHook = (0, hooks_1.useFilters)();
    const sharedProps = (0, props_1.getPropsShared)({
        provider: reactifySearchContext.options,
        config: reactifySearchContext.config,
        filterGroup: filtersHook.filterStack,
    }, props.filter);
    const reactiveProps = (0, props_1.getPropsFilterRange)(props.filter);
    const filterRangeProps = (0, hooks_1.useFilterRangeProps)(props.filter);
    const RenderRangeComponent = (_a = props.renderFilterRange) !== null && _a !== void 0 ? _a : components_1.ExampleFilterRange;
    return (react_1.default.createElement(react_1.default.Fragment, null,
        react_1.default.createElement("div", { style: {
                display: "none",
            } },
            react_1.default.createElement(MultiRange_1.default, Object.assign({}, sharedProps, reactiveProps, { value: filterRangeProps.values, 
                // @note: onChange handler must be defined for controlled component to work correctly
                onChange: () => { }, onValueChange: (values) => {
                    if (values.length === 0) {
                        filterRangeProps.handleClear();
                    }
                } }))),
        react_1.default.createElement(RenderRangeComponent, { filterRangeProps: filterRangeProps, filter: props.filter })));
};
const FilterSlider = (props) => {
    const reactifySearchContext = (0, hooks_1.useReactifySearchContext)();
    const filtersHook = (0, hooks_1.useFilters)();
    const sharedProps = (0, props_1.getPropsShared)({
        provider: reactifySearchContext.options,
        config: reactifySearchContext.config,
        filterGroup: filtersHook.filterStack,
    }, props.filter);
    return (react_1.default.createElement(ReactiveComponent_1.default, Object.assign({}, sharedProps, { defaultQuery: () => ({
            aggs: {
                min: {
                    min: {
                        field: props.filter.field,
                    },
                },
                max: {
                    max: {
                        field: props.filter.field,
                    },
                },
            },
        }), render: (reactivesearchFilterProps) => {
            var _a, _b, _c, _d;
            if (!props.showEmptyFilters &&
                ((_b = (_a = reactivesearchFilterProps === null || reactivesearchFilterProps === void 0 ? void 0 : reactivesearchFilterProps.aggregations) === null || _a === void 0 ? void 0 : _a.min) === null || _b === void 0 ? void 0 : _b.value) ===
                    ((_d = (_c = reactivesearchFilterProps === null || reactivesearchFilterProps === void 0 ? void 0 : reactivesearchFilterProps.aggregations) === null || _c === void 0 ? void 0 : _c.max) === null || _d === void 0 ? void 0 : _d.value)) {
                return null;
            }
            return (react_1.default.createElement(FilterSliderInner, Object.assign({}, props, { reactivesearchFilterProps: reactivesearchFilterProps })));
        } })));
};
// inner component exists only so we can use memos in reactivesearch render functions
const FilterSliderInner = (props) => {
    var _a, _b, _c;
    const { filter, renderFilterSlider, reactivesearchFilterProps } = props, otherProps = __rest(props, ["filter", "renderFilterSlider", "reactivesearchFilterProps"]);
    const filterSliderProps = (0, hooks_1.useFilterSliderProps)(filter);
    react_1.default.useEffect(() => {
        if (reactivesearchFilterProps.aggregations) {
            filterSliderProps.handleRange([
                reactivesearchFilterProps.aggregations.min.value,
                reactivesearchFilterProps.aggregations.max.value,
            ]);
        }
    }, [
        (_a = reactivesearchFilterProps.aggregations) === null || _a === void 0 ? void 0 : _a.min.value,
        (_b = reactivesearchFilterProps.aggregations) === null || _b === void 0 ? void 0 : _b.max.value,
    ]);
    react_1.default.useEffect(() => {
        if (filterSliderProps.value[0] === 0 && filterSliderProps.value[1] === 0) {
            return;
        }
        props.reactivesearchFilterProps.setQuery({
            query: {
                query: {
                    bool: {
                        must: [
                            {
                                bool: {
                                    must: [
                                        {
                                            match: {
                                                published: true,
                                            },
                                        },
                                        {
                                            range: {
                                                [props.filter.field]: {
                                                    gte: filterSliderProps.value[0],
                                                    lte: filterSliderProps.value[1],
                                                    boost: 2,
                                                },
                                            },
                                        },
                                    ],
                                },
                            },
                        ],
                    },
                },
            },
            value: filterSliderProps.value,
        });
    }, [filterSliderProps.value]);
    const RenderListComponent = (_c = props.renderFilterSlider) !== null && _c !== void 0 ? _c : components_1.ExampleFilterSlider;
    return (react_1.default.createElement(RenderListComponent, Object.assign({ filterSliderProps: filterSliderProps, filter: filter }, otherProps)));
};
// inner component exists only so we can use memos in reactivesearch render functions
const FilterListInner = (props) => {
    var _a;
    const { filter, renderFilterList, reactivesearchFilterProps } = props, otherProps = __rest(props, ["filter", "renderFilterList", "reactivesearchFilterProps"]);
    const filterListProps = (0, hooks_1.useFilterListProps)(filter, reactivesearchFilterProps);
    // hide entire filter when no options available
    if (!props.showEmptyFilters && 0 === filterListProps.options.length) {
        return null;
    }
    const RenderListComponent = (_a = props.renderFilterList) !== null && _a !== void 0 ? _a : components_1.ExampleFilterList;
    return (react_1.default.createElement(RenderListComponent, Object.assign({ filterListProps: filterListProps, filter: filter }, otherProps)));
};
//# sourceMappingURL=Filter.js.map