import { EasePicker } from "../../utils/easepicker";
import { Host, h } from "@stencil/core";
import { cls, getId, isEmpty } from "../../utils/helpers";
import { DateTime } from "../../utils/datetime";
import { Lang } from "../../services/lang";
export class XDatepicker {
    constructor() {
        /**
         * Element ID for internal reference
         */
        this.inputId = getId('datepicker');
        /**
         * Element input picker instance
         */
        this.picker = null;
        this.label = undefined;
        this.name = undefined;
        this.info = undefined;
        this.format = 'DD-MM-YYYY';
        this.loading = undefined;
        this.cleanable = undefined;
        this.ranged = undefined;
        this.required = undefined;
        this.rangedDelimiter = " > ";
        this.width = undefined;
        this.value = '';
        this.minDate = undefined;
        this.maxDate = undefined;
        this.minRangedDays = undefined;
        this.maxRangedDays = undefined;
        this.disableDates = undefined;
        this.isValid = true;
        this.isFocused = undefined;
        this.isLoading = undefined;
        this.isDisabled = undefined;
    }
    /**
     * On value attribute change
     *
     * @param value
     */
    watchValue(value) {
        var _a;
        if (this.ranged) {
            const delimiter = value.includes(this.rangedDelimiter) ? this.rangedDelimiter : ',';
            const [start, end] = value.split(delimiter);
            this.picker.setDateRange(start, end);
        }
        else {
            this.picker.setDate(value);
        }
        this.internals.setFormValue(value);
        this.el.dispatchEvent(new InputEvent('input', { bubbles: false }));
        this.formValidateCallback(true);
        (_a = this.internals.form) === null || _a === void 0 ? void 0 : _a.dispatchEvent(new InputEvent('input', { bubbles: false }));
    }
    /**
     * Reload picker on change
     */
    watchMultiple() {
        this.picker && this.picker.off('select', ({ detail }) => this.onSelect(detail));
        this.picker.destroy();
        this.picker = new EasePicker(this.generateOptions());
        this.picker.on('select', ({ detail }) => this.onSelect(detail));
    }
    /**
     * This is called when the 'disabled' attribute of the element or or an ancestor <fieldset> is updated
     *
     * @param disabled
     */
    formDisabledCallback(disabled) {
        this.isDisabled = disabled;
    }
    /**
     * This is called when the parent/owner form is reset
     */
    formResetCallback() {
        this.internals.setFormValue('');
        this.internals.reportValidity();
    }
    /**
     * This is called when the input is validated
     */
    formValidateCallback(dispatchValidation) {
        if (this.required && isEmpty(this.value)) {
            this.internals.setValidity({ valueMissing: true }, Lang.get('fields.validation.value-missing'));
        }
        else {
            this.internals.setValidity({});
        }
        if (dispatchValidation) {
            this.isValid = this.internals.validity.valid;
            this.onValidateInputEvent.emit(this.internals);
        }
    }
    /**
     * This is called on component did load
     */
    componentDidLoad() {
        this.picker = new EasePicker(this.generateOptions());
        this.picker.on('select', ({ detail }) => this.onSelect(detail));
        setTimeout(() => this.formValidateCallback(), 0);
    }
    /**
     * Clears the input value
     */
    clearInput() {
        this.value = '';
    }
    /**
     * Generates options for the picker
     */
    generateOptions() {
        const disableDates = this.generateLockedDays();
        const ranged = this.minRangedDays != null ||
            this.maxRangedDays != null;
        const locked = disableDates.length > 0 ||
            (this.minDate && this.minDate != "") ||
            (this.maxDate && this.maxDate != "");
        const options = {
            element: this.input,
            zIndex: 99999,
            date: this.value,
            format: this.format,
            shadowDom: false,
            delimiter: this.rangedDelimiter,
            ranged: this.ranged || ranged,
            locked: locked || ranged,
            minDate: null,
            maxDate: null,
            minDays: null,
            maxDays: null,
            filter: null,
        };
        if (this.ranged) {
            options.minDays = this.minRangedDays;
            options.maxDays = this.maxRangedDays;
        }
        if (locked) {
            options.minDate = this.minDate;
            options.maxDate = this.maxDate;
            options.filter = (date, picked) => {
                if (picked.length === 1 && date instanceof DateTime) {
                    const incl = date.isBefore(picked[0]) ? '[)' : '(]';
                    return !picked[0].isSame(date, 'day') && date.inArray(disableDates, incl);
                }
                if (date instanceof DateTime) {
                    return date.inArray(disableDates, '[)');
                }
            };
        }
        return options;
    }
    /**
     * Generates locked days
     */
    generateLockedDays() {
        let lockedDays = [];
        if (typeof this.disableDates === 'string') {
            lockedDays = this.disableDates.split(',')
                .map((date) => date.includes(this.rangedDelimiter) ? date.split(this.rangedDelimiter) : date);
        }
        else {
            lockedDays = this.disableDates || [];
        }
        return lockedDays.map((date) => {
            if (Array.isArray(date)) {
                return [new DateTime(date[0], this.format), new DateTime(date[1], this.format)];
            }
            else {
                return new DateTime(date, this.format);
            }
        });
    }
    /**
     * This called on date select
     */
    onSelect(selected) {
        if (this.ranged) {
            this.value = [new DateTime(selected.start).format(this.format), new DateTime(selected.end).format(this.format)].join(',');
        }
        else {
            this.value = new DateTime(selected.date).format(this.format);
        }
    }
    /**
     * This called on input field is unfocused
     */
    onBlurInput() {
        this.blurTimeout = setTimeout(() => {
            this.isFocused = false;
            this.formValidateCallback(true);
        }, 50);
    }
    /**
     * This called on input field is focused
     */
    onFocusInput() {
        clearTimeout(this.blurTimeout);
        this.isFocused = true;
    }
    /**
     * Render component
     */
    render() {
        return h(Host, { key: 'de54c97cdf329191045435c9b9ac4f4dc3be2887', "data-for": this.name, tabindex: "0", onFocus: () => this.onFocusInput(), onBlur: () => this.onBlurInput(), style: { maxWidth: this.width } }, h("div", { key: '9ee11351197e53464426cae518fab42473ab0138', class: cls({
                "input-container": true,
                "focus": this.isFocused,
                "loading": this.loading || this.isLoading,
                "disabled": this.isDisabled,
                "required": this.required,
                "invalid": !this.isValid
            }) }, h("div", { key: '9098801e1cd906fa93689564ac948e10fe7bd7f2', class: "indicator" }, h("slot", { key: 'd93cab2e237c60d6bcee53757b457e0a3b4a32ac', name: "indicator" })), h("div", { key: 'fe9072492bf6eae18bbf2067d9b416bb313ba084', class: "separator" }), h("div", { key: '3e0e15563e9774a06e5fc6e80872d815ebc60ee0', class: "wrap" }, this.label && h("label", { key: '85495cf00ce72882c9c540406a1bc58b4e1f49a3', htmlFor: this.inputId }, this.label), h("input", { key: '7e27ce1a823c10f575e9fa2dcfe07c11b745ea40', ref: el => this.input = el, id: this.inputId, type: "tel", placeholder: this.ranged ? this.format + this.rangedDelimiter + this.format : this.format, disabled: this.isDisabled || this.isLoading, onFocus: () => this.onFocusInput(), onBlur: () => this.onBlurInput() })), this.loading && h("div", { key: '123b9876c40a950011826df08a9c9fc506728306', class: "loading-indicator" }), h("div", { key: '192e04526bcf86483a2f5f0e10149dde070e543a', class: "buttons" }, this.cleanable && h("x-button", { key: '300854742a22fc61db145f4772d74048ec4dc825', icon: "backclear", onClick: () => this.clearInput() }), h("slot", { key: '212088a003c0668bd4c4869a14f67399143274c7', name: "buttons" })), this.info && h("div", { key: '64a0c5e3707f1067abb142bbe4a92e9ea648d74d', class: "info" }, h("x-tooltip", { key: '7e0394dd23a5fca9935db878c01647af00957283', content: this.info }, h("x-icon", { key: '07cecf2f65dc52348b497c4cf029b04b7c529868', name: "info" }))), h("slot", { key: '52691456fa8ae4803b5150a5b23baba9167475e2' })));
    }
    static get is() { return "x-datepicker"; }
    static get formAssociated() { return true; }
    static get originalStyleUrls() {
        return {
            "$": ["./style.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["style.css"]
        };
    }
    static get properties() {
        return {
            "label": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Element input label text"
                },
                "attribute": "label",
                "reflect": false
            },
            "name": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Element input name for forms keys"
                },
                "attribute": "name",
                "reflect": false
            },
            "info": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Element input information block"
                },
                "attribute": "info",
                "reflect": false
            },
            "format": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Element date format"
                },
                "attribute": "format",
                "reflect": false,
                "defaultValue": "'DD-MM-YYYY'"
            },
            "loading": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Element show loading and block for edit"
                },
                "attribute": "loading",
                "reflect": false
            },
            "cleanable": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Element input clear button"
                },
                "attribute": "cleanable",
                "reflect": false
            },
            "ranged": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Element input date ranged"
                },
                "attribute": "ranged",
                "reflect": false
            },
            "required": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Element input required for forms validations"
                },
                "attribute": "required",
                "reflect": false
            },
            "rangedDelimiter": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Element input ranged deliter"
                },
                "attribute": "ranged-delimiter",
                "reflect": false,
                "defaultValue": "\" > \""
            },
            "width": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Element input width"
                },
                "attribute": "width",
                "reflect": false
            },
            "value": {
                "type": "string",
                "mutable": true,
                "complexType": {
                    "original": "string | null",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Element input value"
                },
                "attribute": "value",
                "reflect": false,
                "defaultValue": "''"
            },
            "minDate": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Element input min ranged date"
                },
                "attribute": "min-date",
                "reflect": false
            },
            "maxDate": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Element input max ranged date"
                },
                "attribute": "max-date",
                "reflect": false
            },
            "minRangedDays": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Element input min ranged days"
                },
                "attribute": "min-ranged-days",
                "reflect": false
            },
            "maxRangedDays": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Element input max ranged days"
                },
                "attribute": "max-ranged-days",
                "reflect": false
            },
            "disableDates": {
                "type": "string",
                "mutable": true,
                "complexType": {
                    "original": "[] | string | null",
                    "resolved": "[] | string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Element input disable dates"
                },
                "attribute": "disable-dates",
                "reflect": false
            }
        };
    }
    static get states() {
        return {
            "isValid": {},
            "isFocused": {},
            "isLoading": {},
            "isDisabled": {}
        };
    }
    static get events() {
        return [{
                "method": "onValidateInputEvent",
                "name": "validated",
                "bubbles": false,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "On validate input event"
                },
                "complexType": {
                    "original": "ElementInternals",
                    "resolved": "ElementInternals",
                    "references": {
                        "ElementInternals": {
                            "location": "global",
                            "id": "global::ElementInternals"
                        }
                    }
                }
            }];
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "value",
                "methodName": "watchValue"
            }, {
                "propName": "ranged",
                "methodName": "watchMultiple"
            }, {
                "propName": "rangedDelimiter",
                "methodName": "watchMultiple"
            }, {
                "propName": "minDate",
                "methodName": "watchMultiple"
            }, {
                "propName": "maxDate",
                "methodName": "watchMultiple"
            }, {
                "propName": "minRangedDays",
                "methodName": "watchMultiple"
            }, {
                "propName": "maxRangedDays",
                "methodName": "watchMultiple"
            }, {
                "propName": "disableDates",
                "methodName": "watchMultiple"
            }];
    }
    static get attachInternalsMemberName() { return "internals"; }
}
