import { h, Teleport, ref, computed, provide, reactive, inject, nextTick, watch, onUnmounted } from 'vue';
import { defineVxeComponent } from '../../ui/src/comp';
import XEUtils from 'xe-utils';
import { getConfig, getIcon, getI18n, commands, createEvent, globalEvents, GLOBAL_EVENT_KEYS, useSize, renderEmptyElement } from '../../ui';
import { getFuncText, getLastZIndex, nextZIndex, isEnableConf } from '../../ui/src/utils';
import { updatePanelPlacement, getEventTargetNode } from '../../ui/src/dom';
import { getSlotVNs } from '../../ui/src/vn';
import { parseDateObj, parseDateValue, getDateByCode, handleValueFormat, hasDateValueType, hasTimestampValueType } from '../../date-panel/src/util';
import { errLog } from '../../ui/src/log';
import VxeDatePanelComponent from '../../date-panel/src/date-panel';
import VxeButtonComponent from '../../button/src/button';
import VxeButtonGroupComponent from '../../button/src/button-group';
export default defineVxeComponent({
    name: 'VxeDatePicker',
    props: {
        modelValue: [String, Number, Date],
        immediate: {
            type: Boolean,
            default: true
        },
        name: String,
        type: {
            type: String,
            default: 'date'
        },
        clearable: {
            type: Boolean,
            default: () => getConfig().datePicker.clearable
        },
        readonly: {
            type: Boolean,
            default: null
        },
        disabled: {
            type: Boolean,
            default: null
        },
        placeholder: String,
        autoComplete: {
            type: String,
            default: 'off'
        },
        form: String,
        className: String,
        zIndex: Number,
        size: {
            type: String,
            default: () => getConfig().datePicker.size || getConfig().size
        },
        multiple: Boolean,
        limitCount: {
            type: [String, Number],
            default: () => getConfig().datePicker.limitCount
        },
        // date、week、month、quarter、year
        startDate: {
            type: [String, Number, Date],
            default: () => getConfig().datePicker.startDate
        },
        endDate: {
            type: [String, Number, Date],
            default: () => getConfig().datePicker.endDate
        },
        defaultDate: [String, Number, Date],
        defaultTime: [String, Number, Date],
        minDate: [String, Number, Date],
        maxDate: [String, Number, Date],
        startDay: {
            type: [String, Number],
            default: () => getConfig().datePicker.startDay
        },
        labelFormat: String,
        valueFormat: String,
        timeFormat: String,
        editable: {
            type: Boolean,
            default: true
        },
        festivalMethod: {
            type: Function,
            default: () => getConfig().datePicker.festivalMethod
        },
        disabledMethod: {
            type: Function,
            default: () => getConfig().datePicker.disabledMethod
        },
        // week
        selectDay: {
            type: [String, Number],
            default: () => getConfig().datePicker.selectDay
        },
        showClearButton: {
            type: Boolean,
            default: () => getConfig().datePicker.showClearButton
        },
        showConfirmButton: {
            type: Boolean,
            default: () => getConfig().datePicker.showConfirmButton
        },
        autoClose: {
            type: Boolean,
            default: () => getConfig().datePicker.autoClose
        },
        prefixIcon: String,
        suffixIcon: String,
        placement: String,
        transfer: {
            type: Boolean,
            default: null
        },
        timeConfig: Object,
        popupConfig: Object,
        shortcutConfig: Object,
        // 已废弃 startWeek，被 startDay 替换
        startWeek: Number
    },
    emits: [
        'update:modelValue',
        'input',
        'change',
        'keydown',
        'keyup',
        'click',
        'focus',
        'blur',
        'clear',
        'confirm',
        'prefix-click',
        'suffix-click',
        'date-prev',
        'date-today',
        'date-next',
        'shortcut-click'
    ],
    setup(props, context) {
        const { slots, emit } = context;
        const $xeModal = inject('$xeModal', null);
        const $xeDrawer = inject('$xeDrawer', null);
        const $xeTable = inject('$xeTable', null);
        const $xeForm = inject('$xeForm', null);
        const formItemInfo = inject('xeFormItemInfo', null);
        const xID = XEUtils.uniqueId();
        const { computeSize } = useSize(props);
        const reactData = reactive({
            initialized: false,
            panelIndex: 0,
            visiblePanel: false,
            isAniVisible: false,
            panelStyle: {},
            panelPlacement: '',
            isActivated: false,
            inputValue: '',
            inputLabel: ''
        });
        const internalData = {
            hpTimeout: undefined
        };
        const refElem = ref();
        const refInputTarget = ref();
        const refInputPanel = ref();
        const refPanelWrapper = ref();
        const refDatePanel = ref();
        const refMaps = {
            refElem,
            refInput: refInputTarget
        };
        const $xeDatePicker = {
            xID,
            props,
            context,
            reactData,
            internalData,
            getRefMaps: () => refMaps
        };
        const computeBtnTransfer = computed(() => {
            const { transfer } = props;
            const popupOpts = computePopupOpts.value;
            if (XEUtils.isBoolean(popupOpts.transfer)) {
                return popupOpts.transfer;
            }
            if (transfer === null) {
                const globalTransfer = getConfig().datePicker.transfer;
                if (XEUtils.isBoolean(globalTransfer)) {
                    return globalTransfer;
                }
                if ($xeTable || $xeModal || $xeDrawer || $xeForm) {
                    return true;
                }
            }
            return transfer;
        });
        const computeFormReadonly = computed(() => {
            const { readonly } = props;
            if (readonly === null) {
                if ($xeForm) {
                    return $xeForm.props.readonly;
                }
                return false;
            }
            return readonly;
        });
        const computeIsDisabled = computed(() => {
            const { disabled } = props;
            if (disabled === null) {
                if ($xeForm) {
                    return $xeForm.props.disabled;
                }
                return false;
            }
            return disabled;
        });
        const computeIsDateTimeType = computed(() => {
            const { type } = props;
            return type === 'time' || type === 'datetime';
        });
        const computeIsDatePickerType = computed(() => {
            const isDateTimeType = computeIsDateTimeType.value;
            return isDateTimeType || ['date', 'week', 'month', 'quarter', 'year'].indexOf(props.type) > -1;
        });
        const computeIsClearable = computed(() => {
            return props.clearable;
        });
        const computeInputReadonly = computed(() => {
            const { type, editable, multiple } = props;
            const formReadonly = computeFormReadonly.value;
            return formReadonly || multiple || !editable || type === 'week' || type === 'quarter';
        });
        const computeInpPlaceholder = computed(() => {
            const { placeholder } = props;
            if (placeholder) {
                return getFuncText(placeholder);
            }
            const globalPlaceholder = getConfig().datePicker.placeholder;
            if (globalPlaceholder) {
                return getFuncText(globalPlaceholder);
            }
            return getI18n('vxe.base.pleaseSelect');
        });
        const computeInpImmediate = computed(() => {
            const { immediate } = props;
            return immediate;
        });
        const computeTimeOpts = computed(() => {
            return Object.assign({}, getConfig().datePicker.timeConfig, props.timeConfig);
        });
        const computePopupOpts = computed(() => {
            return Object.assign({}, getConfig().datePicker.popupConfig, props.popupConfig);
        });
        const computeShortcutOpts = computed(() => {
            return Object.assign({}, getConfig().datePicker.shortcutConfig, props.shortcutConfig);
        });
        const computeShortcutList = computed(() => {
            const shortcutOpts = computeShortcutOpts.value;
            const { options } = shortcutOpts;
            if (options) {
                return options.map((option, index) => {
                    return Object.assign({
                        name: `${option.name || option.code || index}`
                    }, option);
                });
            }
            return [];
        });
        const computeDateLabelFormat = computed(() => {
            const { labelFormat } = props;
            return labelFormat || getI18n(`vxe.input.date.labelFormat.${props.type}`);
        });
        const computeDateValueFormat = computed(() => {
            const { type, valueFormat } = props;
            return handleValueFormat(type, valueFormat);
        });
        const computeFirstDayOfWeek = computed(() => {
            const { startDay } = props;
            return XEUtils.toNumber(startDay);
        });
        const computePanelLabel = computed(() => {
            const { type, multiple } = props;
            const { inputValue } = reactData;
            const dateLabelFormat = computeDateLabelFormat.value;
            const dateValueFormat = computeDateValueFormat.value;
            const firstDayOfWeek = computeFirstDayOfWeek.value;
            const vals = inputValue ? (multiple ? inputValue.split(',') : [inputValue]) : [];
            return vals.map(val => {
                const dateObj = parseDateObj(val, type, {
                    valueFormat: dateValueFormat,
                    labelFormat: dateLabelFormat,
                    firstDay: firstDayOfWeek
                });
                return dateObj.label;
            }).join(', ');
        });
        const updateModelValue = () => {
            const { modelValue } = props;
            let val = '';
            if (modelValue) {
                if (XEUtils.isNumber(modelValue) && /^[0-9]{11,15}$/.test(`${modelValue}`)) {
                    val = new Date(modelValue);
                }
                else {
                    val = modelValue;
                }
            }
            reactData.inputValue = val;
        };
        const triggerEvent = (evnt) => {
            const { inputValue } = reactData;
            dispatchEvent(evnt.type, { value: inputValue }, evnt);
        };
        const handleChange = (value, evnt) => {
            const { type, modelValue, valueFormat } = props;
            const dateValueFormat = computeDateValueFormat.value;
            reactData.inputValue = value;
            if (hasTimestampValueType(valueFormat)) {
                const dateVal = parseDateValue(value, type, { valueFormat: dateValueFormat });
                const timeNum = dateVal ? dateVal.getTime() : null;
                emit('update:modelValue', timeNum);
                if (modelValue !== timeNum) {
                    dispatchEvent('change', { value: timeNum }, evnt);
                    // 自动更新校验状态
                    if ($xeForm && formItemInfo) {
                        $xeForm.triggerItemEvent(evnt, formItemInfo.itemConfig.field, timeNum);
                    }
                }
            }
            else if (hasDateValueType(valueFormat)) {
                const dateVal = parseDateValue(value, type, { valueFormat: dateValueFormat });
                emit('update:modelValue', dateVal);
                if (modelValue && dateVal ? XEUtils.toStringDate(modelValue).getTime() !== dateVal.getTime() : modelValue !== dateVal) {
                    dispatchEvent('change', { value: dateVal }, evnt);
                    // 自动更新校验状态
                    if ($xeForm && formItemInfo) {
                        $xeForm.triggerItemEvent(evnt, formItemInfo.itemConfig.field, dateVal);
                    }
                }
            }
            else {
                emit('update:modelValue', value);
                if (XEUtils.toValueString(modelValue) !== value) {
                    dispatchEvent('change', { value }, evnt);
                    // 自动更新校验状态
                    if ($xeForm && formItemInfo) {
                        $xeForm.triggerItemEvent(evnt, formItemInfo.itemConfig.field, value);
                    }
                }
            }
        };
        const inputEvent = (evnt) => {
            const inputElem = evnt.target;
            const value = inputElem.value;
            reactData.inputLabel = value;
            dispatchEvent('input', { value }, evnt);
        };
        const changeEvent = (evnt) => {
            const inpImmediate = computeInpImmediate.value;
            if (!inpImmediate) {
                triggerEvent(evnt);
            }
        };
        const focusEvent = (evnt) => {
            const popupOpts = computePopupOpts.value;
            const { trigger } = popupOpts;
            reactData.isActivated = true;
            if (!trigger || trigger === 'default') {
                datePickerOpenEvent(evnt);
            }
            triggerEvent(evnt);
        };
        const clickPrefixEvent = (evnt) => {
            const isDisabled = computeIsDisabled.value;
            if (!isDisabled) {
                const { inputValue } = reactData;
                dispatchEvent('prefix-click', { value: inputValue }, evnt);
            }
        };
        const hidePanel = () => {
            return new Promise(resolve => {
                reactData.visiblePanel = false;
                internalData.hpTimeout = setTimeout(() => {
                    reactData.isAniVisible = false;
                    resolve();
                }, 350);
            });
        };
        const clearValueEvent = (evnt, value) => {
            const isDatePickerType = computeIsDatePickerType.value;
            if (isDatePickerType) {
                hidePanel();
            }
            handleChange('', evnt);
            dispatchEvent('clear', { value }, evnt);
        };
        const clickSuffixEvent = (evnt) => {
            const isDisabled = computeIsDisabled.value;
            if (!isDisabled) {
                const { inputValue } = reactData;
                dispatchEvent('suffix-click', { value: inputValue }, evnt);
            }
        };
        const blurEvent = (evnt) => {
            const $datePanel = refDatePanel.value;
            const { inputValue } = reactData;
            const inpImmediate = computeInpImmediate.value;
            const value = inputValue;
            if (!inpImmediate) {
                handleChange(value, evnt);
            }
            if (!reactData.visiblePanel) {
                reactData.isActivated = false;
                // 未打开面板时才校验
                if ($datePanel) {
                    $datePanel.checkValue(reactData.inputLabel);
                }
            }
            dispatchEvent('blur', { value }, evnt);
            // 自动更新校验状态
            if ($xeForm && formItemInfo) {
                $xeForm.triggerItemEvent(evnt, formItemInfo.itemConfig.field, value);
            }
        };
        const keydownEvent = (evnt) => {
            triggerEvent(evnt);
        };
        const keyupEvent = (evnt) => {
            triggerEvent(evnt);
        };
        const confirmEvent = (evnt) => {
            const $datePanel = refDatePanel.value;
            if ($datePanel) {
                $datePanel.confirmByEvent(evnt);
            }
            hidePanel();
        };
        const panelChangeEvent = (params) => {
            const { multiple, autoClose } = props;
            const { value, $event } = params;
            const isDateTimeType = computeIsDateTimeType.value;
            handleChange(value, $event);
            if (!multiple && !isDateTimeType) {
                if (autoClose) {
                    hidePanel();
                }
            }
        };
        const panelConfirmEvent = (params) => {
            dispatchEvent('confirm', params, params.$event);
        };
        const panelRevertEvent = (params) => {
            reactData.inputLabel = params.label;
        };
        // 全局事件
        const handleGlobalMousedownEvent = (evnt) => {
            const $datePanel = refDatePanel.value;
            const { visiblePanel, isActivated } = reactData;
            const el = refElem.value;
            const panelWrapperElem = refPanelWrapper.value;
            const isDisabled = computeIsDisabled.value;
            if (!isDisabled && isActivated) {
                reactData.isActivated = getEventTargetNode(evnt, el).flag || getEventTargetNode(evnt, panelWrapperElem).flag;
                if (!reactData.isActivated) {
                    if (visiblePanel) {
                        hidePanel();
                        if ($datePanel) {
                            $datePanel.checkValue(reactData.inputLabel);
                        }
                    }
                }
            }
        };
        const handleGlobalKeydownEvent = (evnt) => {
            const { visiblePanel } = reactData;
            const isDisabled = computeIsDisabled.value;
            if (!isDisabled) {
                const isTab = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.TAB);
                const isEsc = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ESCAPE);
                if (isTab) {
                    reactData.isActivated = false;
                }
                if (visiblePanel) {
                    if (isEsc || isTab) {
                        hidePanel();
                    }
                }
            }
        };
        const handleGlobalMousewheelEvent = (evnt) => {
            const { visiblePanel } = reactData;
            const isDisabled = computeIsDisabled.value;
            if (!isDisabled) {
                if (visiblePanel) {
                    const panelWrapperElem = refPanelWrapper.value;
                    if (getEventTargetNode(evnt, panelWrapperElem).flag) {
                        updatePlacement();
                    }
                    else {
                        hidePanel();
                    }
                }
            }
        };
        const handleGlobalBlurEvent = () => {
            const $datePanel = refDatePanel.value;
            const { isActivated, visiblePanel } = reactData;
            if (visiblePanel) {
                hidePanel();
            }
            if (isActivated) {
                reactData.isActivated = false;
            }
            if (visiblePanel || isActivated) {
                if ($datePanel) {
                    $datePanel.checkValue(reactData.inputLabel);
                }
                const targetElem = refInputTarget.value;
                if (targetElem) {
                    targetElem.blur();
                }
            }
        };
        const handleGlobalResizeEvent = () => {
            const { visiblePanel } = reactData;
            if (visiblePanel) {
                updatePlacement();
            }
        };
        // 弹出面板
        const updateZindex = () => {
            const popupOpts = computePopupOpts.value;
            const customZIndex = popupOpts.zIndex || props.zIndex;
            if (customZIndex) {
                reactData.panelIndex = XEUtils.toNumber(customZIndex);
            }
            else if (reactData.panelIndex < getLastZIndex()) {
                reactData.panelIndex = nextZIndex();
            }
        };
        const updatePlacement = () => {
            const { placement } = props;
            const { panelIndex } = reactData;
            const targetElem = refInputTarget.value;
            const panelElem = refInputPanel.value;
            const btnTransfer = computeBtnTransfer.value;
            const popupOpts = computePopupOpts.value;
            const handleStyle = () => {
                const ppObj = updatePanelPlacement(targetElem, panelElem, {
                    placement: popupOpts.placement || placement,
                    defaultPlacement: popupOpts.defaultPlacement,
                    teleportTo: btnTransfer
                });
                const panelStyle = Object.assign(ppObj.style, {
                    zIndex: panelIndex
                });
                reactData.panelStyle = panelStyle;
                reactData.panelPlacement = ppObj.placement;
            };
            handleStyle();
            return nextTick().then(handleStyle);
        };
        const showPanel = () => {
            const { visiblePanel } = reactData;
            const isDisabled = computeIsDisabled.value;
            if (!isDisabled && !visiblePanel) {
                if (!reactData.initialized) {
                    reactData.initialized = true;
                }
                if (internalData.hpTimeout) {
                    clearTimeout(internalData.hpTimeout);
                    internalData.hpTimeout = undefined;
                }
                reactData.isActivated = true;
                reactData.isAniVisible = true;
                setTimeout(() => {
                    reactData.visiblePanel = true;
                    updatePlacement();
                }, 10);
                updateZindex();
                return updatePlacement();
            }
            return nextTick();
        };
        const datePickerOpenEvent = (evnt) => {
            const formReadonly = computeFormReadonly.value;
            if (!formReadonly) {
                evnt.preventDefault();
                showPanel();
            }
        };
        const clickIconEvent = (evnt) => {
            const popupOpts = computePopupOpts.value;
            const { trigger } = popupOpts;
            if (!trigger || trigger === 'default' || trigger === 'icon') {
                datePickerOpenEvent(evnt);
            }
        };
        const clickEvent = (evnt) => {
            triggerEvent(evnt);
        };
        const handleShortcutEvent = ({ option, $event }) => {
            const { type } = props;
            const { inputValue } = reactData;
            const shortcutOpts = computeShortcutOpts.value;
            const { autoClose } = shortcutOpts;
            const { code, clickMethod } = option;
            let value = inputValue;
            const shortcutParams = {
                $datePicker: $xeDatePicker,
                option,
                value,
                code
            };
            if (!clickMethod && code) {
                const gCommandOpts = commands.get(code);
                const dpCommandMethod = gCommandOpts ? gCommandOpts.datePickerCommandMethod : null;
                if (dpCommandMethod) {
                    dpCommandMethod(shortcutParams);
                }
                else {
                    const dateValueFormat = computeDateValueFormat.value;
                    const firstDayOfWeek = computeFirstDayOfWeek.value;
                    switch (code) {
                        case 'now':
                        case 'prev':
                        case 'next':
                        case 'minus':
                        case 'plus': {
                            const restObj = getDateByCode(code, value, type, {
                                valueFormat: dateValueFormat,
                                firstDay: firstDayOfWeek
                            });
                            value = restObj.value;
                            shortcutParams.value = value;
                            handleChange(value, $event);
                            break;
                        }
                        default:
                            errLog('vxe.error.notCommands', [`[date-picker] ${code}`]);
                            break;
                    }
                }
            }
            else {
                const optClickMethod = clickMethod || shortcutOpts.clickMethod;
                if (optClickMethod) {
                    optClickMethod(shortcutParams);
                }
            }
            if (autoClose) {
                hidePanel();
            }
            dispatchEvent('shortcut-click', shortcutParams, $event);
        };
        const dispatchEvent = (type, params, evnt) => {
            emit(type, createEvent(evnt, { $datePicker: $xeDatePicker }, params));
        };
        const datePickerMethods = {
            dispatchEvent,
            setModelValue(value) {
                reactData.inputValue = value;
                emit('update:modelValue', value);
            },
            setModelValueByEvent(evnt, value) {
                handleChange(value || '', evnt);
            },
            focus() {
                const inputElem = refInputTarget.value;
                reactData.isActivated = true;
                inputElem.focus();
                return nextTick();
            },
            blur() {
                const inputElem = refInputTarget.value;
                inputElem.blur();
                reactData.isActivated = false;
                return nextTick();
            },
            select() {
                const inputElem = refInputTarget.value;
                inputElem.select();
                reactData.isActivated = false;
                return nextTick();
            },
            showPanel,
            hidePanel,
            updatePlacement
        };
        Object.assign($xeDatePicker, datePickerMethods);
        const renderShortcutBtn = (pos, isVertical) => {
            const shortcutOpts = computeShortcutOpts.value;
            const { position, align, mode } = shortcutOpts;
            const shortcutList = computeShortcutList.value;
            if (isEnableConf(shortcutOpts) && shortcutList.length && (position || 'left') === pos) {
                return h('div', {
                    class: `vxe-date-picker--layout-${pos}-wrapper`
                }, [
                    h(VxeButtonGroupComponent, {
                        options: shortcutList,
                        mode,
                        align,
                        vertical: isVertical,
                        onClick: handleShortcutEvent
                    })
                ]);
            }
            return renderEmptyElement($xeDatePicker);
        };
        const renderPanel = () => {
            const { type, multiple, showClearButton, showConfirmButton } = props;
            const { initialized, isAniVisible, visiblePanel, panelPlacement, panelStyle, inputValue } = reactData;
            const vSize = computeSize.value;
            const btnTransfer = computeBtnTransfer.value;
            const shortcutOpts = computeShortcutOpts.value;
            const isClearable = computeIsClearable.value;
            const isDateTimeType = computeIsDateTimeType.value;
            const shortcutList = computeShortcutList.value;
            const timeOpts = computeTimeOpts.value;
            const popupOpts = computePopupOpts.value;
            const { position } = shortcutOpts;
            const headerSlot = slots.header;
            const footerSlot = slots.footer;
            const topSlot = slots.top;
            const bottomSlot = slots.bottom;
            const leftSlot = slots.left;
            const rightSlot = slots.right;
            const ppClassName = popupOpts.className;
            const hasShortcutBtn = shortcutList.length > 0;
            const showConfirmBtn = (showConfirmButton === null ? (isDateTimeType || multiple) : showConfirmButton);
            const showClearBtn = (showClearButton === null ? (isClearable && showConfirmBtn && type !== 'time') : showClearButton);
            return h(Teleport, {
                to: 'body',
                disabled: btnTransfer ? !initialized : true
            }, [
                h('div', {
                    ref: refInputPanel,
                    class: ['vxe-table--ignore-clear vxe-date-picker--panel', `type--${type}`, ppClassName ? (XEUtils.isFunction(ppClassName) ? ppClassName({ $datePicker: $xeDatePicker }) : ppClassName) : '', {
                            [`size--${vSize}`]: vSize,
                            'is--transfer': btnTransfer,
                            'ani--leave': isAniVisible,
                            'ani--enter': visiblePanel,
                            'show--top': !!(topSlot || headerSlot || (hasShortcutBtn && (position === 'top' || position === 'header'))),
                            'show--bottom': !!(bottomSlot || footerSlot || (hasShortcutBtn && (position === 'bottom' || position === 'footer'))),
                            'show--left': !!(leftSlot || (hasShortcutBtn && position === 'left')),
                            'show--right': !!(rightSlot || (hasShortcutBtn && position === 'right'))
                        }],
                    placement: panelPlacement,
                    style: panelStyle
                }, initialized && (visiblePanel || isAniVisible)
                    ? [
                        h('div', {
                            ref: refPanelWrapper,
                            class: ['vxe-date-picker--layout-all-wrapper', `type--${type}`, {
                                    [`size--${vSize}`]: vSize
                                }]
                        }, [
                            topSlot
                                ? h('div', {
                                    class: 'vxe-date-picker--layout-top-wrapper'
                                }, topSlot({}))
                                : renderShortcutBtn('top'),
                            h('div', {
                                class: 'vxe-date-picker--layout-body-layout-wrapper'
                            }, [
                                leftSlot
                                    ? h('div', {
                                        class: 'vxe-date-picker--layout-left-wrapper'
                                    }, leftSlot({}))
                                    : renderShortcutBtn('left', true),
                                h('div', {
                                    class: 'vxe-date-picker--layout-body-content-wrapper'
                                }, [
                                    headerSlot
                                        ? h('div', {
                                            class: 'vxe-date-picker--layout-header-wrapper'
                                        }, headerSlot({}))
                                        : renderShortcutBtn('header'),
                                    h('div', {
                                        class: 'vxe-date-picker--layout-body-wrapper'
                                    }, [
                                        h(VxeDatePanelComponent, {
                                            ref: refDatePanel,
                                            modelValue: reactData.inputValue,
                                            type: props.type,
                                            className: props.className,
                                            multiple: props.multiple,
                                            limitCount: props.limitCount,
                                            startDate: props.startDate,
                                            endDate: props.endDate,
                                            defaultDate: props.defaultDate,
                                            defaultTime: props.defaultTime,
                                            minDate: props.minDate,
                                            maxDate: props.maxDate,
                                            startDay: props.startDay,
                                            labelFormat: props.labelFormat,
                                            valueFormat: props.valueFormat,
                                            timeFormat: props.timeFormat,
                                            timeConfig: timeOpts,
                                            festivalMethod: props.festivalMethod,
                                            disabledMethod: props.disabledMethod,
                                            selectDay: props.selectDay,
                                            onChange: panelChangeEvent,
                                            onConfirm: panelConfirmEvent,
                                            onRevert: panelRevertEvent
                                        })
                                    ]),
                                    h('div', {
                                        class: 'vxe-date-picker--layout-footer-wrapper'
                                    }, [
                                        h('div', {
                                            class: 'vxe-date-picker--layout-footer-custom'
                                        }, footerSlot ? footerSlot({}) : [renderShortcutBtn('footer')]),
                                        showClearBtn || showConfirmBtn
                                            ? h('div', {
                                                class: 'vxe-date-picker--layout-footer-btns'
                                            }, [
                                                showClearBtn
                                                    ? h(VxeButtonComponent, {
                                                        size: 'mini',
                                                        disabled: inputValue === '' || XEUtils.eqNull(inputValue),
                                                        content: getI18n('vxe.button.clear'),
                                                        onClick: clearValueEvent
                                                    })
                                                    : renderEmptyElement($xeDatePicker),
                                                showConfirmBtn
                                                    ? h(VxeButtonComponent, {
                                                        size: 'mini',
                                                        status: 'primary',
                                                        content: getI18n('vxe.button.confirm'),
                                                        onClick: confirmEvent
                                                    })
                                                    : renderEmptyElement($xeDatePicker)
                                            ])
                                            : renderEmptyElement($xeDatePicker)
                                    ])
                                ]),
                                rightSlot
                                    ? h('div', {
                                        class: 'vxe-date-picker--layout-right-wrapper'
                                    }, rightSlot({}))
                                    : renderShortcutBtn('right', true)
                            ]),
                            bottomSlot
                                ? h('div', {
                                    class: 'vxe-date-picker--layout-bottom-wrapper'
                                }, bottomSlot({}))
                                : renderShortcutBtn('bottom')
                        ])
                    ]
                    : [])
            ]);
        };
        const renderPrefixIcon = () => {
            const { prefixIcon } = props;
            const prefixSlot = slots.prefix;
            return prefixSlot || prefixIcon
                ? h('div', {
                    class: 'vxe-date-picker--prefix',
                    onClick: clickPrefixEvent
                }, [
                    h('div', {
                        class: 'vxe-date-picker--prefix-icon'
                    }, prefixSlot
                        ? getSlotVNs(prefixSlot({}))
                        : [
                            h('i', {
                                class: prefixIcon
                            })
                        ])
                ])
                : null;
        };
        const renderSuffixIcon = () => {
            const { suffixIcon } = props;
            const { inputValue } = reactData;
            const suffixSlot = slots.suffix;
            const isDisabled = computeIsDisabled.value;
            const isClearable = computeIsClearable.value;
            return h('div', {
                class: ['vxe-date-picker--suffix', {
                        'is--clear': isClearable && !isDisabled && !(inputValue === '' || XEUtils.eqNull(inputValue))
                    }]
            }, [
                isClearable
                    ? h('div', {
                        class: 'vxe-date-picker--clear-icon',
                        onClick: clearValueEvent
                    }, [
                        h('i', {
                            class: getIcon().INPUT_CLEAR
                        })
                    ])
                    : renderEmptyElement($xeDatePicker),
                renderExtraSuffixIcon(),
                suffixSlot || suffixIcon
                    ? h('div', {
                        class: 'vxe-date-picker--suffix-icon',
                        onClick: clickSuffixEvent
                    }, suffixSlot
                        ? getSlotVNs(suffixSlot({}))
                        : [
                            h('i', {
                                class: suffixIcon
                            })
                        ])
                    : renderEmptyElement($xeDatePicker)
            ]);
        };
        const renderExtraSuffixIcon = () => {
            return h('div', {
                class: 'vxe-date-picker--control-icon',
                onClick: clickIconEvent
            }, [
                h('i', {
                    class: ['vxe-date-picker--date-picker-icon', getIcon().DATE_PICKER_DATE]
                })
            ]);
        };
        const renderVN = () => {
            const { className, type, name, autoComplete } = props;
            const { inputValue, inputLabel, visiblePanel, isActivated } = reactData;
            const vSize = computeSize.value;
            const isDisabled = computeIsDisabled.value;
            const formReadonly = computeFormReadonly.value;
            const panelLabel = computePanelLabel.value;
            if (formReadonly) {
                return h('div', {
                    ref: refElem,
                    class: ['vxe-date-picker--readonly', `type--${type}`, className]
                }, panelLabel);
            }
            const inputReadonly = computeInputReadonly.value;
            const inpPlaceholder = computeInpPlaceholder.value;
            const isClearable = computeIsClearable.value;
            const prefix = renderPrefixIcon();
            const suffix = renderSuffixIcon();
            return h('div', {
                ref: refElem,
                class: ['vxe-date-picker', `type--${type}`, className, {
                        [`size--${vSize}`]: vSize,
                        'is--prefix': !!prefix,
                        'is--suffix': !!suffix,
                        'is--visible': visiblePanel,
                        'is--disabled': isDisabled,
                        'is--active': isActivated,
                        'show--clear': isClearable && !isDisabled && !(inputValue === '' || XEUtils.eqNull(inputValue))
                    }],
                spellcheck: false
            }, [
                prefix || renderEmptyElement($xeDatePicker),
                h('div', {
                    class: 'vxe-date-picker--wrapper'
                }, [
                    h('input', {
                        ref: refInputTarget,
                        class: 'vxe-date-picker--inner',
                        value: inputLabel,
                        name,
                        type: 'text',
                        placeholder: inpPlaceholder,
                        readonly: inputReadonly,
                        disabled: isDisabled,
                        autocomplete: autoComplete,
                        onKeydown: keydownEvent,
                        onKeyup: keyupEvent,
                        onClick: clickEvent,
                        onInput: inputEvent,
                        onChange: changeEvent,
                        onFocus: focusEvent,
                        onBlur: blurEvent
                    })
                ]),
                suffix || renderEmptyElement($xeDatePicker),
                // 下拉面板
                renderPanel()
            ]);
        };
        watch(computePanelLabel, (val) => {
            reactData.inputLabel = val;
        });
        watch(() => props.modelValue, () => {
            updateModelValue();
        });
        nextTick(() => {
            globalEvents.on($xeDatePicker, 'mousewheel', handleGlobalMousewheelEvent);
            globalEvents.on($xeDatePicker, 'mousedown', handleGlobalMousedownEvent);
            globalEvents.on($xeDatePicker, 'keydown', handleGlobalKeydownEvent);
            globalEvents.on($xeDatePicker, 'blur', handleGlobalBlurEvent);
            globalEvents.on($xeDatePicker, 'resize', handleGlobalResizeEvent);
        });
        onUnmounted(() => {
            globalEvents.off($xeDatePicker, 'mousewheel');
            globalEvents.off($xeDatePicker, 'mousedown');
            globalEvents.off($xeDatePicker, 'blur');
            globalEvents.off($xeDatePicker, 'resize');
        });
        updateModelValue();
        provide('$xeDatePicker', $xeDatePicker);
        $xeDatePicker.renderVN = renderVN;
        return $xeDatePicker;
    },
    render() {
        return this.renderVN();
    }
});
