/**
 * amis-ui v6.12.0-beta.0
 * Copyright 2018-2025 fex
 */

'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var tslib = require('tslib');
var React = require('react');
var CalendarContainer = require('./CalendarContainer.js');
var cx = require('classnames');
var moment = require('moment');
var amisCore = require('amis-core');
require('moment/locale/zh-cn');
require('moment/locale/de');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx);
var moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);

var __react_jsx__ = require('react');
var _J$X_ = (__react_jsx__["default"] || __react_jsx__).createElement;
(__react_jsx__["default"] || __react_jsx__).Fragment;
var viewModes = Object.freeze({
    YEARS: 'years',
    MONTHS: 'months',
    DAYS: 'days',
    TIME: 'time'
});
var BaseDatePicker = /** @class */ (function (_super) {
    tslib.__extends(BaseDatePicker, _super);
    function BaseDatePicker(props) {
        var _this = _super.call(this, props) || this;
        _this.timeCellLength = {
            year: 4,
            month: 2,
            date: 2,
            hours: 2,
            minutes: 2,
            seconds: 2,
            milliseconds: 3
        };
        _this.getUpdateOn = function (formats) {
            if (formats.date.match(/[lLD]/)) {
                return 'days';
            }
            else if (formats.date.indexOf('M') !== -1) {
                return 'months';
            }
            else if (formats.date.indexOf('Q') !== -1) {
                return 'quarters';
            }
            else if (formats.date.indexOf('Y') !== -1) {
                return 'years';
            }
            return 'days';
        };
        _this.componentProps = {
            fromProps: [
                'value',
                'isValidDate',
                'renderDay',
                'renderMonth',
                'renderYear',
                'timeConstraints'
            ],
            fromState: ['viewDate', 'selectedDate', 'updateOn'],
            fromThis: [
                'setDate',
                'setTime',
                'showView',
                'addTime',
                'subtractTime',
                'updateSelectedDate',
                'localMoment',
                'handleClickOutside',
                'onClick',
                'onMouseEnter',
                'onMouseLeave'
            ]
        };
        _this.showView = function (view) {
            return function () {
                _this.setState({ currentView: view });
            };
        };
        _this.subtractTime = function (amount, type, toSelected) {
            return function () {
                _this.updateTime('subtract', amount, type, toSelected);
            };
        };
        _this.addTime = function (amount, type, toSelected) {
            return function () {
                _this.updateTime('add', amount, type, toSelected);
            };
        };
        _this.allowedSetTime = ['hours', 'minutes', 'seconds', 'milliseconds'];
        _this.setTime = function (type, value) {
            var index = _this.allowedSetTime.indexOf(type) + 1, state = _this.state, date = (state.selectedDate || state.viewDate).clone(), nextType;
            // It is needed to set all the time properties
            // to not to reset the time
            date[type](value);
            for (; index < _this.allowedSetTime.length; index++) {
                nextType = _this.allowedSetTime[index];
                date[nextType](date[nextType]());
            }
            if (!_this.props.value) {
                _this.setState({
                    selectedDate: date,
                    inputValue: date.format(state.displayForamt)
                });
            }
            _this.props.onChange && _this.props.onChange(date, 'time');
        };
        _this.setDate = function (type) {
            // todo 没看懂这个是啥意思，好像没啥用
            var currentShould = _this.props.viewMode === 'months' &&
                !/^mm$/i.test((_this.props.inputFormat || _this.props.displayForamt) || '');
            var nextViews = {
                month: currentShould ? 'months' : 'days',
                year: currentShould ? 'months' : 'days',
                quarters: ''
            };
            if (_this.props.viewMode === 'quarters') {
                nextViews.year = 'quarters';
            }
            return function (e) {
                _this.setState({
                    viewDate: _this.state.viewDate
                        .clone()[type](parseInt(e.target.closest('td').getAttribute('data-value'), 10)).startOf(type),
                    currentView: nextViews[type]
                });
            };
        };
        _this.getTargetDate = function (e) {
            var target = e.currentTarget, modifier = 0, viewDate = _this.state.viewDate, currentDate = _this.state.selectedDate || viewDate, date;
            if (target.className.indexOf('rdtDay') !== -1) {
                if (target.className.indexOf('rdtNew') !== -1)
                    modifier = 1;
                else if (target.className.indexOf('rdtOld') !== -1)
                    modifier = -1;
                date = viewDate
                    .clone()
                    .month(viewDate.month() + modifier)
                    .date(parseInt(target.getAttribute('data-value'), 10));
            }
            else if (target.className.indexOf('rdtMonth') !== -1) {
                date = viewDate
                    .clone()
                    .month(parseInt(target.getAttribute('data-value'), 10))
                    .date(currentDate.date());
            }
            else if (target.className.indexOf('rdtQuarter') !== -1) {
                date = viewDate
                    .clone()
                    .quarter(parseInt(target.getAttribute('data-value'), 10))
                    .startOf('quarter')
                    .date(currentDate.date());
            }
            else if (target.className.indexOf('rdtYear') !== -1) {
                date = viewDate
                    .clone()
                    .month(currentDate.month())
                    .date(currentDate.date())
                    .year(parseInt(target.getAttribute('data-value'), 10));
            }
            date === null || date === void 0 ? void 0 : date.hours(currentDate.hours()).minutes(currentDate.minutes()).seconds(currentDate.seconds()).milliseconds(currentDate.milliseconds());
            return date;
        };
        _this.updateSelectedDate = function (e, close) {
            var that = _this;
            var _a = that.props, embed = _a.embed, status = _a.status;
            var date = that.getTargetDate(e);
            if (!_this.props.value) {
                var open = !(_this.props.closeOnSelect && close);
                if (!open && !embed) {
                    that.props.onBlur(date);
                }
                _this.setState({
                    selectedDate: date,
                    viewDate: date === null || date === void 0 ? void 0 : date.clone().startOf('month'),
                    inputValue: date === null || date === void 0 ? void 0 : date.format(_this.state.displayForamt),
                    open: open
                });
            }
            else {
                _this.setState({
                    selectedDate: date,
                    viewDate: date === null || date === void 0 ? void 0 : date.clone().startOf('month'),
                    inputValue: date === null || date === void 0 ? void 0 : date.format(_this.state.displayForamt)
                });
                if (_this.props.closeOnSelect && close) {
                    that.closeCalendar();
                }
            }
            that.props.onChange(date, 'days', status);
        };
        _this.getDateBoundary = function (currentDate) {
            var _a, _b;
            var _c = currentDate.toObject(), years = _c.years, months = _c.months;
            var maxDateObject = (_a = _this.props.maxDate) === null || _a === void 0 ? void 0 : _a.toObject();
            var minDateObject = (_b = _this.props.minDate) === null || _b === void 0 ? void 0 : _b.toObject();
            var yearBoundary = {
                max: maxDateObject ? maxDateObject.years : years + 100,
                min: minDateObject ? minDateObject.years : years - 100
            };
            var monthBoundary = {
                max: years === (maxDateObject === null || maxDateObject === void 0 ? void 0 : maxDateObject.years) ? maxDateObject.months : 11,
                min: years === (minDateObject === null || minDateObject === void 0 ? void 0 : minDateObject.years) ? minDateObject.months : 0
            };
            var dateBoundary = {
                max: years === (maxDateObject === null || maxDateObject === void 0 ? void 0 : maxDateObject.years) && months === (maxDateObject === null || maxDateObject === void 0 ? void 0 : maxDateObject.months)
                    ? maxDateObject.date
                    : currentDate.daysInMonth(),
                min: years === (minDateObject === null || minDateObject === void 0 ? void 0 : minDateObject.years) && months === (minDateObject === null || minDateObject === void 0 ? void 0 : minDateObject.months)
                    ? minDateObject.date
                    : 1
            };
            return {
                year: yearBoundary,
                month: monthBoundary,
                date: dateBoundary,
                hours: { max: 23, min: 0 },
                minutes: { max: 59, min: 0 },
                seconds: { max: 59, min: 0 }
            };
        };
        _this.timeCell = function (value, type) {
            var str = value + '';
            while (str.length < _this.timeCellLength[type])
                str = '0' + str;
            return str;
        };
        _this.getColumns = function (types, dateBoundary) {
            var columns = [];
            types.map(function (type) {
                var options = amisCore.utils
                    .getRange(dateBoundary[type].min, dateBoundary[type].max, 1)
                    .map(function (item) {
                    return {
                        text: type === 'month'
                            ? _this.timeCell(item + 1, type)
                            : _this.timeCell(item, type),
                        value: item
                    };
                });
                columns.push({ options: options });
            });
            return columns;
        };
        _this.onConfirm = function (value, types) {
            var currentDate = (_this.state.selectedDate ||
                _this.state.viewDate ||
                moment__default["default"]()).clone();
            var date = amisCore.convertArrayValueToMoment(value, types, currentDate);
            if ((types === null || types === void 0 ? void 0 : types[1]) === 'quarter') {
                date = date.startOf('quarter').date(currentDate.date());
            }
            if (!_this.props.value) {
                _this.setState({
                    selectedDate: date,
                    viewDate: date,
                    inputValue: date.format(_this.state.displayForamt)
                });
            }
            _this.props.onChange && _this.props.onChange(date);
            _this.onClose();
        };
        _this.onClose = function () {
            _this.setState({ currentView: _this.state.initView });
            _this.props.onClose && _this.props.onClose();
        };
        var state = _this.getStateFromProps(_this.props);
        if (state.open === undefined) {
            state.open = !_this.props.input;
        }
        state.currentView = _this.props.dateFormat
            ? _this.props.viewMode || state.updateOn || 'days'
            : _this.props.viewMode || 'time';
        state.initView = state.currentView;
        _this.state = state;
        _this.onClick = _this.onClick.bind(_this);
        _this.onMouseEnter = _this.onMouseEnter.bind(_this);
        _this.onMouseLeave = _this.onMouseLeave.bind(_this);
        return _this;
    }
    BaseDatePicker.prototype.getFormats = function (props) {
        var formats = {
            date: props.dateFormat || '',
            time: props.timeFormat || ''
        }, locale = this.localMoment(props.date, undefined, props).localeData();
        if (formats.date === true) {
            formats.date = locale.longDateFormat('L');
        }
        else if (this.getUpdateOn(formats) !== viewModes.DAYS) {
            formats.time = '';
        }
        if (formats.time === true) {
            formats.time = locale.longDateFormat('LT');
        }
        formats.datetime =
            formats.date && formats.time
                ? formats.date + ' ' + formats.time
                : formats.date || formats.time;
        return formats;
    };
    BaseDatePicker.prototype.componentDidUpdate = function (prevProps) {
        var props = this.props;
        var formats = this.getFormats(props), updatedState = {};
        if (props.value !== prevProps.value ||
            formats.datetime !== this.getFormats(prevProps).datetime) {
            updatedState = this.getStateFromProps(props);
        }
        if (props.viewMode !== prevProps.viewMode) {
            updatedState.currentView = props.viewMode;
        }
        if (props.locale !== prevProps.locale) {
            if (this.state.viewDate) {
                var updatedViewDate = this.state.viewDate.clone().locale(props.locale);
                updatedState.viewDate = updatedViewDate;
            }
            if (this.state.selectedDate) {
                var updatedSelectedDate = this.state.selectedDate
                    .clone()
                    .locale(props.locale);
                updatedState.selectedDate = updatedSelectedDate;
                updatedState.inputValue = updatedSelectedDate.format(formats.datetime);
            }
        }
        if (props.utc !== prevProps.utc ||
            props.displayTimeZone !== prevProps.displayTimeZone) {
            if (props.utc) {
                if (this.state.viewDate)
                    updatedState.viewDate = this.state.viewDate.clone().utc();
                if (this.state.selectedDate) {
                    updatedState.selectedDate = this.state.selectedDate.clone().utc();
                    updatedState.inputValue = updatedState.selectedDate.format(formats.datetime);
                }
            }
            else if (props.displayTimeZone) {
                if (this.state.viewDate)
                    updatedState.viewDate = this.state.viewDate
                        .clone()
                        // @ts-ignore 其实目前不支持，需要自己 import "moment-timezone";
                        .tz(props.displayTimeZone);
                if (this.state.selectedDate) {
                    updatedState.selectedDate = this.state.selectedDate
                        .clone()
                        // @ts-ignore
                        .tz(props.displayTimeZone);
                    updatedState.inputValue = updatedState.selectedDate
                        .tz(props.displayTimeZone)
                        .format(formats.datetime);
                }
            }
            else {
                if (this.state.viewDate)
                    updatedState.viewDate = this.state.viewDate.clone().local();
                if (this.state.selectedDate) {
                    updatedState.selectedDate = this.state.selectedDate.clone().local();
                    updatedState.inputValue = updatedState.selectedDate.format(formats.datetime);
                }
            }
        }
        if (props.viewDate !== prevProps.viewDate) {
            updatedState.viewDate = moment__default["default"](props.viewDate);
        }
        if (Object.keys(updatedState).length) {
            this.setState(updatedState);
        }
        this.checkTZ(props);
    };
    BaseDatePicker.prototype.checkTZ = function (props) {
        var con = console;
        // @ts-ignore
        if (props.displayTimeZone && !this.tzWarning && !moment__default["default"].tz) {
            this.tzWarning = true;
            con &&
                con.error('react-datetime: displayTimeZone prop with value "' +
                    props.displayTimeZone +
                    '" is used but moment.js timezone is not loaded.');
        }
    };
    BaseDatePicker.prototype.localMoment = function (date, format, props) {
        props = props || this.props;
        var m = null;
        if (props.utc) {
            m = moment__default["default"].utc(date, format, props.strictParsing);
        }
        else if (props.displayTimeZone) {
            // @ts-ignore 以后再修
            m = moment__default["default"].tz(date, format, props.displayTimeZone);
        }
        else {
            m = moment__default["default"](date, format, props.strictParsing);
        }
        if (props.locale)
            m.locale(props.locale);
        return m;
    };
    BaseDatePicker.prototype.parseDate = function (date, formats) {
        var parsedDate;
        if (date && typeof date === 'string')
            parsedDate = this.localMoment(date, formats.datetime);
        else if (date)
            parsedDate = this.localMoment(date);
        if (parsedDate && !parsedDate.isValid())
            parsedDate = null;
        return parsedDate;
    };
    BaseDatePicker.prototype.getStateFromProps = function (props) {
        var formats = this.getFormats(props), date = props.value || props.defaultValue || '', selectedDate, viewDate, updateOn, inputValue;
        selectedDate = this.parseDate(date, formats);
        viewDate = this.parseDate(props.viewDate, formats);
        viewDate = selectedDate
            ? selectedDate.clone().startOf('month')
            : viewDate
                ? viewDate.clone().startOf('month')
                : this.localMoment().startOf('month');
        updateOn = this.getUpdateOn(formats);
        if (selectedDate)
            inputValue = selectedDate.format(formats.datetime);
        else if (date.isValid && !date.isValid())
            inputValue = '';
        else
            inputValue = date || '';
        return {
            updateOn: updateOn,
            displayForamt: formats.datetime,
            viewDate: viewDate,
            selectedDate: selectedDate,
            inputValue: inputValue,
            open: props.open
        };
    };
    BaseDatePicker.prototype.getComponentProps = function () {
        var _this = this;
        var me = this, formats = this.getFormats(this.props), props = { dateFormat: formats.date, timeFormat: formats.time };
        this.componentProps.fromProps.forEach(function (name) {
            props[name] = me.props[name];
        });
        this.componentProps.fromState.forEach(function (name) {
            props[name] = me.state[name];
        });
        this.componentProps.fromThis.forEach(function (name) {
            props[name] = me[name];
        });
        props.setDateTimeState = this.setState.bind(this);
        [
            'inputFormat',
            'displayForamt',
            'onChange',
            'requiredConfirm',
            'classPrefix',
            'prevIcon',
            'nextIcon',
            'isEndDate',
            'classnames',
            'minDate',
            'maxDate',
            'schedules',
            'largeMode',
            'todayActiveStyle',
            'onScheduleClick',
            'hideHeader',
            'updateOn',
            'mobileUI',
            'showToolbar',
            'embed',
            'env',
            'testIdBuilder'
        ].forEach(function (key) { return (props[key] = _this.props[key]); });
        return props;
    };
    BaseDatePicker.prototype.updateTime = function (op, amount, type, toSelected) {
        var update = {}, date = toSelected ? 'selectedDate' : 'viewDate';
        // @ts-ignore
        update[date] = this.state[date].clone()[op](amount, type);
        this.setState(update);
    };
    BaseDatePicker.prototype.onClick = function (e) {
        var date = this.getTargetDate(e);
        this.props.onClick && this.props.onClick(date);
    };
    BaseDatePicker.prototype.onMouseEnter = function (e) {
        var date = this.getTargetDate(e);
        this.props.onMouseEnter && this.props.onMouseEnter(date);
    };
    BaseDatePicker.prototype.onMouseLeave = function (e) {
        var date = this.getTargetDate(e);
        this.props.onMouseLeave && this.props.onMouseLeave(date);
    };
    BaseDatePicker.prototype.render = function () {
        var _a;
        var _b = this.props, viewMode = _b.viewMode, timeFormat = _b.timeFormat, dateFormat = _b.dateFormat, timeRangeHeader = _b.timeRangeHeader, mobileUI = _b.mobileUI, testIdBuilder = _b.testIdBuilder;
        var Component = CalendarContainer["default"];
        var viewProps = this.getComponentProps();
        if (viewMode === 'quarters') {
            _a = tslib.__read([
                'quarters',
                this.props.renderQuarter
            ], 2), viewProps.updateOn = _a[0], viewProps.renderQuarter = _a[1];
        }
        else if (viewMode === 'years') {
            viewProps.updateOn = 'years';
        }
        else if (viewMode === 'months') {
            viewProps.updateOn = 'months';
        }
        viewProps.onConfirm = this.onConfirm;
        viewProps.onClose = this.onClose;
        viewProps.getDateBoundary = this.getDateBoundary;
        viewProps.getColumns = this.getColumns;
        viewProps.timeCell = this.timeCell;
        viewProps.timeRangeHeader = this.props.timeRangeHeader;
        return (_J$X_("div", tslib.__assign({ className: cx__default["default"]('rdt rdtStatic rdtOpen', this.props.className, (timeFormat && !dateFormat) || typeof dateFormat !== 'string'
                ? 'rdtTimeWithoutD'
                : timeFormat && timeFormat.toLowerCase().indexOf('s') > 0
                    ? 'rdtTimeWithS'
                    : timeFormat
                        ? 'rdtTime'
                        : '') }, testIdBuilder === null || testIdBuilder === void 0 ? void 0 : testIdBuilder.getTestId()),
            _J$X_("div", { key: "dt", className: cx__default["default"]('rdtPicker', {
                    'is-mobile-year': mobileUI && viewMode === 'years'
                }, { 'is-mobile-embed': mobileUI && viewProps.embed }, timeFormat && !dateFormat
                    ? 'rdtPickerTimeWithoutD'
                    : timeFormat && dateFormat
                        ? 'rdtPickerTime'
                        : dateFormat && !timeFormat
                            ? 'rdtPickerDate'
                            : '') },
                _J$X_(Component, { view: this.state.currentView, viewProps: viewProps, timeRangeHeader: timeRangeHeader }))));
    };
    return BaseDatePicker;
}(React__default["default"].Component));
var Calendar = amisCore.themeable(BaseDatePicker);

exports["default"] = Calendar;
