export const defaultRangeFacetOptions = {
    filterFacetCount: true,
    injectionDepth: 1000,
    numberOfValues: 8,
    sortCriteria: 'ascending',
    rangeAlgorithm: 'even',
    resultsMustMatch: 'atLeastOneValue',
};
export function registerRangeFacet(state, slice) {
    const { request } = slice;
    const { facetId } = request;
    if (facetId in state) {
        return;
    }
    const numberOfValues = calculateNumberOfValues(request);
    request.numberOfValues = numberOfValues;
    state[facetId] = slice;
}
export function updateRangeValues(state, facetId, values) {
    const request = state[facetId]?.request;
    if (!request) {
        return;
    }
    request.currentValues = values;
    request.numberOfValues = calculateNumberOfValues(request);
}
export function toggleSelectRangeValue(state, facetId, selection) {
    const request = state[facetId]?.request;
    if (!request) {
        return;
    }
    const value = findRange(request.currentValues, selection);
    if (!value) {
        return;
    }
    const isSelected = value.state === 'selected';
    value.previousState = value.state;
    value.state = isSelected ? 'idle' : 'selected';
    request.preventAutoSelect = true;
}
export function toggleExcludeRangeValue(state, facetId, selection) {
    const request = state[facetId]?.request;
    if (!request) {
        return;
    }
    const value = findRange(request.currentValues, selection);
    if (!value) {
        return;
    }
    const isExcluded = value.state === 'excluded';
    value.previousState = value.state;
    value.state = isExcluded ? 'idle' : 'excluded';
    request.preventAutoSelect = true;
}
export function handleRangeFacetDeselectAll(state, facetId) {
    const facetRequest = state[facetId]?.request;
    if (!facetRequest) {
        return;
    }
    facetRequest.currentValues.forEach((request) => {
        if (request.state !== 'idle') {
            request.previousState = request.state;
        }
        request.state = 'idle';
    });
}
export function handleRangeFacetSearchParameterRestoration(state, rangeFacets) {
    Object.entries(state).forEach(([facetId, { request }]) => {
        const rangesToSelect = rangeFacets[facetId] || [];
        request.currentValues.forEach((range) => {
            const found = !!findRange(rangesToSelect, range);
            if (found) {
                range.state = 'selected';
            }
            else if (typeof rangeFacets === 'object' &&
                facetId in rangeFacets &&
                range.state !== 'idle') {
                range.previousState = range.state;
                range.state = 'idle';
            }
            return range;
        });
        const missingRanges = rangesToSelect.filter((range) => !findRange(request.currentValues, range));
        const currentValues = request.currentValues;
        currentValues.push(...missingRanges);
        request.numberOfValues = Math.max(request.numberOfValues, currentValues.length);
    });
}
export function onRangeFacetRequestFulfilled(state, facets, convert) {
    facets.forEach((facetResponse) => {
        const id = facetResponse.facetId;
        const facetRequest = state[id]?.request;
        if (!facetRequest) {
            return;
        }
        const values = convert(facetResponse.values);
        facetRequest.currentValues = values;
        facetRequest.preventAutoSelect = false;
    });
}
function findRange(values, value) {
    const { start, end } = value;
    return values.find((range) => range.start === start && range.end === end);
}
export function findExactRangeValue(values, value) {
    const { start, end, endInclusive } = value;
    return values.find((range) => range.start === start &&
        range.end === end &&
        range.endInclusive === endInclusive);
}
function calculateNumberOfValues(request) {
    const { generateAutomaticRanges, currentValues, numberOfValues } = request;
    return generateAutomaticRanges
        ? Math.max(numberOfValues, currentValues.length)
        : currentValues.length;
}
