"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Datepicker = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const OverlayTrigger_1 = tslib_1.__importDefault(require("../OverlayTrigger"));
const react_1 = require("react");
const useProperty_1 = tslib_1.__importDefault(require("../utils/useProperty"));
const FieldWrap_1 = tslib_1.__importDefault(require("../FieldWrap"));
const SimpleButton_1 = tslib_1.__importDefault(require("../SimpleButton"));
const rebass_1 = require("rebass");
const FormatHelper_1 = require("../../Utilities/Helpers/FormatHelper");
const Caption_1 = require("./Caption");
const CaptionLabel_1 = require("./CaptionLabel");
const DatepickerContext_1 = require("./DatepickerContext");
const addDays_1 = tslib_1.__importDefault(require("date-fns/addDays"));
const addBusinessDays_1 = tslib_1.__importDefault(require("date-fns/addBusinessDays"));
const react_day_picker_1 = require("react-day-picker");
const AdaptableDateInlineInput_1 = require("../../View/Components/AdaptableInput/AdaptableDateInlineInput");
const date_fns_1 = require("date-fns");
const DatepickerOverlay = ({ onHide, children, onKeyDown, onMouseDown, }) => {
    const domRef = React.useRef(null);
    React.useEffect(() => {
        var _a;
        (_a = domRef.current) === null || _a === void 0 ? void 0 : _a.focus();
    }, []);
    return (React.createElement("div", { className: "ab-Datepicker-Overlay", ref: domRef, tabIndex: -1, onKeyDown: onKeyDown, onMouseDown: onMouseDown, onBlur: (e) => {
            var _a;
            const { relatedTarget } = e;
            const node = domRef.current;
            // relatedTarget is the newly focused element as a result of this blur event
            // so we close the overlay when the newly focused element is outside the overlay
            if (relatedTarget == null || !((_a = node.contains) === null || _a === void 0 ? void 0 : _a.call(node, relatedTarget))) {
                onHide();
            }
        } }, children));
};
exports.Datepicker = React.forwardRef((props, ref) => {
    var _a;
    const { dateProps, required, disabled, style, placeholder, showWeekNumber, showOutsideDays, value: _, defaultValue: __, onChange: ___, datepickerButtons } = props, boxProps = tslib_1.__rest(props, ["dateProps", "required", "disabled", "style", "placeholder", "showWeekNumber", "showOutsideDays", "value", "defaultValue", "onChange", "datepickerButtons"]);
    const datepickerContext = (0, DatepickerContext_1.useDatepickerContext)();
    let [value, setValue] = (0, useProperty_1.default)(props, 'value', undefined, {
        onChange: props.onChange,
    });
    const useInputOptions = Object.assign(Object.assign({}, dateProps), { required });
    if (value && value instanceof Date && !isNaN(+value)) {
        useInputOptions.defaultSelected = value;
    }
    const [month, setMonth] = (0, react_1.useState)(value !== null && value !== void 0 ? value : new Date());
    const { dayPickerProps, setSelected } = (0, react_day_picker_1.useInput)(useInputOptions);
    const updateValue = (value) => {
        setValue(value);
        setSelected(value);
    };
    const inputValue = (_a = (0, FormatHelper_1.DateFormatter)(value, { Pattern: dateProps.format })) !== null && _a !== void 0 ? _a : '';
    const [visible, doSetVisible] = (0, react_1.useState)(false);
    const setVisible = (visible, keyboardEventKey) => {
        var _a, _b;
        doSetVisible(visible);
        if (!visible) {
            (_a = datepickerContext === null || datepickerContext === void 0 ? void 0 : datepickerContext.onHide) === null || _a === void 0 ? void 0 : _a.call(datepickerContext, keyboardEventKey);
        }
        else {
            (_b = datepickerContext === null || datepickerContext === void 0 ? void 0 : datepickerContext.onShow) === null || _b === void 0 ? void 0 : _b.call(datepickerContext);
        }
    };
    const clearValue = () => {
        updateValue(undefined);
    };
    const renderButton = (label, onClick) => (React.createElement(SimpleButton_1.default, { onClick: onClick, margin: '2px' }, label));
    const todayDate = new Date();
    const footerButtonsMap = {
        clear: renderButton('Clear', () => clearValue()),
        close: renderButton('Close', () => setVisible(false)),
        today: renderButton('Today', () => updateValue(todayDate)),
        tomorrow: renderButton('Tomorrow', () => updateValue((0, addDays_1.default)(todayDate, 1))),
        yesterday: renderButton('Yesterday', () => updateValue((0, addDays_1.default)(todayDate, -1))),
        nextWorkday: renderButton('Next Workday', () => updateValue((0, addBusinessDays_1.default)(todayDate, 1))),
        prevWorkday: renderButton('Prev Workday', () => updateValue((0, addBusinessDays_1.default)(todayDate, -1))),
        '-': React.createElement("div", { style: { flex: '1 1 1%' } }),
        '|': React.createElement("hr", { style: { width: '100%', height: 0, margin: 0, border: 'none' } }),
    };
    const footerButtons = datepickerButtons.map((buttonKey, index) => React.cloneElement(footerButtonsMap[buttonKey], { key: index }));
    const clearButton = (React.createElement(SimpleButton_1.default, { "data-name": "clear", variant: "text", tooltip: "Clear", iconSize: 20, padding: 0, icon: "close", onMouseDown: (e) => {
            e.preventDefault();
            clearValue();
        }, accessLevel: 'Full' }));
    const calendarButton = (React.createElement(SimpleButton_1.default, { disabled: disabled, variant: "text", icon: "calendar", tooltip: "Date", iconSize: 20, px: 0, py: 0, onClick: () => setVisible(true) }));
    return (React.createElement(rebass_1.Flex, null,
        React.createElement(OverlayTrigger_1.default, { visible: visible, render: () => (React.createElement(DatepickerOverlay, { onMouseDown: props.onMouseDown, onHide: () => setVisible(false), onKeyDown: (e) => {
                    if (e.key === 'Escape' || e.key === 'Enter') {
                        setVisible(false, e.key);
                    }
                } },
                React.createElement(react_day_picker_1.DayPicker, Object.assign({ fixedWeeks: true }, dayPickerProps, { showWeekNumber: showWeekNumber, showOutsideDays: showOutsideDays, mode: "single", month: isNaN(+month) ? new Date() : month, onMonthChange: setMonth, components: { Caption: Caption_1.Caption, CaptionLabel: CaptionLabel_1.CaptionLabel }, onSelect: updateValue, footer: React.createElement(rebass_1.Flex, { justifyContent: "space-between", mt: 2, flexWrap: 'wrap' }, footerButtons) })))) },
            React.createElement(FieldWrap_1.default, Object.assign({}, boxProps, { style: {
                    borderRadius: style === null || style === void 0 ? void 0 : style.borderRadius,
                    width: style === null || style === void 0 ? void 0 : style.width,
                    maxWidth: style === null || style === void 0 ? void 0 : style.maxWidth,
                }, className: "ab-Datepicker", onFocus: () => {
                    if (!visible) {
                        setVisible(true);
                    }
                } }),
                React.createElement(AdaptableDateInlineInput_1.AdaptableDateInlineInput, { ref: ref, value: inputValue, 
                    // We do not want to show the format when the date-picker is visible
                    placeholder: placeholder !== null && placeholder !== void 0 ? placeholder : '', onChange: (value) => {
                        const date = new Date(value);
                        if ((0, date_fns_1.isValid)(date)) {
                            updateValue(date);
                        }
                    }, style: style, disabled: disabled }),
                !!inputValue ? clearButton : null,
                calendarButton))));
});
