"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: Object.getOwnPropertyDescriptor(all, name).get
    });
}
_export(exports, {
    get datePickerRangeConfig () {
        return datePickerRangeConfig;
    },
    get datePickerRangeRoot () {
        return datePickerRangeRoot;
    }
});
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
const _classnames = /*#__PURE__*/ _interop_require_default(require("classnames"));
const _utils = require("../../../utils");
const _datejs = require("../../../utils/datejs");
const _dateHelper = require("../utils/dateHelper");
const _useDatePicker = require("../hooks/useDatePicker");
const _DatePickertokens = require("../DatePicker.tokens");
const _useKeyboardNavigation = require("../hooks/useKeyboardNavigation");
const _DatePickerBasestyles = require("../DatePickerBase.styles");
const _utils1 = require("../../Calendar/utils");
const _utils2 = require("../utils");
const _base = require("./variations/_size/base");
const _base1 = require("./variations/_view/base");
const _base2 = require("./variations/_hint-view/base");
const _base3 = require("./variations/_hint-size/base");
const _base4 = require("./variations/_tooltip-size/base");
const _base5 = require("./variations/_disabled/base");
const _base6 = require("./variations/_readonly/base");
const _RangeDatestyles = require("./RangeDate.styles");
const _RangeDatePopover = require("./RangeDatePopover/RangeDatePopover");
function _interop_require_default(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    };
}
function _getRequireWildcardCache(nodeInterop) {
    if (typeof WeakMap !== "function") return null;
    var cacheBabelInterop = new WeakMap();
    var cacheNodeInterop = new WeakMap();
    return (_getRequireWildcardCache = function(nodeInterop) {
        return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
    })(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
    if (!nodeInterop && obj && obj.__esModule) {
        return obj;
    }
    if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
        return {
            default: obj
        };
    }
    var cache = _getRequireWildcardCache(nodeInterop);
    if (cache && cache.has(obj)) {
        return cache.get(obj);
    }
    var newObj = {
        __proto__: null
    };
    var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
    for(var key in obj){
        if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
            var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
            if (desc && (desc.get || desc.set)) {
                Object.defineProperty(newObj, key, desc);
            } else {
                newObj[key] = obj[key];
            }
        }
    }
    newObj.default = obj;
    if (cache) {
        cache.set(obj, newObj);
    }
    return newObj;
}
const datePickerRangeRoot = (Root)=>/*#__PURE__*/ (0, _react.forwardRef)(({ className, name, autoComplete, // controlled
    isDoubleCalendar = false, opened: outerOpened, value: outerValue, defaultFirstDate = '', defaultSecondDate = '', preserveInvalidOnBlur, // variations
    view, size, readOnly = false, disabled = false, appearance, hasClearDivider, stretched, firstValueError, secondValueError, firstValueSuccess, secondValueSuccess, // layout
    required, requiredPlacement = 'right', hasRequiredIndicator = false, label, leftHelper, contentLeft, contentRight, dividerVariant = 'dash', dividerIcon, firstPlaceholder, secondPlaceholder, firstTextfieldContentLeft, firstTextfieldContentRight, secondTextfieldContentLeft, secondTextfieldContentRight, firstTextfieldTextBefore, secondTextfieldTextBefore, firstTextfieldTextAfter, secondTextfieldTextAfter, // hint
    hintTrigger = 'hover', hintText, hintView = 'default', hintSize = 'm', hintTargetIcon, hintTargetPlacement = 'outer', hintPlacement = 'auto', hintHasArrow, hintOffset = [
        0,
        0
    ], hintWidth, hintContentLeft, // popover-container
    frame = 'document', usePortal = false, zIndex, placement = [
        'top',
        'bottom'
    ], closeOnOverlayClick = true, closeOnEsc = true, closeAfterDateSelect = true, offset, disableFlip, // calendar
    format = 'DD.MM.YYYY', lang = 'ru', maskWithFormat, min, max, renderFromDate, includeEdgeDates = false, eventTooltipOptions, eventList, disabledList, eventMonthList, disabledMonthList, eventQuarterList, disabledQuarterList, eventYearList, disabledYearList, type = 'Days', calendarContainerWidth, calendarContainerHeight, dateShortcuts, dateShortcutsPlacement = 'left', dateShortcutsWidth, onToggle, onChange, onChangeFirstValue, onChangeSecondValue, onCommitFirstDate, onCommitSecondDate, onFocusFirstTextfield, onFocusSecondTextfield, onBlurFirstTextfield, onBlurSecondTextfield, ...rest }, ref)=>{
        const rangeRef = ref && 'current' in ref ? ref : /*#__PURE__*/ (0, _react.createRef)();
        const rootRef = (0, _react.useRef)(null);
        const innerRefFirst = (0, _react.useRef)(null);
        const innerRefSecond = (0, _react.useRef)(null);
        const [firstInputRef, setFirstInputRef] = (0, _react.useState)(rangeRef?.current?.firstTextField());
        const [secondInputRef, setSecondInputRef] = (0, _react.useState)(rangeRef?.current?.secondTextField());
        const [isInnerOpen, setIsInnerOpen] = (0, _react.useState)(false);
        const openedValue = outerOpened ?? isInnerOpen;
        const dateFormatDelimiter = (0, _dateHelper.getDateFormatDelimiter)(format);
        const [startInnerDate, setStartInnerDate] = (0, _react.useState)(defaultFirstDate || '');
        const startDateValue = outerValue?.[0] ?? startInnerDate;
        const startInitialValues = (0, _utils2.getFormattedDates)({
            value: startDateValue,
            delimiter: dateFormatDelimiter,
            lang,
            format,
            includeEdgeDates,
            min,
            max
        });
        const [endInnerDate, setEndInnerDate] = (0, _react.useState)(defaultSecondDate || '');
        const endDateValue = outerValue?.[1] ?? endInnerDate;
        const endInitialValues = (0, _utils2.getFormattedDates)({
            value: endDateValue,
            delimiter: dateFormatDelimiter,
            lang,
            format,
            includeEdgeDates,
            min,
            max
        });
        const [correctStartDates, setCorrectStartDates] = (0, _react.useState)({
            calendar: startInitialValues.originalDate,
            input: startInitialValues.formattedDate
        });
        const [correctEndDates, setCorrectEndDates] = (0, _react.useState)({
            calendar: endInitialValues.originalDate,
            input: endInitialValues.formattedDate
        });
        const calendarFirstValue = startInitialValues.originalDate;
        const inputFirstValue = startInitialValues.formattedDate;
        const calendarSecondValue = endInitialValues.originalDate;
        const inputSecondValue = endInitialValues.formattedDate;
        const fullDateEntered = Boolean(calendarFirstValue && calendarSecondValue);
        const [secondTextFieldClicked, setSecondTextFieldClicked] = (0, _react.useState)(false);
        const isSameMonth = Boolean(fullDateEntered && (0, _datejs.customDayjs)(calendarFirstValue).isSame(calendarSecondValue, 'month'));
        let calendarFocusedDate = calendarFirstValue;
        if (secondTextFieldClicked && calendarSecondValue) {
            const shouldShowPreviousMonth = Boolean(isDoubleCalendar && calendarFirstValue && !isSameMonth);
            calendarFocusedDate = shouldShowPreviousMonth ? new Date(calendarSecondValue.getFullYear(), calendarSecondValue.getMonth() - 1, 1) : calendarSecondValue;
        }
        const handleInputChange = (value)=>{
            if (onChange) {
                onChange({
                    target: {
                        value,
                        name
                    }
                });
            }
        };
        const setFirstInputValue = (value)=>{
            setStartInnerDate(value);
            handleInputChange(`${value} - ${inputSecondValue}`);
        };
        const setSecondInputValue = (value)=>{
            setEndInnerDate(value);
            handleInputChange(`${inputFirstValue} - ${value}`);
        };
        const commonUseDatePickerArgs = {
            format,
            lang,
            disabled,
            readOnly,
            maskWithFormat,
            name,
            type,
            min,
            max,
            includeEdgeDates,
            dateFormatDelimiter
        };
        const { handleChangeValue: handleChangeFirstValue, handleCalendarPick: handleFirstCalendarPick, handleSearch: handleSearchFirst, updateExternalDate: updateExternalFirstDate, getQuarterInfo: getFirstQuarterInfo } = (0, _useDatePicker.useDatePicker)({
            currentValue: inputFirstValue,
            valueError: firstValueError,
            valueSuccess: firstValueSuccess,
            ...commonUseDatePickerArgs,
            setCorrectDates: setCorrectStartDates,
            setInnerDate: setFirstInputValue,
            onChangeValue: onChangeFirstValue,
            onCommitDate: onCommitFirstDate
        });
        const { handleChangeValue: handleChangeSecondValue, handleCalendarPick: handleSecondCalendarPick, handleSearch: handleSearchSecond, updateExternalDate: updateExternalSecondDate, getQuarterInfo: getSecondQuarterInfo } = (0, _useDatePicker.useDatePicker)({
            currentValue: inputSecondValue,
            valueError: secondValueError,
            valueSuccess: secondValueSuccess,
            ...commonUseDatePickerArgs,
            setCorrectDates: setCorrectEndDates,
            setInnerDate: setSecondInputValue,
            onChangeValue: onChangeSecondValue,
            onCommitDate: onCommitSecondDate
        });
        const handleToggle = (currentOpened, event)=>{
            if (disabled || readOnly) {
                return;
            }
            const isCalendarOpen = (firstInputRef?.current?.contains(event?.target || null) || secondInputRef?.current?.contains(event?.target || null)) && event?.code !== _useKeyboardNavigation.keys.Escape ? true : currentOpened;
            if (!isCalendarOpen) {
                setSecondTextFieldClicked(false);
            }
            if (onToggle) {
                onToggle(isCalendarOpen, event);
            }
            setIsInnerOpen(isCalendarOpen);
        };
        const handleFocusFirstTextField = (event)=>{
            onFocusFirstTextfield?.(event);
            setSecondTextFieldClicked(false);
        };
        const handleFocusSecondTextField = (event)=>{
            onFocusSecondTextfield?.(event);
            setSecondTextFieldClicked(true);
        };
        const handleBlur = (event, outerHandler)=>{
            if (!inputFirstValue || !inputSecondValue || preserveInvalidOnBlur) {
                outerHandler?.(event);
                return;
            }
            const commonArgs = {
                lang,
                format,
                includeEdgeDates,
                min,
                max
            };
            let { originalDate: startOriginalDate } = (0, _utils2.getFormattedDates)({
                value: inputFirstValue,
                delimiter: dateFormatDelimiter,
                ...commonArgs
            });
            let { originalDate: endOriginalDate } = (0, _utils2.getFormattedDates)({
                value: inputSecondValue,
                delimiter: dateFormatDelimiter,
                ...commonArgs
            });
            if (!calendarFirstValue && correctStartDates.calendar) {
                startOriginalDate = new Date(correctStartDates.calendar);
            }
            if (!calendarSecondValue && correctEndDates.calendar) {
                endOriginalDate = new Date(correctEndDates.calendar);
            }
            const [startValue, endValue] = (0, _utils1.getSortedValues)([
                startOriginalDate,
                endOriginalDate
            ]);
            const { formattedDate: formattedFirstDate, originalDate: originalFirstDate, isoDate: isoFirstDate } = (0, _utils2.getFormattedDates)({
                value: startValue,
                delimiter: dateFormatDelimiter,
                ...commonArgs
            });
            const { formattedDate: formattedSecondDate, originalDate: originalSecondDate, isoDate: isoSecondDate } = (0, _utils2.getFormattedDates)({
                value: endValue,
                delimiter: dateFormatDelimiter,
                ...commonArgs
            });
            if (formattedFirstDate !== inputFirstValue) {
                if (onChangeFirstValue) {
                    onChangeFirstValue(event, formattedFirstDate, originalFirstDate, isoFirstDate);
                }
                if (onCommitFirstDate) {
                    const dateInfo = originalFirstDate ? getFirstQuarterInfo(originalFirstDate) : undefined;
                    (0, _utils2.invokeOnCommitDate)({
                        callback: onCommitFirstDate,
                        value: formattedFirstDate,
                        formattedValues: {
                            error: false,
                            success: true,
                            dateInfo,
                            originalDate: originalFirstDate,
                            isoDate: isoFirstDate
                        }
                    });
                }
            }
            if (formattedSecondDate !== inputSecondValue) {
                if (onChangeSecondValue) {
                    onChangeSecondValue(event, formattedSecondDate, originalSecondDate, isoSecondDate);
                }
                if (onCommitSecondDate) {
                    const dateInfo = originalSecondDate ? getSecondQuarterInfo(originalSecondDate) : undefined;
                    (0, _utils2.invokeOnCommitDate)({
                        callback: onCommitSecondDate,
                        value: formattedSecondDate,
                        formattedValues: {
                            error: false,
                            success: true,
                            dateInfo,
                            originalDate: originalSecondDate,
                            isoDate: isoSecondDate
                        }
                    });
                }
            }
            setFirstInputValue(startValue);
            setSecondInputValue(endValue);
            outerHandler?.(event);
        };
        const { onKeyDown } = (0, _useKeyboardNavigation.useKeyNavigation)({
            isCalendarOpen: openedValue,
            format,
            maskWithFormat,
            delimiter: dateFormatDelimiter,
            closeOnEsc,
            onToggle: handleToggle
        });
        const handleShortcutDateSelect = (shortcutDate)=>{
            handleFirstCalendarPick(shortcutDate[0]);
            handleSecondCalendarPick(shortcutDate[1]);
        };
        const handleChangeStartOfRange = (chosenDate, dateInfo)=>{
            if (!fullDateEntered) {
                handleFirstCalendarPick(chosenDate, dateInfo);
                handleSecondCalendarPick(undefined);
                return;
            }
            const prevValue = secondTextFieldClicked ? calendarFirstValue : calendarSecondValue;
            const [first, second] = (0, _utils1.getSortedValues)([
                prevValue,
                chosenDate
            ]);
            /**
                 * NOTE: проверяем совпадает ли новая дата с предыдущей
                 * Если нет, то вызываем handle{First,Second}CalendarPick
                 */ _datejs.customDayjs.locale(lang);
            const firstFormatted = first ? (0, _datejs.customDayjs)(first).format(format) : '';
            const secondFormatted = second ? (0, _datejs.customDayjs)(second).format(format) : '';
            if (firstFormatted !== inputFirstValue) {
                handleFirstCalendarPick(first, dateInfo);
            }
            if (secondFormatted !== inputSecondValue) {
                handleSecondCalendarPick(second, dateInfo);
            }
            if (!firstValueError && !secondValueError && closeAfterDateSelect) {
                handleToggle(false);
            }
        };
        const handleChangeCalendarValue = ([firstDate, secondDate], dateInfo)=>{
            /**
                 * NOTE: проверяем совпадает ли новая дата с предыдущей
                 * Если нет, то вызываем handle{First,Second}CalendarPick
                 */ _datejs.customDayjs.locale(lang);
            const firstFormatted = firstDate ? (0, _datejs.customDayjs)(firstDate).format(format) : '';
            const secondFormatted = secondDate ? (0, _datejs.customDayjs)(secondDate).format(format) : '';
            if (firstFormatted !== inputFirstValue) {
                handleFirstCalendarPick(firstDate, dateInfo);
            }
            if (secondFormatted !== inputSecondValue) {
                handleSecondCalendarPick(secondDate, dateInfo);
            }
            if (firstDate && secondDate && !firstValueError && !secondValueError && closeAfterDateSelect) {
                handleToggle(false);
            }
        };
        const handleSearchFirstValue = (_, date)=>{
            handleSearchFirst(String(date));
            if (!calendarSecondValue || secondValueError) {
                rangeRef?.current?.secondTextField()?.current?.focus();
            }
        };
        const handleSearchSecondValue = (_, date)=>{
            handleSearchSecond(String(date));
            if (!calendarFirstValue || firstValueError) {
                rangeRef?.current?.firstTextField()?.current?.focus();
            }
        };
        const handleBlurFirstTextfield = (event)=>handleBlur(event, onBlurFirstTextfield);
        const handleBlurSecondTextfield = (event)=>handleBlur(event, onBlurSecondTextfield);
        const RangeComponent = /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/ _react.default.createElement(_RangeDatestyles.StyledRange, {
            size: size,
            ref: rangeRef,
            autoComplete: autoComplete,
            dividerIcon: dividerIcon,
            dividerVariant: dividerVariant,
            label: label,
            leftHelper: leftHelper,
            required: required,
            requiredIndicatorPlacement: requiredPlacement,
            hasRequiredIndicator: hasRequiredIndicator,
            disabled: disabled,
            readOnly: !disabled && readOnly,
            firstPlaceholder: firstPlaceholder,
            secondPlaceholder: secondPlaceholder,
            contentLeft: contentLeft,
            contentRight: contentRight,
            firstTextfieldTextBefore: firstTextfieldTextBefore,
            secondTextfieldTextBefore: secondTextfieldTextBefore,
            firstTextfieldTextAfter: firstTextfieldTextAfter,
            secondTextfieldTextAfter: secondTextfieldTextAfter,
            firstTextfieldContentLeft: firstTextfieldContentLeft,
            firstTextfieldContentRight: firstTextfieldContentRight,
            secondTextfieldContentLeft: secondTextfieldContentLeft,
            secondTextfieldContentRight: secondTextfieldContentRight,
            firstValue: inputFirstValue,
            secondValue: inputSecondValue,
            firstValueError: firstValueError,
            secondValueError: secondValueError,
            firstValueSuccess: firstValueSuccess,
            secondValueSuccess: secondValueSuccess,
            onChangeFirstValue: handleChangeFirstValue,
            onChangeSecondValue: handleChangeSecondValue,
            name: name,
            onSearchFirstValue: handleSearchFirstValue,
            onSearchSecondValue: handleSearchSecondValue,
            onFocusFirstTextfield: handleFocusFirstTextField,
            onFocusSecondTextfield: handleFocusSecondTextField,
            onBlurFirstTextfield: handleBlurFirstTextfield,
            onBlurSecondTextfield: handleBlurSecondTextfield,
            onKeyDown: onKeyDown,
            appearance: appearance,
            hasClearDivider: hasClearDivider,
            hintText: hintText,
            hintView: hintView,
            hintSize: hintSize,
            hintTrigger: hintTrigger,
            hintTargetIcon: hintTargetIcon,
            hintPlacement: hintPlacement,
            hintTargetPlacement: hintTargetPlacement,
            hintHasArrow: hintHasArrow,
            hintOffset: hintOffset,
            hintWidth: hintWidth,
            hintContentLeft: hintContentLeft
        }));
        (0, _react.useEffect)(()=>{
            setFirstInputRef(rangeRef.current?.firstTextField());
            setSecondInputRef(rangeRef.current?.secondTextField());
        }, [
            rangeRef.current
        ]);
        (0, _react.useLayoutEffect)(()=>{
            if (!startDateValue) {
                updateExternalFirstDate(defaultFirstDate);
            }
        }, [
            defaultFirstDate,
            format,
            lang
        ]);
        (0, _react.useLayoutEffect)(()=>{
            if (!endDateValue) {
                updateExternalSecondDate(defaultSecondDate);
            }
        }, [
            defaultSecondDate,
            format,
            lang
        ]);
        const RootWrapper = (0, _react.useCallback)(/*#__PURE__*/ (0, _react.forwardRef)(({ children, className: rootWrapperClassName, onClick }, rootWrapperRef)=>/*#__PURE__*/ _react.default.createElement(Root, {
                ref: rootWrapperRef,
                view: view,
                size: size,
                eventTooltipSize: eventTooltipOptions?.size,
                className: rootWrapperClassName,
                disabled: disabled,
                readOnly: !disabled && readOnly,
                onClick: onClick
            }, children)), [
            view,
            size,
            disabled,
            readOnly
        ]);
        return /*#__PURE__*/ _react.default.createElement(Root, {
            ref: rootRef,
            view: view,
            size: size,
            eventTooltipSize: eventTooltipOptions?.size,
            className: (0, _classnames.default)(_DatePickertokens.classes.datePickerRoot, className, {
                [_DatePickertokens.classes.datePickerstretched]: stretched
            }),
            disabled: disabled,
            readOnly: !disabled && readOnly,
            ...hintText && {
                hintView,
                hintSize
            },
            ...rest
        }, /*#__PURE__*/ _react.default.createElement(_RangeDatePopover.RangeDatePopover, {
            calendarValue: [
                calendarFirstValue,
                calendarSecondValue
            ],
            calendarFocusedDate: calendarFocusedDate,
            target: RangeComponent,
            opened: openedValue,
            includeEdgeDates: includeEdgeDates,
            eventTooltipOptions: eventTooltipOptions,
            eventList: eventList,
            disabledList: disabledList,
            eventMonthList: eventMonthList,
            disabledMonthList: disabledMonthList,
            eventQuarterList: eventQuarterList,
            disabledQuarterList: disabledQuarterList,
            eventYearList: eventYearList,
            disabledYearList: disabledYearList,
            min: min,
            max: max,
            renderFromDate: renderFromDate,
            frame: frame,
            usePortal: usePortal,
            zIndex: zIndex,
            placement: placement,
            closeOnOverlayClick: closeOnOverlayClick,
            closeOnEsc: closeOnEsc,
            offset: offset,
            stretched: stretched,
            calendarContainerWidth: calendarContainerWidth,
            calendarContainerHeight: calendarContainerHeight,
            type: type,
            onToggle: handleToggle,
            lang: lang,
            isDoubleCalendar: isDoubleCalendar,
            rootWrapper: RootWrapper,
            onChangeStartOfRange: handleChangeStartOfRange,
            onChangeValue: handleChangeCalendarValue,
            setIsInnerOpen: setIsInnerOpen,
            dateShortcuts: dateShortcuts,
            dateShortcutsPlacement: dateShortcutsPlacement,
            dateShortcutsWidth: dateShortcutsWidth,
            disableFlip: disableFlip,
            onShortcutDateSelect: handleShortcutDateSelect
        }), /*#__PURE__*/ _react.default.createElement(_DatePickerBasestyles.InputHidden, {
            name: name,
            type: "hidden",
            datatype: "datepicker-double",
            "data-datepicker": "from",
            value: inputFirstValue,
            ref: innerRefFirst,
            ..._utils.noop
        }), /*#__PURE__*/ _react.default.createElement(_DatePickerBasestyles.InputHidden, {
            name: name,
            type: "hidden",
            datatype: "datepicker-double",
            "data-datepicker": "to",
            value: inputSecondValue,
            ref: innerRefSecond,
            ..._utils.noop
        }));
    });
const datePickerRangeConfig = {
    name: 'DatePickerRange',
    tag: 'div',
    layout: datePickerRangeRoot,
    base: _RangeDatestyles.base,
    variations: {
        view: {
            css: _base1.base
        },
        size: {
            css: _base.base
        },
        eventTooltipSize: {
            css: _base4.base
        },
        hintView: {
            css: _base2.base
        },
        hintSize: {
            css: _base3.base
        },
        disabled: {
            css: _base5.base,
            attrs: true
        },
        readOnly: {
            css: _base6.base,
            attrs: true
        }
    },
    defaults: {
        size: 'm',
        view: 'default',
        eventTooltipSizeCSS: 'm'
    }
};
