<template>
    <span style="position:relative;" v-if="isValid" >
        {{label}}
        <input type="text"  :placeholder="placeholder" @focus.stop="showDatePanel" v-model="currentDate" :class="['input',sizeClass]"/>
    </span>
</template>
<script>
    import dateSelect from "./date.vue";
    import Vue  from "vue";
    import minxins from './mixins.js';

    export default{
        name: "v-f9-date-input",
        mixins:[minxins],
        data(){
            return {
                currentDate: "",//当前绑定的日期值
                dateInfo:{
                    year:null,//年
                    month:null,//月
                    day:null,//日
                    hour:null,//小时
                    minute:null,//分钟
                    second:null//秒
                },
                isValid:true//日期校验是否合法
            }
        },

        props: {
            //日期格式的模式( 0:年月日(YYYY-MM-DD), 1:年月(YYYY-MM), 2:年(YYYY),3:年月日 时(YYYY-MM-DD HH),4:年月日 时:分(YYYY-MM-DD HH:mm),5:年月日 时:分:秒(YYYY-MM-DD HH:mm:ss),6:时(HH),7:时:分(HH:mm),8:时:分:秒(HH:mm:ss) )
            em_date_mode: {
                type: Number,
                default: 2
            },

            value: [String],
            //日期输入框的默认占位

            placeholder: {
                type: String,
                default: ''
            },
            //日期的标题描述

            label: {
                type: String,
                default: ''
            },

            // 最小日期
            minDate: {
                type: String,
                default:''
            },

            // 最大日期
            maxDate: {
                type: String,
                default:''
            },
            //尺寸
            size:{
                type: String,
                default:'small'
            }
        },
        computed:{
            sizeClass(){

                return `v-f9-date-input-${this.size}`;

            }
        },

        methods: {
            //显示日期面板
            showDatePanel(){

                let initDate=this.init();

                if (!this.$refs.date.$props.date_show) {

                    this.getDateInfo(initDate);//解析日期的年,月,日

                    if(this.em_date_mode>5){

                        this.$refs.date.mode=3;//时模式
                        this.$refs.date.panelClass="v-f9-date-input-div-hour";//设置日期面板项的样式类

                    }
                    else{

                        this.$refs.date.mode=1;//年模式
                        this.$refs.date.panelClass="v-f9-date-input-div-month";//设置日期面板项的样式类

                    }

                    let topThree = initDate.substring(0, 3);//截取日期年的头三位
                    this.$refs.date.time = [];//清空日期面板的数据集合
                    
                    this.$refs.date.year_now=this.dateInfo.year;//日期年
                    this.$refs.date.month_now=this.dateInfo.month;//日期月
                    this.$refs.date.day_now=this.dateInfo.day;//日期天
                    this.$refs.date.hour_now=this.dateInfo.hour;//日期小时
                    this.$refs.date.minute_now=this.dateInfo.minute;//日期分钟
                    this.$refs.date.second_now=this.dateInfo.second;//日期秒钟

                    this.$refs.date.years_start = topThree + "0";//日期面板的开始日期
                    this.$refs.date.years_end = topThree + "9";//日期面板的结束日期
                    this.$refs.date.title = this.generateTitle();//日期面板的展示标题
                    this.$refs.date.time=this.generatePanelDate();//生成日期面板展示的数据

                }

                this.$refs.date.$props.date_show = true;//设置日期面板的

            },
            //检测传入日期是否符合规则
            checkIsValid(value){

                let self=this;

                let formatting={
                    //格式：YYYY-MM-DD
                    0:/^[0-9]{4}-((0[0-9]{1})|1[0-2]{1})-((0[1-9]{1})|(([1-2]{1}[0-9]{1}))|(3[0-1]{1}))$/,
                    //格式：YYYY-MM
                    1:/^[0-9]{4}-((0[0-9]{1})|1[0-2]{1})$/,
                    //格式：YYYY
                    2:/^[0-9]{4}$/,
                    //格式: YYYY-MM-DD HH
                    3:/^[0-9]{4}-((0[0-9]{1})|1[0-2]{1})-((0[1-9]{1})|(([1-2]{1}[0-9]{1}))|(3[0-1]{1})) ((0[0-9]{1})|(1[0-9]{1})|(2[0-3]{1}))$/,
                    //格式: YYYY-MM-DD HH:mm
                    4:/^[0-9]{4}-((0[0-9]{1})|1[0-2]{1})-((0[1-9]{1})|(([1-2]{1}[0-9]{1}))|(3[0-1]{1})) ((0[0-9]{1})|(1[0-9]{1})|(2[0-3]{1})):((0[0-9]{1})|([1-5]{1}[0-9]{1}))$/,
                    //格式: YYYY-MM-DD HH:mm:ss
                    5:/^[0-9]{4}-((0[0-9]{1})|1[0-2]{1})-((0[1-9]{1})|(([1-2]{1}[0-9]{1}))|(3[0-1]{1})) ((0[0-9]{1})|(1[0-9]{1})|(2[0-3]{1})):((0[0-9]{1})|([1-5]{1}[0-9]{1})):((0[0-9]{1})|([1-5]{1}[0-9]{1}))$/,
                    //格式: HH
                    6:/^((0[0-9]{1})|(1[0-9]{1})|2[0-3]{1})$/,
                    //格式: HH:mm
                    7:/^((0[0-9]{1})|(1[0-9]{1})|(2[0-3]{1})):((0[0-9]{1})|([1-5]{1}[0-9]{1}))$/,
                    //格式: HH:mm:ss
                    8:/^((0[0-9]{1})|(1[0-9]{1})|(2[0-3]{1})):((0[0-9]{1})|([1-5]{1}[0-9]{1})):((0[0-9]{1})|([1-5]{1}[0-9]{1}))$/,
                    isValid(mode,value){

                        let isDateValid=this[mode].test(value);//日期是否合法
                        let isDayValid=true;//日期天是否合法

                        if(!isDateValid){

                            return false;

                        }

                        self.getDateInfo(value);//获取日期信息

                        //判断如果是YYYY-MM-DD,需要判断日期天的合法性
                        if(mode==0){

                            //获取当前日期月的最大天数
                            let maxDay=new Date(self.dateInfo.month,self.dateInfo.month,0).getDate();

                            isDayValid=self.dateInfo.day<=maxDay;

                        }

                        return isDateValid && isDayValid;

                    }
                };

                return formatting.isValid(this.em_date_mode,value);

            },
            //获取日期
            getDateInfo(value){
                
                value=this.getWholeDate(value);
                let date=value ?new Date(value):new Date();
                this.dateInfo.year=date.getFullYear();//年
                this.dateInfo.month=date.getMonth()+1;//月
                this.dateInfo.day=date.getDate();//日
                this.dateInfo.hour=date.getHours();//小时
                this.dateInfo.minute=date.getMinutes();//分钟
                this.dateInfo.second=date.getSeconds();//秒

            },
            //关闭日期面板
            closePanel(e){

                let dateDiv = this.$refs.date.$el;

                if ((e.target != dateDiv ) && (!dateDiv.contains(e.target) ) && (!this.$el.childNodes[1].contains(e.target))) {

                    this.$refs.date.$props.date_show = false;

                } 

            },
            //生成标题
            generateTitle(){

                let title;

                if(this.em_date_mode>=6){

                    title=`00-59`;

                }
                else{

                    title=this.$refs.date.years_start + "-" + this.$refs.date.years_end;

                }

                return title;

            },
            //生成日期面板数据
            generatePanelDate(){

                let panelData=[];

                if(this.em_date_mode>=6){

                    for(let i=0;i<24;i++){

                        panelData.push(i);

                    }

                }
                else{

                    let startYear= Number(this.$refs.date.years_start);
                    let endYear=Number(this.$refs.date.years_end);

                    for(let year=startYear;year<=endYear;year++){

                        panelData.push(year);

                    }

                }

                return panelData;

            },
            //初始化
            init(){

                let value=this.getWholeDate(this.currentDate);
                let dateInfo=this.currentDate?new Date(value):new Date();
                let year=dateInfo.getFullYear();//年
                let month=dateInfo.getMonth()+1;//月
                let day=dateInfo.getDate();//日
                let hour=dateInfo.getHours();//小时
                let minute=dateInfo.getMinutes();//分钟
                let second=dateInfo.getSeconds();//秒
                return this.generateDate(year,month,day,hour,minute,second);

            }
        },
        created: function () {

            //校验日期格式
            if(this.value && !this.checkIsValid(this.value)){

                this.isValid=false;
                console.log('日期格式不正确');
                return false;

            }

            //构造日期组件实例
            const dateConstrctor = Vue.extend(dateSelect);
            const instance = new dateConstrctor({
                el: document.createElement('div'),
                data: {
                    minDate: this.minDate,//最小日期
                    maxDate: this.maxDate,//最大日期
                }
            });

            //赋值当前传递的绑定的默认展示的日期值
            this.currentDate=this.value;

            //设置日期隐藏
            instance.$props.date_show = false;

            //日历模式属性
            instance.$props.em_date_mode = this.em_date_mode;

            //传递给input日期值
            instance.$on("dateChange", (msg)=> {
                this.currentDate = msg;
            });

            //添加组件引用
            this.$refs.date = instance;


        },

        mounted: function () {

            if(!this.isValid){

                return false;

            }

            //日期组件的引用
            let dateDiv = this.$refs.date.$el;

            this.$el.appendChild(dateDiv);

            //点击非日期控件的地方,关闭日期面板
            document.addEventListener('click', this.closePanel, true);

        },

        watch: {
            //日期文本框的值监听
            currentDate: function (newVal) {

                //检测输入input合法性
                if(!this.checkIsValid(newVal)){

                    this.currentDate="";

                }
                
                //响应父组件的绑定的v-model
                this.$emit('input', newVal);

            },
            //可选最小日期的监听
            minDate(){

                //动态给日期面板的最小日期赋值
                this.$refs.date.minDate=this.minDate;

            },
            //可选最大日期的监听
            maxDate(){

                //动态给日期面板的最大日期赋值
                this.$refs.date.maxDate=this.maxDate;

            }
        },
        //日期组件销毁
        destroyed(){

            //将日期组件从body中删除
            this.$el.removeChild(this.$refs.date.$el);

            //销毁日期组件绑定的事件
            document.removeEventListener('click',this.closePanel);//点击非日期控件的地方,关闭日期面板事件

        }
    }

</script>
