"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vue_1 = require("vue");
const date_fns_1 = require("date-fns");
const vooks_1 = require("vooks");
const utils_1 = require("../../date-picker/src/utils");
const icons_1 = require("../../_internal/icons");
const _internal_1 = require("../../_internal");
const _utils_1 = require("../../_utils");
const button_1 = require("../../button");
const _mixins_1 = require("../../_mixins");
const styles_1 = require("../styles");
const index_cssr_1 = require("./styles/index.cssr");
const calendarProps = Object.assign(Object.assign({}, _mixins_1.useTheme.props), { isDateDisabled: Function, value: Number, defaultValue: {
        type: Number,
        defualt: null
    }, 'onUpdate:value': [Function, Array], onUpdateValue: [Function, Array] });
exports.default = vue_1.defineComponent({
    name: 'Calendar',
    props: calendarProps,
    setup(props) {
        const { mergedClsPrefixRef } = _mixins_1.useConfig(props);
        const themeRef = _mixins_1.useTheme('Calendar', 'Calendar', index_cssr_1.default, styles_1.calendarLight, props, mergedClsPrefixRef);
        const { localeRef, dateLocaleRef } = _mixins_1.useLocale('DatePicker');
        const now = Date.now();
        // ts => timestamp
        const monthTsRef = vue_1.ref(date_fns_1.startOfMonth(now).valueOf());
        const uncontrolledValueRef = vue_1.ref(null);
        const mergedValueRef = vooks_1.useMergedState(vue_1.toRef(props, 'value'), uncontrolledValueRef);
        function doUpdateValue(value, time) {
            const { onUpdateValue, 'onUpdate:value': _onUpdateValue } = props;
            if (onUpdateValue) {
                _utils_1.call(onUpdateValue, value, time);
            }
            if (_onUpdateValue) {
                _utils_1.call(_onUpdateValue, value, time);
            }
            uncontrolledValueRef.value = value;
        }
        function handlePrevClick() {
            monthTsRef.value = date_fns_1.addMonths(monthTsRef.value, -1).valueOf();
        }
        function handleNextClick() {
            monthTsRef.value = date_fns_1.addMonths(monthTsRef.value, 1).valueOf();
        }
        function handleTodayClick() {
            monthTsRef.value = date_fns_1.startOfMonth(now).valueOf();
        }
        return {
            mergedClsPrefix: mergedClsPrefixRef,
            locale: localeRef,
            dateLocale: dateLocaleRef,
            now,
            mergedValue: mergedValueRef,
            monthTs: monthTsRef,
            dateItems: vue_1.computed(() => {
                return utils_1.dateArray(monthTsRef.value, mergedValueRef.value, now, localeRef.value.firstDayOfWeek, true);
            }),
            doUpdateValue,
            handleTodayClick,
            handlePrevClick,
            handleNextClick,
            mergedTheme: themeRef,
            cssVars: vue_1.computed(() => {
                const { common: { cubicBezierEaseInOut }, self: { borderColor, borderColorModal, borderColorPopover, borderRadius, titleFontSize, textColor, titleFontWeight, titleTextColor, dayTextColor, fontSize, lineHeight, dateColorCurrent, dateTextColorCurrent, cellColorHover, cellColor, cellColorModal, barColor, cellColorPopover, cellColorHoverModal, cellColorHoverPopover } } = themeRef.value;
                return {
                    '--bezier': cubicBezierEaseInOut,
                    '--border-color': borderColor,
                    '--border-color-modal': borderColorModal,
                    '--border-color-popover': borderColorPopover,
                    '--border-radius': borderRadius,
                    '--text-color': textColor,
                    '--title-font-weight': titleFontWeight,
                    '--title-font-size': titleFontSize,
                    '--title-text-color': titleTextColor,
                    '--day-text-color': dayTextColor,
                    '--font-size': fontSize,
                    '--line-height': lineHeight,
                    '--date-color-current': dateColorCurrent,
                    '--date-text-color-current': dateTextColorCurrent,
                    '--cell-color': cellColor,
                    '--cell-color-modal': cellColorModal,
                    '--cell-color-popover': cellColorPopover,
                    '--cell-color-hover': cellColorHover,
                    '--cell-color-hover-modal': cellColorHoverModal,
                    '--cell-color-hover-popover': cellColorHoverPopover,
                    '--bar-color': barColor
                };
            })
        };
    },
    render() {
        const { isDateDisabled, mergedClsPrefix, monthTs, cssVars, mergedValue, mergedTheme, locale: { monthBeforeYear, today }, dateLocale: { locale }, handleTodayClick, handlePrevClick, handleNextClick } = this;
        const normalizedValue = mergedValue && date_fns_1.startOfDay(mergedValue).valueOf();
        const localeMonth = date_fns_1.format(monthTs, 'MMMM', { locale });
        const year = date_fns_1.getYear(monthTs);
        const title = monthBeforeYear
            ? `${localeMonth} ${year}`
            : `${year} ${localeMonth}`;
        return (vue_1.h("div", { class: `${mergedClsPrefix}-calendar`, style: cssVars },
            vue_1.h("div", { class: `${mergedClsPrefix}-calendar-header` },
                vue_1.h("div", { class: `${mergedClsPrefix}-calendar-header__title` }, title),
                vue_1.h("div", { class: `${mergedClsPrefix}-calendar-header__extra` },
                    vue_1.h(button_1.NButtonGroup, null, {
                        default: () => (vue_1.h(vue_1.Fragment, null,
                            vue_1.h(button_1.NButton, { size: "small", onClick: handlePrevClick, theme: mergedTheme.peers.Button, themeOverrides: mergedTheme.peerOverrides.Button }, {
                                icon: () => (vue_1.h(_internal_1.NBaseIcon, { clsPrefix: mergedClsPrefix, class: `${mergedClsPrefix}-calendar-prev-btn` }, { default: () => vue_1.h(icons_1.ChevronLeftIcon, null) }))
                            }),
                            vue_1.h(button_1.NButton, { size: "small", onClick: handleTodayClick, theme: mergedTheme.peers.Button, themeOverrides: mergedTheme.peerOverrides.Button }, { default: () => today }),
                            vue_1.h(button_1.NButton, { size: "small", onClick: handleNextClick, theme: mergedTheme.peers.Button, themeOverrides: mergedTheme.peerOverrides.Button }, {
                                icon: () => (vue_1.h(_internal_1.NBaseIcon, { clsPrefix: mergedClsPrefix, class: `${mergedClsPrefix}-calendar-next-btn` }, { default: () => vue_1.h(icons_1.ChevronRightIcon, null) }))
                            })))
                    }))),
            vue_1.h("div", { class: `${mergedClsPrefix}-calendar-dates` }, this.dateItems.map(({ dateObject, ts, inCurrentMonth, isCurrentDate }, index) => {
                const { year, month, date } = dateObject;
                const disabled = !inCurrentMonth || (isDateDisabled === null || isDateDisabled === void 0 ? void 0 : isDateDisabled(ts)) === true;
                const selected = normalizedValue === date_fns_1.startOfDay(ts).valueOf();
                return (vue_1.h("div", { key: isCurrentDate ? 'current' : index, class: [
                        `${mergedClsPrefix}-calendar-cell`,
                        disabled && `${mergedClsPrefix}-calendar-cell--disabled`,
                        isCurrentDate &&
                            `${mergedClsPrefix}-calendar-cell--current`,
                        selected && `${mergedClsPrefix}-calendar-cell--selected`
                    ], onClick: () => {
                        this.doUpdateValue(ts, {
                            year,
                            month: month + 1,
                            date
                        });
                        this.monthTs = date_fns_1.startOfMonth(ts).valueOf();
                    } },
                    vue_1.h("div", { class: `${mergedClsPrefix}-calendar-date` },
                        disabled ? (vue_1.h("div", { class: `${mergedClsPrefix}-calendar-date__date`, key: "disabled" }, date)) : (vue_1.h("div", { class: `${mergedClsPrefix}-calendar-date__date`, key: "available" }, date)),
                        index < 7 && (vue_1.h("div", { class: `${mergedClsPrefix}-calendar-date__day` }, date_fns_1.format(ts, 'EEE', {
                            locale
                        })))),
                    vue_1.renderSlot(this.$slots, 'default', {
                        year,
                        month: month + 1,
                        date
                    }),
                    vue_1.h("div", { class: `${mergedClsPrefix}-calendar-cell__bar`, key: month })));
            }))));
    }
});
