import { h } from "@stencil/core";
import { getCalendarDays, parseDate, formatDate, addMonths, isSameDay, MONTH_NAMES, WEEK_DAY_NAMES, } from "../../utils/date-helpers";
import { createClickOutsideHandler } from "../../utils/click-outside";
/**
 * DateRangePicker 日期范围选择器组件
 * 选择开始与结束日期，展开双月份面板（右月 = 左月 + 1）
 */
export class DateRangePicker {
    el;
    /** 绑定值 [start, end]，ISO 字符串 */
    modelValue = [];
    /** 占位文本 [startPlaceholder, endPlaceholder] */
    placeholder = ['开始日期', '结束日期'];
    /** 是否禁用 */
    disabled = false;
    /** 是否可清空 */
    clearable = false;
    /** 尺寸 */
    size = 'default';
    /** 日期格式 */
    format = 'YYYY-MM-DD';
    /**
     * 禁用日期判定函数。返回 true 的日期在日历中不可选（加 disabled 态、不可点击、aria-disabled）。
     * @param date 当前日期格子的 Date 对象
     */
    disabledDate;
    /** 原生 name 属性 */
    name;
    /** 范围改变事件，detail 为 [start, end] */
    hbChange;
    /** 面板展开/收起事件 */
    hbVisibleChange;
    /** 面板是否展开 */
    isOpen = false;
    /** 左侧面板视图月份 */
    leftViewDate = new Date();
    /** 范围起点（Date 形式，选择中暂存） */
    startDate;
    /** 范围终点（Date 形式，选择中暂存） */
    endDate;
    /** 是否已选了起点，等待选终点 */
    pickingEnd = false;
    /** hover 中的日期，用于高亮范围 */
    hoverDate;
    clickOutside = createClickOutsideHandler({
        host: null,
        isOpen: () => this.isOpen,
        onClose: () => this.closePanel(),
    });
    componentDidLoad() {
        this.clickOutside = createClickOutsideHandler({
            host: this.el,
            isOpen: () => this.isOpen,
            onClose: () => this.closePanel(),
        });
        this.clickOutside.connect();
        this.syncFromModelValue();
    }
    disconnectedCallback() {
        this.clickOutside.disconnect();
    }
    handleModelValueChange() {
        this.syncFromModelValue();
    }
    syncFromModelValue() {
        if (!this.modelValue || this.modelValue.length === 0) {
            this.startDate = undefined;
            this.endDate = undefined;
            this.pickingEnd = false;
            return;
        }
        this.startDate = parseDate(this.modelValue[0]);
        this.endDate = parseDate(this.modelValue[1]);
        this.pickingEnd = false;
    }
    get displayStart() {
        return this.startDate ? formatDate(this.startDate, this.format) : '';
    }
    get displayEnd() {
        return this.endDate ? formatDate(this.endDate, this.format) : '';
    }
    openPanel() {
        if (this.disabled)
            return;
        this.isOpen = true;
        this.hbVisibleChange.emit(true);
    }
    closePanel() {
        if (!this.isOpen)
            return;
        this.isOpen = false;
        this.hoverDate = undefined;
        this.pickingEnd = false;
        this.hbVisibleChange.emit(false);
    }
    handleTriggerClick = () => {
        if (this.disabled)
            return;
        if (this.isOpen) {
            this.closePanel();
        }
        else {
            this.openPanel();
        }
    };
    handleClear = (e) => {
        e.stopPropagation();
        this.startDate = undefined;
        this.endDate = undefined;
        this.pickingEnd = false;
        this.modelValue = [];
        this.hbChange.emit([]);
        this.closePanel();
    };
    changeMonth(delta) {
        this.leftViewDate = addMonths(this.leftViewDate, delta);
    }
    /** 判断某日期是否被 disabledDate 禁用 */
    isDateDisabled = (date) => {
        return !!this.disabledDate && this.disabledDate(date);
    };
    /** 点击某一日格 */
    handleDayClick = (date) => {
        // disabledDate 返回 true 的日期不可选
        if (this.isDateDisabled(date))
            return;
        if (!this.startDate || (this.startDate && this.endDate) || !this.pickingEnd) {
            // 起点（或重新开始选择）
            this.startDate = date;
            this.endDate = undefined;
            this.pickingEnd = true;
            return;
        }
        // 选终点
        if (date.getTime() < this.startDate.getTime()) {
            // 终点早于起点：交换，将新点作为起点
            this.endDate = this.startDate;
            this.startDate = date;
        }
        else {
            this.endDate = date;
        }
        this.pickingEnd = false;
        this.commitRange();
    };
    commitRange() {
        if (!this.startDate || !this.endDate)
            return;
        const start = formatDate(this.startDate, this.format);
        const end = formatDate(this.endDate, this.format);
        this.modelValue = [start, end];
        this.hbChange.emit([start, end]);
        this.closePanel();
    }
    handleDayHover = (date) => {
        if (this.pickingEnd) {
            this.hoverDate = date;
        }
    };
    /** 计算某日格的状态 */
    isStart(date) {
        return !!this.startDate && isSameDay(this.startDate, date);
    }
    isEnd(date) {
        return !!this.endDate && isSameDay(this.endDate, date);
    }
    isInRange(date) {
        if (!this.startDate)
            return false;
        const end = this.endDate || this.hoverDate;
        if (!end)
            return false;
        const t = date.getTime();
        const startT = this.startDate.getTime();
        const endT = end.getTime();
        const lo = Math.min(startT, endT);
        const hi = Math.max(startT, endT);
        return t > lo && t < hi;
    }
    renderMonth(viewDate, side) {
        const days = getCalendarDays(viewDate, undefined);
        return (h("div", { class: "hb-date-range-picker__pane" }, h("div", { class: "hb-date-range-picker__header" }, side === 'left' && (h("button", { type: "button", class: "hb-date-range-picker__prev-btn", onClick: () => this.changeMonth(-1), "aria-label": "\u4E0A\u4E2A\u6708" }, "\u2039")), h("span", { class: "hb-date-range-picker__header-label" }, viewDate.getFullYear(), "\u5E74 ", MONTH_NAMES[viewDate.getMonth()]), side === 'right' && (h("button", { type: "button", class: "hb-date-range-picker__next-btn", onClick: () => this.changeMonth(1), "aria-label": "\u4E0B\u4E2A\u6708" }, "\u203A"))), h("div", { class: "hb-date-range-picker__weekdays" }, WEEK_DAY_NAMES.map((day) => (h("div", { class: "hb-date-range-picker__weekday" }, day)))), h("div", { class: "hb-date-range-picker__days" }, days.map((day, index) => {
            const dayDisabled = day.isCurrentMonth && this.isDateDisabled(day.date);
            return (h("div", { key: index, class: {
                    'hb-date-range-picker__day': true,
                    'hb-date-range-picker__day--other-month': !day.isCurrentMonth,
                    'hb-date-range-picker__day--today': day.isToday,
                    'hb-date-range-picker__day--start': this.isStart(day.date),
                    'hb-date-range-picker__day--end': this.isEnd(day.date),
                    'hb-date-range-picker__day--in-range': this.isInRange(day.date),
                    'hb-date-range-picker__day--disabled': dayDisabled,
                }, role: "gridcell", "aria-disabled": !day.isCurrentMonth || dayDisabled ? 'true' : undefined, onClick: () => day.isCurrentMonth && !dayDisabled && this.handleDayClick(day.date), onMouseEnter: () => day.isCurrentMonth && !dayDisabled && this.handleDayHover(day.date) }, day.date.getDate()));
        }))));
    }
    render() {
        const rightViewDate = addMonths(this.leftViewDate, 1);
        const showClear = this.clearable && !!this.startDate && !!this.endDate && !this.disabled;
        return (h("div", { key: 'ab2b71304782a01f2cc8ac7330a20a3172c17fd5', class: {
                'hb-date-range-picker': true,
                'hb-date-range-picker--open': this.isOpen,
                'hb-date-range-picker--disabled': this.disabled,
                [`hb-date-range-picker--${this.size}`]: true,
            } }, h("div", { key: '8e0bdbd8de6b7881e555072c84689654e3a43a17', class: "hb-date-range-picker__input-wrapper", onClick: this.handleTriggerClick }, h("input", { key: '478634c74c6f001c0213e1591497679618f0c30c', type: "text", name: this.name, class: "hb-date-range-picker__input", placeholder: this.placeholder[0] || '开始日期', value: this.displayStart, disabled: this.disabled, readonly: true }), h("span", { key: 'bb7827695f0cbab0267f704bf89b17df3bb6e87a', class: "hb-date-range-picker__separator" }, "\u81F3"), h("input", { key: '010d1e8d5ebfc98a892ecb00a1489fbc9d59f7f0', type: "text", class: "hb-date-range-picker__input", placeholder: this.placeholder[1] || '结束日期', value: this.displayEnd, disabled: this.disabled, readonly: true }), h("span", { key: 'fe43d0f5ddbd4c80a9cecf1c49e2bc4cab2f9f5b', class: "hb-date-range-picker__suffix" }, showClear && (h("span", { key: 'e215b4eb8bde0de50f17092527cd882381188f2a', class: "hb-date-range-picker__clear", onClick: this.handleClear }, "\u00D7")), h("span", { key: 'f7610ce152b6b61b8014b6cba213188bb1f4ad4a', class: "hb-date-range-picker__icon" }, "\uD83D\uDCC5"))), this.isOpen && (h("div", { key: '72045b3c598a61515e8d7d0ea15a3865b9efaf20', class: "hb-date-range-picker__dropdown" }, this.renderMonth(this.leftViewDate, 'left'), this.renderMonth(rightViewDate, 'right')))));
    }
    static get is() { return "hb-date-range-picker"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["date-range-picker.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["date-range-picker.css"]
        };
    }
    static get properties() {
        return {
            "modelValue": {
                "type": "unknown",
                "mutable": true,
                "complexType": {
                    "original": "string[]",
                    "resolved": "string[]",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "\u7ED1\u5B9A\u503C [start, end]\uFF0CISO \u5B57\u7B26\u4E32"
                },
                "getter": false,
                "setter": false,
                "defaultValue": "[]"
            },
            "placeholder": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "string[]",
                    "resolved": "string[]",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "\u5360\u4F4D\u6587\u672C [startPlaceholder, endPlaceholder]"
                },
                "getter": false,
                "setter": false,
                "defaultValue": "['\u5F00\u59CB\u65E5\u671F', '\u7ED3\u675F\u65E5\u671F']"
            },
            "disabled": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "\u662F\u5426\u7981\u7528"
                },
                "getter": false,
                "setter": false,
                "attribute": "disabled",
                "reflect": false,
                "defaultValue": "false"
            },
            "clearable": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "\u662F\u5426\u53EF\u6E05\u7A7A"
                },
                "getter": false,
                "setter": false,
                "attribute": "clearable",
                "reflect": false,
                "defaultValue": "false"
            },
            "size": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "ComponentSize",
                    "resolved": "\"default\" | \"large\" | \"small\"",
                    "references": {
                        "ComponentSize": {
                            "location": "import",
                            "path": "../../utils/form-input-base",
                            "id": "src/utils/form-input-base.ts::ComponentSize"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "\u5C3A\u5BF8"
                },
                "getter": false,
                "setter": false,
                "attribute": "size",
                "reflect": false,
                "defaultValue": "'default'"
            },
            "format": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "\u65E5\u671F\u683C\u5F0F"
                },
                "getter": false,
                "setter": false,
                "attribute": "format",
                "reflect": false,
                "defaultValue": "'YYYY-MM-DD'"
            },
            "disabledDate": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "(date: Date) => boolean",
                    "resolved": "(date: Date) => boolean",
                    "references": {
                        "Date": {
                            "location": "global",
                            "id": "global::Date"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "param",
                            "text": "date \u5F53\u524D\u65E5\u671F\u683C\u5B50\u7684 Date \u5BF9\u8C61"
                        }],
                    "text": "\u7981\u7528\u65E5\u671F\u5224\u5B9A\u51FD\u6570\u3002\u8FD4\u56DE true \u7684\u65E5\u671F\u5728\u65E5\u5386\u4E2D\u4E0D\u53EF\u9009\uFF08\u52A0 disabled \u6001\u3001\u4E0D\u53EF\u70B9\u51FB\u3001aria-disabled\uFF09\u3002"
                },
                "getter": false,
                "setter": false
            },
            "name": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "\u539F\u751F name \u5C5E\u6027"
                },
                "getter": false,
                "setter": false,
                "attribute": "name",
                "reflect": false
            }
        };
    }
    static get states() {
        return {
            "isOpen": {},
            "leftViewDate": {},
            "startDate": {},
            "endDate": {},
            "pickingEnd": {},
            "hoverDate": {}
        };
    }
    static get events() {
        return [{
                "method": "hbChange",
                "name": "hbChange",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "\u8303\u56F4\u6539\u53D8\u4E8B\u4EF6\uFF0Cdetail \u4E3A [start, end]"
                },
                "complexType": {
                    "original": "string[]",
                    "resolved": "string[]",
                    "references": {}
                }
            }, {
                "method": "hbVisibleChange",
                "name": "hbVisibleChange",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "\u9762\u677F\u5C55\u5F00/\u6536\u8D77\u4E8B\u4EF6"
                },
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                }
            }];
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "modelValue",
                "methodName": "handleModelValueChange"
            }];
    }
}
//# sourceMappingURL=DateRangePicker.js.map
