import dayjs from 'dayjs';
import customParse from '../../../../_virtual/customParseFormat.js';
import isBetween from '../../../../_virtual/isBetween.js';
import StartEndDatetUtils from '../start-end-date/utils.js';
import RelativeDateRange from './types.js';
import { calcDatesForUI, calcDatesForAPI } from '../../../utils/durationCalculator.js';

/* eslint-disable no-param-reassign */
dayjs.extend(customParse);
dayjs.extend(isBetween);
const dateIsInBounds = (startDate, endDate, min, max) => {
    const minDate = dayjs(min, 'YYYY-MM-DD').startOf('day');
    const maxDate = dayjs(max, 'YYYY-MM-DD').endOf('day');
    const isStartValid = !startDate || dayjs(startDate, 'DD/MM/YYYY').isBetween(minDate, maxDate, 'day', '[]');
    const isEndValid = !endDate || dayjs(endDate, 'DD/MM/YYYY').isBetween(minDate, maxDate, 'day', '[]');
    return isStartValid && isEndValid;
};
const setValueFromRequest = (filter, req, prefix) => {
    const { relativeOptions } = filter;
    const start = req.query[`${prefix}${filter.name}.start`];
    const end = req.query[`${prefix}${filter.name}.end`];
    const relative = req.query[`${prefix}${filter.name}.relative-duration`];
    let relativeDisabled = false;
    if (relative && relativeOptions) {
        const option = relativeOptions.find((opt) => opt.value === relative);
        relativeDisabled = option && option.disabled ? option.disabled : false;
    }
    const value = {
        start,
        end,
        ...(relative && !relativeDisabled && { relative }),
    };
    return value;
};
const setDefaultValue = (req, name) => {
    const dateRangeName = name.split('.')[0];
    const dateRangeDefaults = Object.keys(req.body)
        .filter((key) => key.includes(dateRangeName))
        .map((key) => {
        return { name: key.split('.')[2], value: req.body[key] };
    });
    const dateRangeValue = { start: '', end: '' };
    dateRangeDefaults.forEach((dateRangeDefault) => {
        if (dateRangeDefault.name.includes('start')) {
            dateRangeValue.start = dateRangeDefault.value;
        }
        if (dateRangeDefault.name.includes('end')) {
            dateRangeValue.end = dateRangeDefault.value;
        }
        if (dateRangeDefault.name.includes('relative-duration')) {
            dateRangeValue.relative = dateRangeDefault.value;
        }
    });
    return { value: dateRangeValue, name: dateRangeName };
};
const setFilterValueFromDefault = (defaultValue, filter) => {
    const value = { start: '', end: '', relative: '' };
    const { start, end, relative } = defaultValue.value;
    if (relative) {
        value.relative = relative;
    }
    if (start) {
        value.start = dayjs(start, 'D/M/YYYY').format('YYYY-MM-DD').toString();
    }
    if (end) {
        value.end = dayjs(end, 'D/M/YYYY').format('YYYY-MM-DD').toString();
    }
    return {
        ...filter,
        value,
    };
};
const getRelativeDateOptions = (min, max) => {
    if (!min)
        min = '1977-05-25';
    if (!max)
        max = '9999-01-01';
    let options = getRelativeValues();
    options.forEach((option) => {
        if (option.value !== RelativeDateRange.NONE) {
            const dates = calcDatesForUI(option.value);
            if (dates && !dateIsInBounds(dates.start, dates.end, min, max)) {
                option.disabled = true;
            }
        }
    });
    if (options
        .filter((opt) => opt.value !== 'none')
        .every((opt) => {
        return opt.value === null || opt.disabled;
    })) {
        options = [];
    }
    return options;
};
const mapRelativeValue = (value) => {
    const values = getRelativeValues();
    const opt = values.find((v) => v.value === value);
    return opt ? opt.text : '';
};
const getRelativeValues = () => {
    return [
        { value: RelativeDateRange.NONE, text: 'None' },
        { value: RelativeDateRange.YESTERDAY, text: 'Yesterday' },
        { value: RelativeDateRange.TOMORROW, text: 'Tomorrow' },
        { value: RelativeDateRange.LAST_WEEK, text: 'Last week' },
        { value: RelativeDateRange.NEXT_WEEK, text: 'Next week' },
        { value: RelativeDateRange.LAST_MONTH, text: 'Last month' },
        { value: RelativeDateRange.NEXT_MONTH, text: 'Next month' },
    ];
};
const getFilterFromDefinition = (filter, filterData) => {
    const value = StartEndDatetUtils.getStartAndEndValueFromDefinition(filter);
    const relativeOptions = getRelativeDateOptions(filter.min, filter.max);
    return {
        ...filterData,
        min: filter.min,
        max: filter.max,
        relativeOptions,
        value,
    };
};
/**
 * Creates and appends the daterange query string
 * to an existing URLSearchParams
 *
 * @param {URLSearchParams} params
 * @param {string} fieldName
 * @param {string} defaultValue
 */
const appendDateRangeValue = (params, fieldName, value) => {
    if (value.start) {
        params.append(`filters.${fieldName}.start`, value.start);
    }
    if (value.end) {
        params.append(`filters.${fieldName}.end`, value.end);
    }
    if (value.relative) {
        params.append(`filters.${fieldName}.relative-duration`, value.relative);
    }
};
const resolveDateRangeDefaults = (filter) => {
    // Case 1: quick filter wins
    if (filter.defaultQuickFilterValue) {
        const dates = calcDatesForAPI(filter.defaultQuickFilterValue);
        return {
            relative: filter.defaultQuickFilterValue,
            ...(dates?.start !== undefined ? { start: dates.start } : {}),
            ...(dates?.end !== undefined ? { end: dates.end } : {}),
        };
    }
    if (filter.defaultValue) {
        const [start, end] = filter.defaultValue
            .split(' - ')
            .map((v) => v.trim())
            .filter(Boolean);
        return {
            ...(start !== undefined ? { start } : {}),
            ...(end !== undefined ? { end } : {}),
        };
    }
    return undefined;
};
var DateRangeInputUtils = {
    getRelativeDateOptions,
    getFilterFromDefinition,
    setValueFromRequest,
    mapRelativeValue,
    setDefaultValue,
    setFilterValueFromDefault,
    appendDateRangeValue,
};

export { appendDateRangeValue, dateIsInBounds, DateRangeInputUtils as default, getFilterFromDefinition, getRelativeDateOptions, getRelativeValues, mapRelativeValue, resolveDateRangeDefaults, setDefaultValue, setFilterValueFromDefault, setValueFromRequest };
//# sourceMappingURL=utils.js.map
