'use strict';

var DateLib = require('../classes/DateLib.cjs');
var dateMatchModifiers = require('./dateMatchModifiers.cjs');
var rangeContainsDayOfWeek = require('./rangeContainsDayOfWeek.cjs');
var rangeIncludesDate = require('./rangeIncludesDate.cjs');
var rangeOverlaps = require('./rangeOverlaps.cjs');
var typeguards = require('./typeguards.cjs');

/**
 * Returns whether a range contains dates that match the given modifiers.
 *
 * ```tsx
 * const range: DateRange = {
 *   from: new Date(2021, 12, 21),
 *   to: new Date(2021, 12, 30)
 * };
 * const matcher1: Date = new Date(2021, 12, 21);
 * const matcher2: DateRange = {
 *   from: new Date(2022, 5, 1),
 *   to: new Date(2022, 5, 23)
 * };
 * rangeContainsModifiers(range, [matcher1, matcher2]); // true, since matcher1 is in the date.
 * ```
 *
 * @since 9.2.2
 * @group Utilities
 */
function rangeContainsModifiers(range, modifiers, dateLib = DateLib.defaultDateLib) {
    const matchers = Array.isArray(modifiers) ? modifiers : [modifiers];
    // Defer function matchers evaluation as they are the least performant.
    const nonFunctionMatchers = matchers.filter((matcher) => typeof matcher !== "function");
    const nonFunctionMatchersResult = nonFunctionMatchers.some((matcher) => {
        if (typeof matcher === "boolean")
            return matcher;
        if (dateLib.isDate(matcher)) {
            return rangeIncludesDate.rangeIncludesDate(range, matcher, false, dateLib);
        }
        if (typeguards.isDatesArray(matcher, dateLib)) {
            return matcher.some((date) => rangeIncludesDate.rangeIncludesDate(range, date, false, dateLib));
        }
        if (typeguards.isDateRange(matcher)) {
            if (matcher.from && matcher.to) {
                return rangeOverlaps.rangeOverlaps(range, { from: matcher.from, to: matcher.to }, dateLib);
            }
            return false;
        }
        if (typeguards.isDayOfWeekType(matcher)) {
            return rangeContainsDayOfWeek.rangeContainsDayOfWeek(range, matcher.dayOfWeek, dateLib);
        }
        if (typeguards.isDateInterval(matcher)) {
            const isClosedInterval = dateLib.isAfter(matcher.before, matcher.after);
            if (isClosedInterval) {
                return rangeOverlaps.rangeOverlaps(range, {
                    from: dateLib.addDays(matcher.after, 1),
                    to: dateLib.addDays(matcher.before, -1)
                }, dateLib);
            }
            return (dateMatchModifiers.dateMatchModifiers(range.from, matcher, dateLib) ||
                dateMatchModifiers.dateMatchModifiers(range.to, matcher, dateLib));
        }
        if (typeguards.isDateAfterType(matcher) || typeguards.isDateBeforeType(matcher)) {
            return (dateMatchModifiers.dateMatchModifiers(range.from, matcher, dateLib) ||
                dateMatchModifiers.dateMatchModifiers(range.to, matcher, dateLib));
        }
        return false;
    });
    if (nonFunctionMatchersResult) {
        return true;
    }
    const functionMatchers = matchers.filter((matcher) => typeof matcher === "function");
    if (functionMatchers.length) {
        let date = range.from;
        const totalDays = dateLib.differenceInCalendarDays(range.to, range.from);
        for (let i = 0; i <= totalDays; i++) {
            if (functionMatchers.some((matcher) => matcher(date))) {
                return true;
            }
            date = dateLib.addDays(date, 1);
        }
    }
    return false;
}

exports.rangeContainsModifiers = rangeContainsModifiers;
//# sourceMappingURL=rangeContainsModifiers.cjs.map
