<template>

    <input type="text" data-input="true" :disabled="disabled" @input="onInput" :style="inputStyle" />
    
</template>

<script>

import flatpickr from './plugins/flatpickr.js';
import {excludedEvents, includedEvents} from "./helper/events.js";
import {arrayify, camelToKebab, cloneObject} from "./helper/util.js";
const allEvents = includedEvents.concat(excludedEvents);
const configCallbacks = ['locale', 'showMonths'];

//加载中文语言包
const chinese = require("./plugins/l10n/zh.js").default.zh;
flatpickr.localize(chinese);

export default {
    name:'v-datetime',
    props: {
        value: {
            default: null,
            required: true,
            validator(value) {

                return value === null || value instanceof Date || typeof value === 'string' || value instanceof String || value instanceof Array || typeof value === 'number';
                
            }
        },
        config: {
            type: Object,
            default: () => ({
                wrap: false,
                defaultDate: null,
            })
        },
        events: {
            type: Array,
            default: () => includedEvents
        },
        disabled: {
            type: Boolean,
            default: false
        },
        width:{
            type:Number,
            default:300
        },
        height:{
            type:Number,
            default:30
        }
    },
    data(){

        return {
            instance: null
        };

    },
    computed:{
        inputStyle(){

            return {
                width:`${this.width}px`,
                height:`${this.height}px`
            };

        }
    },
    methods:{
        getElem() {

            return this.config.wrap ? this.$el.parentNode : this.$el;

        },
        onInput(event) {

            this.$nextTick(() => {

                this.$emit('input', event.target.value);

            });

        },
        fpInput() {

            return this.instance.altInput || this.instance.input;

        },
        onBlur(event) {

            this.$emit('blur', event.target.value);

        }
    },
    watch:{
        config: {
            deep: true,
            handler(newConfig) {

                let safeConfig = cloneObject(newConfig);

                allEvents.forEach((hook) => {

                    delete safeConfig[hook];

                });

                this.instance.set(safeConfig);

                configCallbacks.forEach((name) => {

                    if (typeof safeConfig[name] !== 'undefined') {

                        this.instance.set(name, safeConfig[name]);

                    }

                });

            }
        },
        value(newValue) {

            if (newValue === this.$el.value) return;

            this.instance && this.instance.setDate(newValue, true);

        },
        disabled(newState) {

            if (newState) {

                this.fpInput().setAttribute('disabled', newState);

            } 
            else 
            {

                this.fpInput().removeAttribute('disabled');

            }

        }
    },
    mounted(){

        if (this.instance) return;
        
        let safeConfig = cloneObject(this.config);

        this.events.forEach((hook) => {

            safeConfig[hook] = arrayify(safeConfig[hook] || []).concat((...args) => {

                this.$emit(camelToKebab(hook), ...args);

            });

        });

        safeConfig.defaultDate = this.value || safeConfig.defaultDate;

        this.instance = new flatpickr(this.getElem(), safeConfig);

        this.fpInput().addEventListener('blur', this.onBlur);

    },
    beforeDestroy() {

        if (this.instance) {

            this.fpInput().removeEventListener('blur', this.onBlur);

            this.instance.destroy();

            this.instance = null;

        }
    }
}
</script>

