"use strict";
/*
 * Copyright 2023 Palantir Technologies, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.NonContiguousDayRangePicker = void 0;
var tslib_1 = require("tslib");
var React = tslib_1.__importStar(require("react"));
var react_day_picker_1 = require("react-day-picker");
var core_1 = require("@blueprintjs/core");
var datetime_1 = require("@blueprintjs/datetime");
var classes_1 = require("../../classes");
var reactDayPickerUtils_1 = require("../../common/reactDayPickerUtils");
var datePicker3Caption_1 = require("../react-day-picker/datePicker3Caption");
/**
 * Date range picker with two calendars which can move independently of each other.
 */
var NonContiguousDayRangePicker = function (_a) {
    var allowSingleDayRange = _a.allowSingleDayRange, boundaryToModify = _a.boundaryToModify, dayPickerEventHandlers = _a.dayPickerEventHandlers, dayPickerProps = _a.dayPickerProps, initialMonthAndYear = _a.initialMonthAndYear, locale = _a.locale, maxDate = _a.maxDate, minDate = _a.minDate, onRangeSelect = _a.onRangeSelect, value = _a.value;
    var _b = useNonContiguousCalendarViews(initialMonthAndYear, value, dayPickerProps === null || dayPickerProps === void 0 ? void 0 : dayPickerProps.onMonthChange, minDate, maxDate), displayMonths = _b.displayMonths, handleLeftMonthChange = _b.handleLeftMonthChange, handleRightMonthChange = _b.handleRightMonthChange;
    var handleDaySelect = React.useCallback(function (range, selectedDay, activeModifiers, e) {
        var _a;
        (_a = dayPickerProps === null || dayPickerProps === void 0 ? void 0 : dayPickerProps.onSelect) === null || _a === void 0 ? void 0 : _a.call(dayPickerProps, range, selectedDay, activeModifiers, e);
        if (activeModifiers.disabled) {
            return;
        }
        var _b = datetime_1.DateRangeSelectionStrategy.getNextState(value, selectedDay, allowSingleDayRange, boundaryToModify), nextValue = _b.dateRange, boundary = _b.boundary;
        onRangeSelect(nextValue, selectedDay, boundary);
    }, [allowSingleDayRange, boundaryToModify, dayPickerProps, onRangeSelect, value]);
    // props applied to both the left and right calendars
    var commonDayPickerProps = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({ locale: locale, mode: "range", showOutsideDays: true }, dayPickerProps), dayPickerEventHandlers), { components: tslib_1.__assign({ Caption: datePicker3Caption_1.DatePicker3Caption }, dayPickerProps === null || dayPickerProps === void 0 ? void 0 : dayPickerProps.components), onSelect: handleDaySelect, selected: (0, reactDayPickerUtils_1.dateRangeToDayPickerRange)(value) });
    return (React.createElement("div", { className: classes_1.Classes.DATERANGEPICKER_CALENDARS },
        React.createElement(react_day_picker_1.DayPicker, tslib_1.__assign({ key: "left" }, commonDayPickerProps, { fromDate: minDate, month: displayMonths.left.getFullDate(), numberOfMonths: 1, onMonthChange: handleLeftMonthChange, toMonth: datetime_1.DateUtils.getDatePreviousMonth(maxDate) })),
        React.createElement(react_day_picker_1.DayPicker, tslib_1.__assign({ key: "right" }, commonDayPickerProps, { fromMonth: datetime_1.DateUtils.getDateNextMonth(minDate), month: displayMonths.right.getFullDate(), numberOfMonths: 1, onMonthChange: handleRightMonthChange, toDate: maxDate }))));
};
exports.NonContiguousDayRangePicker = NonContiguousDayRangePicker;
exports.NonContiguousDayRangePicker.displayName = "".concat(core_1.DISPLAYNAME_PREFIX, ".NonContiguousDayRangePicker");
/**
 * State management and navigation event handlers for two (left and right) non-contiguous calendar views.
 *
 * @param initialMonthAndYear initial month and year to display in the left calendar
 * @param selectedRange currently selected date range
 * @param userOnMonthChange custom `dayPickerProps.onMonthChange` handler supplied by users of `DateRangePicker3`
 */
