import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useEffect, useRef, useState } from 'react';
import Box from '../box';
import Button, { LineButton } from '../button';
import Calendar, { maxDateTimestamp, minDateTimestamp } from '../calendar';
import { omitThemingProps, useStyleConfig, vui } from '../core';
import Popover from '../popover';
import { cs } from '../utils';
import { DateInput } from './dateInput';
/** Select or input a date. */
export const DatePicker = vui((props, ref) => {
    const { autoOpened, boundaries, popupPosition, placement, selectedDate: selectedDateProps, showClearButton, slotBottom, slotTop, onSelected, children, className, ...rest } = omitThemingProps(props);
    const styles = useStyleConfig('DatePicker', props);
    const [selectedDate, setSelectedDate] = useState(selectedDateProps);
    const [isOpen, setIsOpen] = useState(!selectedDate && autoOpened);
    const [isInvalidInputDate, setIsInvalidInputDate] = useState(true);
    const [isInvalidSelectedDate, setIsInvalidSelectedDate] = useState(!selectedDate);
    const initialDateRef = useRef(selectedDateProps);
    const isClearButtonVisible = showClearButton && initialDateRef.current;
    const isStartDateInRange = (date) => !!boundaries?.startDate && !!date ? date.getTime() - boundaries.startDate.getTime() >= 0 : true;
    const isEndDateInRange = (date) => !!boundaries?.endDate && !!date ? date.getTime() - boundaries.endDate.getTime() <= 0 : true;
    const isValidDateRange = (date) => {
        const minDateTime = new Date(minDateTimestamp);
        const maxDateTime = new Date(maxDateTimestamp);
        return date >= minDateTime || date <= maxDateTime;
    };
    useEffect(() => {
        if (!isOpen) {
            setSelectedDate(selectedDateProps);
            initialDateRef.current = selectedDateProps;
        }
    }, [isOpen, selectedDateProps]);
    useEffect(() => {
        setIsInvalidSelectedDate((selectedDate && !isStartDateInRange(selectedDate)) ||
            (selectedDate && !isEndDateInRange(selectedDate)) ||
            (selectedDate && !isValidDateRange(selectedDate)) ||
            !selectedDate);
    }, [selectedDate]);
    const onApplyDates = (date) => {
        onSelected?.(date);
        initialDateRef.current = date;
        setIsOpen(false);
    };
    const onClear = () => {
        onClose();
        onSelected?.(undefined);
    };
    const onClose = () => {
        setSelectedDate(undefined);
        setIsOpen(false);
    };
    const onToggle = () => {
        if (isOpen)
            onClose();
        setIsOpen(!isOpen);
    };
    const selectDate = (range) => setSelectedDate(range?.startDate);
    const onDateInputValidate = (date) => {
        const minDateTime = new Date(minDateTimestamp);
        const maxDateTime = new Date(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?.startDate && !isStartDateInRange(date), 'Invalid date'],
                [!!boundaries?.endDate && !isEndDateInRange(date), 'Invalid date'],
            ];
            const [validateErrorPair] = conditions.filter(([result]) => result);
            if (validateErrorPair) {
                const [_, message] = validateErrorPair;
                setIsInvalidInputDate(true);
                return message;
            }
        }
        return '';
    };
    return (_jsx(Box, { className: cs('vui-datePicker', className), position: "relative", ref: ref, ...styles, ...rest, children: _jsxs(Popover, { isOpen: isOpen, onClose: () => setIsOpen(false), placement: placement ? placement : popupPosition === 'right' ? 'bottom-end' : undefined, children: [_jsx(Popover.Trigger, { as: Box, onClick: onToggle, children: children }), _jsxs(Popover.Content, { column: true, children: [!!slotTop && _jsx(Box, { px: 2, children: slotTop }), _jsx(Box, { display: "block", mb: 0, mt: 2, mx: 2, children: _jsx(DateInput, { autoFocus: true, initialDate: selectedDate, onChange: newDate => setSelectedDate(newDate), onValidate: onDateInputValidate, setValidateStatus: inValid => setIsInvalidInputDate(!inValid) }) }), _jsx(Box, { mx: 2, my: 1, children: _jsx(Calendar, { boundaries: boundaries ?? { startDate: undefined, endDate: undefined }, fixedNumberOfWeeks: true, fontWeight: 500, minH: 310, mode: "exact", onSelectDates: range => selectDate(range), selectedDates: { startDate: selectedDate, endDate: undefined }, w: "100%" }) }), _jsx(Box, { overflow: "unset", pt: 0.5, children: _jsxs(Box, { alignItems: "center", flex: 1, ml: "auto", pb: 2, px: 2, children: [isClearButtonVisible && (_jsx(LineButton, { flex: 1, onClick: onClear, size: "md", children: "Clear" })), _jsx(Button, { disabled: isInvalidSelectedDate || isInvalidInputDate, flex: 1, ml: isClearButtonVisible ? 1 : 0, onClick: () => onApplyDates(selectedDate), size: "md", children: "Apply" })] }) }), !!slotBottom && _jsx(Box, { px: 2, children: slotBottom })] })] }) }));
});
DatePicker.displayName = 'DatePicker';
export default DatePicker;
//# sourceMappingURL=datePicker.js.map