"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 calendarDoubleConfig () {
        return calendarDoubleConfig;
    },
    get calendarDoubleRoot () {
        return calendarDoubleRoot;
    }
});
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
const _classnames = /*#__PURE__*/ _interop_require_default(require("classnames"));
const _hooks = require("../../../hooks");
const _utils = require("../utils");
const _hooks1 = require("../hooks");
const _ui = require("../ui");
const _reducer = require("../store/reducer");
const _types = require("../store/types");
const _CalendarBasestyles = require("../CalendarBase/CalendarBase.styles");
const _Calendartokens = require("../Calendar.tokens");
const _base = require("./variations/_view/base");
const _base1 = require("./variations/_size/base");
const _base2 = require("./variations/_tooltip-size/base");
const _CalendarDoublestyles = require("./CalendarDouble.styles");
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 calendarDoubleRoot = (Root)=>/*#__PURE__*/ (0, _react.forwardRef)(({ className, value: externalValue, focusedDate, min: minDate, max: maxDate, renderFromDate, includeEdgeDates, type = 'Days', eventTooltipOptions, eventList, disabledList, eventMonthList, disabledMonthList, eventQuarterList, disabledQuarterList, eventYearList, disabledYearList, locale = 'ru', stretched, onChangeValue, ...rest }, outerRootRef)=>{
        const [firstValue, secondValue] = (0, _react.useMemo)(()=>Array.isArray(externalValue) ? externalValue : [
                externalValue
            ], [
            externalValue
        ]);
        const value = focusedDate || secondValue || firstValue;
        const isSingleMode = !Array.isArray(externalValue);
        const [internalValue, setInternalValue] = (0, _react.useState)(externalValue);
        const [prevExternalForSelection, setPrevExternalForSelection] = (0, _react.useState)(externalValue);
        if ((0, _utils.isValueUpdate)(externalValue, prevExternalForSelection)) {
            setInternalValue(externalValue);
            setPrevExternalForSelection(externalValue);
        }
        const [hoveredItem, setHoveredItem] = (0, _react.useState)();
        const [prevType, setPrevType] = (0, _react.useState)(type);
        const [prevValue, setPrevValue] = (0, _react.useState)(value);
        const [outOfRangeKey, setOutOfRangeKey] = (0, _react.useState)(0);
        const [eventNodes, setEventNodes] = (0, _react.useState)([]);
        const eventTooltipTargetRef = (0, _react.useRef)(null);
        const rootRef = (0, _react.useRef)(null);
        const innerRootRef = (0, _hooks.useForkRef)(rootRef, outerRootRef);
        const min = minDate && new Date(minDate);
        const max = maxDate && new Date(maxDate);
        if (min) {
            min.setHours(0, 0, 0, 0);
        }
        if (max) {
            max.setHours(23, 59, 59, 999);
        }
        const [state, dispatch] = (0, _react.useReducer)(_reducer.reducer, (0, _reducer.getInitialState)(value, min, renderFromDate, type, true));
        const { date, calendarState, startYear, size } = state;
        const [firstDate, setFirstDate] = (0, _react.useState)(date);
        const [secondDate, setSecondDate] = (0, _react.useState)(date);
        const { handleNext, handlePrev } = (0, _hooks1.useCalendarNavigation)({
            calendarState,
            date,
            dispatch
        });
        const [selectIndexes, onKeyDown, onSelectIndexes, outerRefs, isOutOfRange] = (0, _hooks1.useKeyNavigation)({
            isDouble: true,
            size,
            calendarState,
            onNext: handleNext,
            onPrev: handlePrev
        });
        const handleOnChangeValue = (0, _react.useCallback)((newDay, dateInfo)=>{
            if (isSingleMode && externalValue == null) {
                setInternalValue(newDay);
            }
            onChangeValue?.(newDay, dateInfo);
        }, [
            onChangeValue,
            isSingleMode,
            externalValue
        ]);
        const { handleOnChangeDay, handleOnChangeMonth, handleOnChangeQuarter, handleOnChangeYear, handleUpdateCalendarState } = (0, _hooks1.useCalendarDateChange)({
            type,
            onChangeValue: handleOnChangeValue,
            onSelectIndexes,
            dispatch
        });
        const updateSecondDate = ()=>{
            if (calendarState === _types.CalendarState.Days) {
                const [nextYear, nextMonthIndex] = (0, _utils.getNextDate)(date.year, date.monthIndex);
                setSecondDate({
                    year: nextYear,
                    monthIndex: nextMonthIndex,
                    day: date.day
                });
            }
            if (calendarState === _types.CalendarState.Months || calendarState === _types.CalendarState.Quarters) {
                setSecondDate({
                    year: date.year + 1,
                    monthIndex: date.monthIndex,
                    day: date.day
                });
            }
            if (calendarState === _types.CalendarState.Years) {
                setSecondDate({
                    year: startYear + _utils.YEAR_RENDER_COUNT,
                    monthIndex: date.monthIndex,
                    day: date.day
                });
            }
        };
        const getBoundaryDates = ()=>{
            // NOTE: Если установить индекс дня равным "0", то берется последнее число предыдущего месяца
            if (calendarState === _types.CalendarState.Days) {
                return [
                    new Date(firstDate.year, firstDate.monthIndex, 1),
                    new Date(secondDate.year, secondDate.monthIndex + 1, 0)
                ];
            }
            if (calendarState === _types.CalendarState.Months || calendarState === _types.CalendarState.Quarters) {
                return [
                    new Date(firstDate.year, 0),
                    new Date(secondDate.year, 12, 0)
                ];
            }
            const endVisibleYear = startYear + _utils.YEAR_RENDER_COUNT * 2 - 1;
            return [
                new Date(startYear, 0),
                new Date(endVisibleYear, 11)
            ];
        };
        // Изменяем ключ каждый раз как пытаемся перейти на даты которые находятся за пределами min/max ограничений.
        // Это необходимо для того чтобы screen-reader корректно озвучивал уведомление aria-live="assertive"
        // о том что нет доступных дат
        const handleKeyDown = (0, _react.useCallback)((event)=>{
            setOutOfRangeKey((previousState)=>Number(!previousState));
            onKeyDown(event);
        }, [
            onKeyDown
        ]);
        const handleTriggerEventTooltip = (structureRef, events)=>{
            if (structureRef?.current && events?.length) {
                eventTooltipTargetRef.current = structureRef.current;
                setEventNodes(events);
            } else if (eventTooltipTargetRef.current !== null) {
                eventTooltipTargetRef.current = null;
                setEventNodes([]);
            }
        };
        const tooltipContent = ()=>{
            const TooltipBodyWrapper = eventTooltipOptions?.bodyWrapper;
            if (!TooltipBodyWrapper) {
                return eventNodes;
            }
            return /*#__PURE__*/ _react.default.createElement(TooltipBodyWrapper, null, eventNodes);
        };
        (0, _react.useEffect)(()=>{
            if (prevType !== calendarState) {
                dispatch({
                    type: _types.ActionType.UPDATE_CALENDAR_STATE,
                    payload: {
                        calendarState,
                        size: _reducer.sizeMap[calendarState].double
                    }
                });
                setPrevType(calendarState);
            }
        }, [
            calendarState
        ]);
        (0, _react.useEffect)(()=>{
            if (prevType !== type) {
                dispatch({
                    type: _types.ActionType.UPDATE_CALENDAR_STATE,
                    payload: {
                        calendarState: type,
                        size: _reducer.sizeMap[type].double
                    }
                });
                setPrevType(type);
            }
        }, [
            type
        ]);
        (0, _react.useEffect)(()=>{
            if (value && prevValue && (0, _utils.isValueUpdate)(value, prevValue) || value && !prevValue) {
                const [minVisibleDate, maxVisibleDate] = getBoundaryDates();
                if (focusedDate || value > maxVisibleDate || value < minVisibleDate) {
                    dispatch({
                        type: _types.ActionType.UPDATE_DATE,
                        payload: {
                            value
                        }
                    });
                }
            }
            if (!value && !prevValue) {
                dispatch({
                    type: _types.ActionType.UPDATE_DATE,
                    payload: {
                        value: renderFromDate || min || new Date()
                    }
                });
            }
            setPrevValue(value);
        }, [
            value
        ]);
        (0, _react.useEffect)(()=>{
            setFirstDate(date);
            updateSecondDate();
        }, [
            date,
            calendarState
        ]);
        return /*#__PURE__*/ _react.default.createElement(Root, {
            ref: innerRootRef,
            className: (0, _classnames.default)(className, {
                [_Calendartokens.classes.stretched]: stretched
            }),
            "aria-label": _utils.I18N.selectDate[locale],
            eventTooltipSize: eventTooltipOptions?.size,
            ...rest
        }, isOutOfRange && /*#__PURE__*/ _react.default.createElement(_CalendarBasestyles.IsOutOfRange, {
            key: outOfRangeKey,
            "aria-atomic": "true",
            role: "alert",
            "aria-live": "assertive",
            "aria-relevant": "additions"
        }, "Далее нет доступных дат."), /*#__PURE__*/ _react.default.createElement(_ui.CalendarHeader, {
            isDouble: true,
            size: rest.size,
            firstDate: firstDate,
            secondDate: secondDate,
            startYear: startYear,
            type: calendarState,
            onPrev: handlePrev,
            onNext: handleNext,
            onUpdateCalendarState: handleUpdateCalendarState,
            locale: locale
        }), /*#__PURE__*/ _react.default.createElement(_CalendarDoublestyles.StyledWrapper, null, calendarState === _types.CalendarState.Days && /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/ _react.default.createElement(_ui.CalendarDays, {
            value: internalValue,
            date: firstDate,
            min: min,
            max: max,
            eventList: eventList,
            disabledList: disabledList,
            includeEdgeDates: includeEdgeDates,
            hoveredDay: hoveredItem,
            selectIndexes: selectIndexes,
            onChangeDay: handleOnChangeDay,
            onHoverDay: setHoveredItem,
            onSetSelected: onSelectIndexes,
            onTriggerEventTooltip: handleTriggerEventTooltip,
            onKeyDown: handleKeyDown,
            outerRefs: outerRefs,
            locale: locale,
            isDouble: true
        }), /*#__PURE__*/ _react.default.createElement(_CalendarDoublestyles.StyledSeparator, null), /*#__PURE__*/ _react.default.createElement(_ui.CalendarDays, {
            value: internalValue,
            date: secondDate,
            min: min,
            max: max,
            eventList: eventList,
            disabledList: disabledList,
            includeEdgeDates: includeEdgeDates,
            hoveredDay: hoveredItem,
            selectIndexes: selectIndexes,
            onChangeDay: handleOnChangeDay,
            onHoverDay: setHoveredItem,
            onSetSelected: onSelectIndexes,
            onTriggerEventTooltip: handleTriggerEventTooltip,
            onKeyDown: handleKeyDown,
            outerRefs: outerRefs,
            locale: locale,
            isDouble: true,
            isSecond: true
        })), calendarState === _types.CalendarState.Months && /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/ _react.default.createElement(_ui.CalendarMonths, {
            value: internalValue,
            date: firstDate,
            min: min,
            max: max,
            eventList: eventMonthList,
            disabledList: disabledMonthList,
            hoveredMonth: hoveredItem,
            selectIndexes: selectIndexes,
            onChangeMonth: handleOnChangeMonth,
            onSetSelected: onSelectIndexes,
            onHoverMonth: setHoveredItem,
            onTriggerEventTooltip: handleTriggerEventTooltip,
            onKeyDown: handleKeyDown,
            outerRefs: outerRefs,
            locale: locale,
            isDouble: true
        }), /*#__PURE__*/ _react.default.createElement(_CalendarDoublestyles.StyledSeparator, null), /*#__PURE__*/ _react.default.createElement(_ui.CalendarMonths, {
            value: internalValue,
            date: secondDate,
            min: min,
            max: max,
            eventList: eventMonthList,
            disabledList: disabledMonthList,
            hoveredMonth: hoveredItem,
            selectIndexes: selectIndexes,
            onChangeMonth: handleOnChangeMonth,
            onSetSelected: onSelectIndexes,
            onHoverMonth: setHoveredItem,
            onTriggerEventTooltip: handleTriggerEventTooltip,
            onKeyDown: handleKeyDown,
            outerRefs: outerRefs,
            locale: locale,
            isDouble: true,
            isSecond: true
        })), calendarState === _types.CalendarState.Quarters && /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/ _react.default.createElement(_ui.CalendarQuarters, {
            value: internalValue,
            date: firstDate,
            min: min,
            max: max,
            eventList: eventQuarterList,
            disabledList: disabledQuarterList,
            hoveredQuarter: hoveredItem,
            selectIndexes: selectIndexes,
            onChangeQuarter: handleOnChangeQuarter,
            onSetSelected: onSelectIndexes,
            onHoverQuarter: setHoveredItem,
            onTriggerEventTooltip: handleTriggerEventTooltip,
            onKeyDown: handleKeyDown,
            outerRefs: outerRefs,
            isDouble: true
        }), /*#__PURE__*/ _react.default.createElement(_CalendarDoublestyles.StyledSeparator, null), /*#__PURE__*/ _react.default.createElement(_ui.CalendarQuarters, {
            value: internalValue,
            date: secondDate,
            min: min,
            max: max,
            eventList: eventQuarterList,
            disabledList: disabledQuarterList,
            hoveredQuarter: hoveredItem,
            selectIndexes: selectIndexes,
            onChangeQuarter: handleOnChangeQuarter,
            onSetSelected: onSelectIndexes,
            onHoverQuarter: setHoveredItem,
            onTriggerEventTooltip: handleTriggerEventTooltip,
            onKeyDown: handleKeyDown,
            outerRefs: outerRefs,
            isDouble: true,
            isSecond: true
        })), calendarState === _types.CalendarState.Years && /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/ _react.default.createElement(_ui.CalendarYears, {
            value: internalValue,
            date: firstDate,
            startYear: startYear,
            selectIndexes: selectIndexes,
            min: min,
            max: max,
            eventList: eventYearList,
            disabledList: disabledYearList,
            hoveredYear: hoveredItem,
            onChangeYear: handleOnChangeYear,
            onSetSelected: onSelectIndexes,
            onHoverYear: setHoveredItem,
            onTriggerEventTooltip: handleTriggerEventTooltip,
            onKeyDown: handleKeyDown,
            outerRefs: outerRefs,
            isDouble: true
        }), /*#__PURE__*/ _react.default.createElement(_CalendarDoublestyles.StyledSeparator, null), /*#__PURE__*/ _react.default.createElement(_ui.CalendarYears, {
            value: internalValue,
            date: secondDate,
            startYear: startYear + _utils.YEAR_RENDER_COUNT,
            selectIndexes: selectIndexes,
            min: min,
            max: max,
            eventList: eventYearList,
            disabledList: disabledYearList,
            hoveredYear: hoveredItem,
            onChangeYear: handleOnChangeYear,
            onSetSelected: onSelectIndexes,
            onHoverYear: setHoveredItem,
            onTriggerEventTooltip: handleTriggerEventTooltip,
            onKeyDown: handleKeyDown,
            outerRefs: outerRefs,
            isDouble: true,
            isSecond: true
        }))), eventTooltipTargetRef.current && eventNodes?.length && /*#__PURE__*/ _react.default.createElement(_ui.EventTooltip, {
            opened: Boolean(eventNodes?.length),
            target: eventTooltipTargetRef,
            frame: rootRef,
            text: tooltipContent(),
            trigger: "hover",
            ...eventTooltipOptions
        }));
    });
const calendarDoubleConfig = {
    name: 'CalendarDouble',
    tag: 'div',
    layout: calendarDoubleRoot,
    base: _CalendarDoublestyles.StyledCalendar,
    variations: {
        view: {
            css: _base.base
        },
        size: {
            css: _base1.base
        },
        eventTooltipSize: {
            css: _base2.base
        }
    },
    defaults: {
        view: 'primary',
        size: 'm',
        eventTooltipSizeCSS: 'm'
    }
};