function useNonContiguousCalendarViews(initialMonthAndYear, selectedRange, userOnMonthChange, minDate, maxDate) {
    // show the selected end date's encompassing month in the right view if
    // the calendars don't have to be contiguous.
    // if left view and right view months are the same, show next month in the right view.
    var _a = React.useState({
        left: initialMonthAndYear,
        right: getInitialRightView(selectedRange[1], initialMonthAndYear),
    }), views = _a[0], setViews = _a[1];
    React.useEffect(function () {
        if (selectedRange == null) {
            return;
        }
        setViews(function (_a) {
            var left = _a.left, right = _a.right;
            var newLeftView = left.clone();
            var newRightView = right.clone();
            var nextValueStartView = datetime_1.MonthAndYear.fromDate(selectedRange[0]);
            var nextValueEndView = datetime_1.MonthAndYear.fromDate(selectedRange[1]);
            if (nextValueStartView == null && nextValueEndView != null) {
                // Only end date selected.
                // If the newly selected end date isn't in either of the displayed months, then
                //   - set the right DayPicker to the month of the selected end date
                //   - ensure the left DayPicker is before the right, changing if needed
                if (!nextValueEndView.isSame(newLeftView) && !nextValueEndView.isSame(newRightView)) {
                    newRightView = nextValueEndView;
                    if (!newLeftView.isBefore(newRightView)) {
                        newLeftView = newRightView.getPreviousMonth();
                    }
                }
            }
            else if (nextValueStartView != null && nextValueEndView == null) {
                // Only start date selected.
                // If the newly selected start date isn't in either of the displayed months, then
                //   - set the left DayPicker to the month of the selected start date
                //   - ensure the right DayPicker is before the left, changing if needed
                if (!nextValueStartView.isSame(newLeftView) && !nextValueStartView.isSame(newRightView)) {
                    newLeftView = nextValueStartView;
                    if (!newRightView.isAfter(newLeftView)) {
                        newRightView = newLeftView.getNextMonth();
                    }
                }
            }
            else if (nextValueStartView != null && nextValueEndView != null) {
                // Both start and end date months are identical
                // If the selected month isn't in either of the displayed months, then
                //   - set the left DayPicker to be the selected month
                //   - set the right DayPicker to +1
                if (nextValueStartView.isSame(nextValueEndView)) {
                    if (newLeftView.isSame(nextValueStartView) || newRightView.isSame(nextValueStartView)) {
                        // do nothing
                    }
                    else {
                        newLeftView = nextValueStartView;
                        newRightView = nextValueStartView.getNextMonth();
                    }
                }
                else {
                    // Different start and end date months, adjust display months.
                    if (!newLeftView.isSame(nextValueStartView)) {
                        newLeftView = nextValueStartView;
                        newRightView = nextValueStartView.getNextMonth();
                    }
                    if (!newRightView.isSame(nextValueEndView)) {
                        newRightView = nextValueEndView;
                    }
                }
            }
            return { left: newLeftView, right: newRightView };
        });
    }, [setViews, selectedRange]);
    var handleLeftMonthChange = React.useCallback(function (newDate) {
        var newLeftView = datetime_1.MonthAndYear.fromDate(newDate);
        setViews(function (_a) {
            var _b;
            var right = _a.right;
            var newRightView = right.clone();
            if (!newLeftView.isBefore(newRightView)) {
                newRightView = newLeftView.getNextMonth();
            }
            _b = getBoundedViews(newLeftView, newRightView, minDate, maxDate), newLeftView = _b[0], newRightView = _b[1];
            userOnMonthChange === null || userOnMonthChange === void 0 ? void 0 : userOnMonthChange(newLeftView.getFullDate());
            return { left: newLeftView, right: newRightView };
        });
    }, [minDate, maxDate, setViews, userOnMonthChange]);
    var handleRightMonthChange = React.useCallback(function (newDate) {
        var newRightView = datetime_1.MonthAndYear.fromDate(newDate);
        setViews(function (_a) {
            var _b;
            var left = _a.left;
            var newLeftView = left.clone();
            if (!newRightView.isAfter(newLeftView)) {
                newLeftView = newRightView.getPreviousMonth();
            }
            _b = getBoundedViews(newLeftView, newRightView, minDate, maxDate), newLeftView = _b[0], newRightView = _b[1];
            userOnMonthChange === null || userOnMonthChange === void 0 ? void 0 : userOnMonthChange(newRightView.getFullDate());
            return { left: newLeftView, right: newRightView };
        });
    }, [minDate, maxDate, setViews, userOnMonthChange]);
    return {
        displayMonths: views,
        handleLeftMonthChange: handleLeftMonthChange,
        handleRightMonthChange: handleRightMonthChange,
    };
}
function getBoundedViews(leftView, rightView, minDate, maxDate) {
    var minView = datetime_1.MonthAndYear.fromDate(minDate !== null && minDate !== void 0 ? minDate : null);
    if (minView != null && leftView.isBefore(minView)) {
        return [minView, minView.getNextMonth()];
    }
    var maxView = datetime_1.MonthAndYear.fromDate(maxDate !== null && maxDate !== void 0 ? maxDate : null);
    if (maxView != null && rightView.isAfter(maxView)) {
        return [maxView.getPreviousMonth(), maxView];
    }
    return [leftView, rightView];
}
function getInitialRightView(selectedRangeEnd, leftView) {
    var rightView = datetime_1.MonthAndYear.fromDate(selectedRangeEnd);
    if (rightView === undefined || rightView.isSameMonth(leftView)) {
        return leftView.getNextMonth();
    }
    return rightView;
}
//# sourceMappingURL=nonContiguousDayRangePicker.js.map