"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DatePicker = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const box_1 = __importDefault(require("../box"));
const button_1 = __importStar(require("../button"));
const calendar_1 = __importStar(require("../calendar"));
const core_1 = require("../core");
const popover_1 = __importDefault(require("../popover"));
const utils_1 = require("../utils");
const dateInput_1 = require("./dateInput");
/** Select or input a date. */
exports.DatePicker = (0, core_1.vui)((props, ref) => {
    const _a = (0, core_1.omitThemingProps)(props), { autoOpened, boundaries, popupPosition, placement, selectedDate: selectedDateProps, showClearButton, slotBottom, slotTop, onSelected, children, className } = _a, rest = __rest(_a, ["autoOpened", "boundaries", "popupPosition", "placement", "selectedDate", "showClearButton", "slotBottom", "slotTop", "onSelected", "children", "className"]);
    const styles = (0, core_1.useStyleConfig)('DatePicker', props);
    const [selectedDate, setSelectedDate] = (0, react_1.useState)(selectedDateProps);
    const [isOpen, setIsOpen] = (0, react_1.useState)(!selectedDate && autoOpened);
    const [isInvalidInputDate, setIsInvalidInputDate] = (0, react_1.useState)(true);
    const [isInvalidSelectedDate, setIsInvalidSelectedDate] = (0, react_1.useState)(!selectedDate);
    const initialDateRef = (0, react_1.useRef)(selectedDateProps);
    const isClearButtonVisible = showClearButton && initialDateRef.current;
    const isStartDateInRange = (date) => !!(boundaries === null || boundaries === void 0 ? void 0 : boundaries.startDate) && !!date ? date.getTime() - boundaries.startDate.getTime() >= 0 : true;
    const isEndDateInRange = (date) => !!(boundaries === null || boundaries === void 0 ? void 0 : boundaries.endDate) && !!date ? date.getTime() - boundaries.endDate.getTime() <= 0 : true;
    const isValidDateRange = (date) => {
        const minDateTime = new Date(calendar_1.minDateTimestamp);
        const maxDateTime = new Date(calendar_1.maxDateTimestamp);
        return date >= minDateTime || date <= maxDateTime;
    };
    (0, react_1.useEffect)(() => {
        if (!isOpen) {
            setSelectedDate(selectedDateProps);
            initialDateRef.current = selectedDateProps;
        }
    }, [isOpen, selectedDateProps]);
    (0, react_1.useEffect)(() => {
        setIsInvalidSelectedDate((selectedDate && !isStartDateInRange(selectedDate)) ||
            (selectedDate && !isEndDateInRange(selectedDate)) ||
            (selectedDate && !isValidDateRange(selectedDate)) ||
            !selectedDate);
    }, [selectedDate]);
    const onApplyDates = (date) => {
        onSelected === null || onSelected === void 0 ? void 0 : onSelected(date);
        initialDateRef.current = date;
        setIsOpen(false);
    };
    const onClear = () => {
        onClose();
        onSelected === null || onSelected === void 0 ? void 0 : onSelected(undefined);
    };
    const onClose = () => {
        setSelectedDate(undefined);
        setIsOpen(false);
    };
    const onToggle = () => {
        if (isOpen)
            onClose();
        setIsOpen(!isOpen);
    };
    const selectDate = (range) => setSelectedDate(range === null || range === void 0 ? void 0 : range.startDate);
    const onDateInputValidate = (date) => {
        const minDateTime = new Date(calendar_1.minDateTimestamp);
        const maxDateTime = new Date(calendar_1.maxDateTimestamp);
        if (date) {
            const conditions = [
                [isNaN(date.getTime()), 'Supported format is YYYY-MM-DD'],
                [date < minDateTime, 'Invalid date, the minimum date time is 1753-01-02'],
                [date > maxDateTime, 'Invalid date, the maximum date time is 9000-12-31'],
                [!!(boundaries === null || boundaries === void 0 ? void 0 : boundaries.startDate) && !isStartDateInRange(date), 'Invalid date'],
                [!!(boundaries === null || boundaries === void 0 ? void 0 : boundaries.endDate) && !isEndDateInRange(date), 'Invalid date'],
            ];
            const [validateErrorPair] = conditions.filter(([result]) => result);
            if (validateErrorPair) {
                const [_, message] = validateErrorPair;
                setIsInvalidInputDate(true);
                return message;
            }
        }
        return '';
    };
    return ((0, jsx_runtime_1.jsx)(box_1.default, Object.assign({ className: (0, utils_1.cs)('vui-datePicker', className), position: "relative", ref: ref }, styles, rest, { children: (0, jsx_runtime_1.jsxs)(popover_1.default, { isOpen: isOpen, onClose: () => setIsOpen(false), placement: placement ? placement : popupPosition === 'right' ? 'bottom-end' : undefined, children: [(0, jsx_runtime_1.jsx)(popover_1.default.Trigger, { as: box_1.default, onClick: onToggle, children: children }), (0, jsx_runtime_1.jsxs)(popover_1.default.Content, { column: true, children: [!!slotTop && (0, jsx_runtime_1.jsx)(box_1.default, { px: 2, children: slotTop }), (0, jsx_runtime_1.jsx)(box_1.default, { display: "block", mb: 0, mt: 2, mx: 2, children: (0, jsx_runtime_1.jsx)(dateInput_1.DateInput, { autoFocus: true, initialDate: selectedDate, onChange: newDate => setSelectedDate(newDate), onValidate: onDateInputValidate, setValidateStatus: inValid => setIsInvalidInputDate(!inValid) }) }), (0, jsx_runtime_1.jsx)(box_1.default, { mx: 2, my: 1, children: (0, jsx_runtime_1.jsx)(calendar_1.default, { boundaries: boundaries !== null && boundaries !== void 0 ? boundaries : { startDate: undefined, endDate: undefined }, fixedNumberOfWeeks: true, fontWeight: 500, minH: 310, mode: "exact", onSelectDates: range => selectDate(range), selectedDates: { startDate: selectedDate, endDate: undefined }, w: "100%" }) }), (0, jsx_runtime_1.jsx)(box_1.default, { overflow: "unset", pt: 0.5, children: (0, jsx_runtime_1.jsxs)(box_1.default, { alignItems: "center", flex: 1, ml: "auto", pb: 2, px: 2, children: [isClearButtonVisible && ((0, jsx_runtime_1.jsx)(button_1.LineButton, { flex: 1, onClick: onClear, size: "md", children: "Clear" })), (0, jsx_runtime_1.jsx)(button_1.default, { disabled: isInvalidSelectedDate || isInvalidInputDate, flex: 1, ml: isClearButtonVisible ? 1 : 0, onClick: () => onApplyDates(selectedDate), size: "md", children: "Apply" })] }) }), !!slotBottom && (0, jsx_runtime_1.jsx)(box_1.default, { px: 2, children: slotBottom })] })] }) })));
});
exports.DatePicker.displayName = 'DatePicker';
exports.default = exports.DatePicker;
//# sourceMappingURL=datePicker.js.map