"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (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 (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __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;
var react_1 = __importStar(require("react"));
var core_1 = require("@unform/core");
var dateFns = __importStar(require("date-fns"));
var use_immer_1 = require("use-immer");
var useClickOutside_1 = require("../../../hooks/useClickOutside");
var services_1 = require("../../../services");
var calendar_service_1 = require("../../../services/calendar.service");
var web_1 = require("../../Checkbox/web");
var UnformVirtual_1 = require("../../UnformVirtual");
var datepicker_interface_1 = require("../datepicker.interface");
var datepicker_style_1 = __importDefault(require("./datepicker.style"));
exports.Datepicker = function (_a) {
    var _b;
    var name = _a.name, title = _a.title, onChange = _a.onChange, _c = _a.withTimePicker, withTimePicker = _c === void 0 ? false : _c, theme = _a.theme, _d = _a.applyOnSelect, applyOnSelect = _d === void 0 ? false : _d, rest = __rest(_a, ["name", "title", "onChange", "withTimePicker", "theme", "applyOnSelect"]);
    var _e = core_1.useField(name), registerField = _e.registerField, defaultValue = _e.defaultValue, fieldName = _e.fieldName, error = _e.error, clearError = _e.clearError;
    var _f = use_immer_1.useImmer(datepicker_interface_1.getDateValue(defaultValue) || new Date()), calendarDate = _f[0], setCalendarDate = _f[1];
    var _g = use_immer_1.useImmer(datepicker_interface_1.getDateValue(defaultValue)), currentAuxValue = _g[0], setCurrentAuxValue = _g[1];
    var _h = use_immer_1.useImmer(datepicker_interface_1.getDateValue(defaultValue)), currentValue = _h[0], setCurrentValue = _h[1];
    var _j = react_1.useState(false), open = _j[0], setOpen = _j[1];
    var _k = react_1.useState(((_b = datepicker_interface_1.transformerValue(defaultValue)) === null || _b === void 0 ? void 0 : _b.allDay) || false), allDay = _k[0], setAllDay = _k[1];
    var hourInputRef = react_1.useRef(null);
    var minuteInputRef = react_1.useRef(null);
    if (withTimePicker)
        applyOnSelect = true;
    var calendarPopupRef = react_1.useRef(null);
    useClickOutside_1.useClickOutside(function () {
        setOpen(false);
        setCalendarDate(function () { return currentValue || new Date(); });
    }, calendarPopupRef);
    react_1.useEffect(function () {
        if (open) {
            var el = document.getElementsByClassName('datepicker-popup')[0];
            if (el) {
                if (el.scrollIntoView)
                    el.scrollIntoView({ block: 'end' });
            }
        }
    }, [open]);
    react_1.useEffect(function () {
        registerField({
            name: fieldName,
            clearValue: function () {
                setCalendarDate(function () { return new Date(); });
                setCurrentAuxValue(function () { return null; });
                setCurrentValue(function () { return null; });
            },
            setValue: function (ref, v) {
                setCurrentAuxValue(function () { return datepicker_interface_1.getDateValue(v); });
                setCurrentValue(function () { return datepicker_interface_1.getDateValue(v); });
            },
            getValue: function (i) {
                return datepicker_interface_1.transformerValue(currentValue, { allDay: allDay });
            },
        });
    }, [fieldName, registerField, currentValue, allDay]);
    var nextMonth = react_1.useCallback(function nextMonth() {
        setCalendarDate(function (draft) { return dateFns.addMonths(draft, 1); });
    }, []);
    var previousMonth = react_1.useCallback(function previousMonth() {
        setCalendarDate(function (draft) { return dateFns.subMonths(draft, 1); });
    }, []);
    var apply = react_1.useCallback(function apply() {
        setOpen(false);
        if (!currentAuxValue)
            return;
        clearError();
        setCurrentAuxValue(function (draft) {
            var date = draft;
            if (!allDay && withTimePicker) {
                date = dateFns.setHours(date, Number(hourInputRef.current.value));
                date = dateFns.setMinutes(date, Number(minuteInputRef.current.value));
            }
            return datepicker_interface_1.getDateValue(date);
        });
        setCurrentValue(function () {
            var date = currentAuxValue;
            if (!allDay && withTimePicker) {
                date = dateFns.setHours(date, Number(hourInputRef.current.value));
                date = dateFns.setMinutes(date, Number(minuteInputRef.current.value));
            }
            return datepicker_interface_1.getDateValue(date);
        });
        if (onChange) {
            var date = currentAuxValue;
            if (!allDay) {
                date = dateFns.setHours(date, Number(hourInputRef.current.value));
                date = dateFns.setMinutes(date, Number(minuteInputRef.current.value));
            }
            onChange(datepicker_interface_1.transformerValue(date, { allDay: allDay }));
        }
    }, [currentAuxValue, allDay]);
    react_1.useLayoutEffect(function () {
        if (open) {
            if (hourInputRef.current)
                hourInputRef.current.value = Number(dateFns.getHours(currentAuxValue)) || 0;
            if (minuteInputRef.current)
                minuteInputRef.current.value = Number(dateFns.getMinutes(currentAuxValue)) || 0;
        }
    }, [open]);
    var cancel = react_1.useCallback(function cancel() {
        setOpen(false);
        setCurrentAuxValue(function () { return currentValue; });
        setCalendarDate(function () { return currentValue || new Date(); });
    }, [currentValue]);
    var setDate = react_1.useCallback(function setDate(date) {
        setCurrentAuxValue(function (drat) {
            if (!drat)
                return date;
            return dateFns.set(drat, {
                year: dateFns.getYear(date),
                month: dateFns.getMonth(date),
                date: dateFns.getDate(date),
            });
        });
        if (!applyOnSelect) {
            clearError();
            setOpen(false);
            setCurrentValue(function () { return date; });
        }
    }, []);
    function onChangeHour() {
        hourInputRef.current.value = services_1.OnlyNumbers(hourInputRef.current.value);
        if (Number(hourInputRef.current.value) > 23) {
            hourInputRef.current.value = '23';
        }
        if (hourInputRef.current.value.length >= 2) {
            minuteInputRef.current.focus();
            minuteInputRef.current.select();
        }
    }
    function onChangeMinutes() {
        minuteInputRef.current.value = services_1.OnlyNumbers(minuteInputRef.current.value);
        if (Number(minuteInputRef.current.value) > 59) {
            minuteInputRef.current.value = '59';
        }
    }
    function onBlurHours() {
        if (!minuteInputRef.current.value) {
            minuteInputRef.current.value = '00';
        }
        if (!hourInputRef.current.value) {
            hourInputRef.current.value = '00';
        }
    }
    var removeDate = react_1.useCallback(function removeDate() {
        setCalendarDate(function () { return new Date(); });
        setCurrentAuxValue(function () { return null; });
        setCurrentValue(function () { return null; });
        setOpen(false);
        if (onChange)
            onChange(null);
    }, []);
    var addHour = react_1.useCallback(function addHour() {
        hourInputRef.current.value = Number(services_1.OnlyNumbers(hourInputRef.current.value)) + 1;
        if (hourInputRef.current.value > 23) {
            hourInputRef.current.value = 0;
        }
    }, []);
    var subHour = react_1.useCallback(function subHour() {
        hourInputRef.current.value = Number(services_1.OnlyNumbers(hourInputRef.current.value)) - 1;
        if (hourInputRef.current.value < 0) {
            hourInputRef.current.value = 23;
        }
    }, []);
    var addMinute = react_1.useCallback(function addMinute() {
        minuteInputRef.current.value = Number(services_1.OnlyNumbers(minuteInputRef.current.value)) + 1;
        if (minuteInputRef.current.value > 59) {
            minuteInputRef.current.value = 0;
        }
    }, []);
    var subMinute = react_1.useCallback(function subMinute() {
        minuteInputRef.current.value = Number(services_1.OnlyNumbers(minuteInputRef.current.value)) - 1;
        if (minuteInputRef.current.value < 0) {
            minuteInputRef.current.value = 59;
        }
    }, []);
    return (react_1.default.createElement(datepicker_style_1.default, { themeInput: theme, "data-cy": "datepicker-" + name },
        react_1.default.createElement("div", { className: "input-title" }, title),
        react_1.default.createElement(InputDatePicker, { currentValue: currentValue, error: error, allDay: allDay, setOpen: setOpen, withTimePicker: withTimePicker, removeDate: removeDate }),
        open && (react_1.default.createElement("div", { className: "datepicker-popup", ref: calendarPopupRef, "data-testid": "datepicker-popup" },
            react_1.default.createElement(DatePickerCalendar, { nextMonth: nextMonth, previousMonth: previousMonth, date: calendarDate, selectedDate: currentAuxValue, setDate: setDate }),
            withTimePicker && (react_1.default.createElement("div", null,
                react_1.default.createElement("hr", null),
                react_1.default.createElement(UnformVirtual_1.UnformVirtual, { onSubmit: function () { }, initialData: { allDay: allDay } },
                    react_1.default.createElement(web_1.Checkbox, { name: "allDay", title: "Dia todo", onChange: function (checked) { return setAllDay(!!checked); }, "data-testid": "datepicker-all-day" })),
                !allDay && (react_1.default.createElement("div", { className: "timepicker" },
                    react_1.default.createElement("div", { className: "d-flex w-100" },
                        react_1.default.createElement("div", { className: "d-flex flex-fill" },
                            react_1.default.createElement("div", { className: "plus flex-fill align-self-center", onClick: subHour },
                                react_1.default.createElement("i", { className: "fas fa-minus-circle" })),
                            react_1.default.createElement("div", { className: "input-time" },
                                react_1.default.createElement("input", { type: "text", defaultValue: "00", ref: hourInputRef, onFocus: function () { return hourInputRef.current.select(); }, onChange: onChangeHour, onBlur: onBlurHours, maxLength: 2, "data-testid": "datepicker-input-hour" })),
                            react_1.default.createElement("div", { className: "plus flex-fill align-self-center", onClick: addHour },
                                react_1.default.createElement("i", { className: "fas fa-plus-circle" }))),
                        react_1.default.createElement("span", { className: "division" }, ":"),
                        react_1.default.createElement("div", { className: "d-flex flex-fill" },
                            react_1.default.createElement("div", { className: "plus flex-fill align-self-center", onClick: subMinute },
                                react_1.default.createElement("i", { className: "fas fa-minus-circle" })),
                            react_1.default.createElement("div", { className: "input-time" },
                                react_1.default.createElement("input", { type: "text", defaultValue: "00", ref: minuteInputRef, onFocus: function () { return minuteInputRef.current.select(); }, onChange: onChangeMinutes, onBlur: onBlurHours, maxLength: 2, "data-testid": "datepicker-input-minute" })),
                            react_1.default.createElement("div", { className: "plus flex-fill align-self-center", onClick: addMinute },
                                react_1.default.createElement("i", { className: "fas fa-plus-circle" })))))))),
            applyOnSelect && (react_1.default.createElement("div", { className: "actions" },
                react_1.default.createElement("div", { className: "btn-cancel", onClick: cancel, "data-testid": "datepicker-cancel" }, "Cancelar"),
                react_1.default.createElement("div", { className: "btn-apply", onClick: function () { return apply(); }, "data-testid": "datepicker-apply" }, "Aplicar"))))),
        error && (react_1.default.createElement("div", { "data-testid": "input-error", className: "error-input" }, error))));
};
function InputDatePicker(_a) {
    var currentValue = _a.currentValue, error = _a.error, setOpen = _a.setOpen, withTimePicker = _a.withTimePicker, removeDate = _a.removeDate, allDay = _a.allDay;
    var viewDateStringView = currentValue ? dateFns.format(currentValue, 'd MMM yyyy') : '';
    var value = datepicker_interface_1.transformerValue(currentValue);
    var hour = currentValue ? dateFns.format(currentValue, 'HH') : '';
    var minute = currentValue ? dateFns.format(currentValue, 'mm') : '';
    return (react_1.default.createElement(react_1.default.Fragment, null,
        !value && (react_1.default.createElement("div", { className: "input-border " + (error && 'has-error'), onClick: function () { return setOpen(true); }, "data-testid": "datepicker-input" },
            react_1.default.createElement("div", { className: "prefix" },
                react_1.default.createElement("i", { className: "far fa-calendar-alt" })),
            react_1.default.createElement("div", { className: "input pl-3" }, "Selecione um data"))),
        !!value && (react_1.default.createElement("div", { className: "input-border", "data-cy": "view-date" },
            react_1.default.createElement("div", { className: "table calendar-input" },
                react_1.default.createElement("div", { className: "text-primary calendar-icon", onClick: function () { return setOpen(true); } },
                    react_1.default.createElement("i", { className: "far fa-calendar-alt" })),
                react_1.default.createElement("div", { className: "pl-3 text-primary font-weight-bold flex-fill", "data-testid": "datepicker-input", onClick: function () { return setOpen(true); } },
                    react_1.default.createElement("div", { className: "date" }, viewDateStringView),
                    withTimePicker && !allDay && (react_1.default.createElement("div", { className: "time" },
                        "\u00C1s ",
                        hour,
                        ":",
                        minute)),
                    withTimePicker && allDay && react_1.default.createElement("div", { className: "time" }, "O dia todo")),
                react_1.default.createElement("div", { className: "font-weight-bold align-self-center", "data-testid": "datepicker-remove-date", onClick: removeDate },
                    react_1.default.createElement("i", { className: "fas fa-times" })))))));
}
function DatePickerCalendar(_a) {
    var nextMonth = _a.nextMonth, previousMonth = _a.previousMonth, date = _a.date, selectedDate = _a.selectedDate, setDate = _a.setDate;
    var monthName = calendar_service_1.Calendar.monthsName[dateFns.getMonth(date)];
    var calendarYear = dateFns.getYear(date);
    var weekNames = react_1.useMemo(function () { return calendar_service_1.Calendar.weeksName; }, []);
    var month = react_1.useMemo(function () { return calendar_service_1.Calendar.getMonth(dateFns.getMonth(date), dateFns.getYear(date)); }, [date]);
    return (react_1.default.createElement(react_1.default.Fragment, null,
        react_1.default.createElement("div", { className: "month" },
            react_1.default.createElement("i", { className: "fas fa-angle-right right", onClick: nextMonth, "data-testid": "datepicker-next-month" }),
            react_1.default.createElement("i", { className: "fas fa-angle-left left", onClick: previousMonth, "data-testid": "datepicker-previous-month" }),
            react_1.default.createElement("div", { className: "month-name", "data-testid": "datepicker-month-name" },
                monthName,
                ", ",
                calendarYear)),
        weekNames.map(function (nameWeek, i) { return (react_1.default.createElement("div", { key: nameWeek + "-" + i, className: "weekName" }, nameWeek)); }),
        month.map(function (week, weekI) { return (react_1.default.createElement("div", { key: weekI, className: "week" }, week.map(function (day) { return (react_1.default.createElement("div", { key: day.dateYYYYMMDD, "data-testid": day.dateYYYYMMDD, className: "day " + (day.today && 'today') + " " + (dateFns.isSameDay(day.dateInstance, selectedDate) && 'select') + " " + (!day.currentMonth && 'other-month'), onClick: function () { return setDate(day.dateInstance); } }, day.day)); }))); })));
}
//# sourceMappingURL=datepicker.js.map