import { Namespace } from '../../utils/namespace.js';
import Picker from '../picker/picker.jsx';
import { DateExtension } from '../../utils/extensions/date';

const namespcae = Namespace.Create('date-time-picker')

const now = new Date();
export default {
  name: namespcae.name,
  components: {
    Picker
  },
  props: {
    pattern: {
      type: String,
      default: 'date'
    },
    itemHeight: {
      type: Number,
      default: 50
    },
    visibleItemCount: {
      type: Number,
      default: 5
    },
    swipeDuration: {
      type: Number,
      default: 800
    },
    title: {
      type: String,
      default: ''
    },
    readonly: {
      type: Boolean,
      default: false
    },
    minDate: {
      type: Date,
      default: () => new Date(now.getFullYear() - 10, 0, 1)
    },
    maxDate: {
      type: Date,
      default: () => new Date(now.getFullYear() + 10, 11, 31)
    },
    minTime:{
      type: String,
      default: '00:00:00'
    },
    maxTime:{
      type: String,
      default:'23:59:59'
    },
    showSuffix: {
      type: Boolean,
      default: false
    },
    value: {
      type: Date | String,
      required: true
    },
    windowPattern: {
      type: String,
      default: 'fill'
    }
  },
  model: {
    prop: 'value',
    event: 'change'
  },
  computed: {
    isDate() {
      return this.pattern === 'date';
    },
    isDateTime() {
      return this.pattern === 'datetime';
    },
    isTime() {
      return this.pattern === 'time';
    },
    currentYear(){
      return this.value.getFullYear()
    },
    currentMonth(){
      return this.value.getMonth()
    },
    currentDay(){
      return this.value.getDate()
    },
    currentHour(){
      return this.value.getHours()
    },
    currentMinute(){
      return this.value.getMinutes()
    },
    currentSecond(){
      return this.value.getSeconds()
    },
    minYear(){
      return this.minDate.getFullYear()
    },
    minMonth(){
      return this.minDate.getMonth()
    },
    minDay(){
      return this.minDate.getDate()
    },
    minHour(){
      return this.minDate.getHours()
    },
    minMinute(){
      return this.minDate.getMinutes()
    },
    minSecond(){
      return this.minDate.getSeconds()
    },
    maxYear(){
      return this.maxDate.getFullYear()
    },
    maxMonth(){
      return this.maxDate.getMonth()
    },
    maxDay(){
      return this.maxDate.getDate()
    },
    maxtHour(){
      return this.maxDate.getHours()
    },
    maxMinute(){
      return this.maxDate.getMinutes()
    },
    maxSecond(){
      return this.maxDate.getSeconds()
    },
    yearSuffix(){
      return this.showSuffix ? '年' : ''
    },
    monthSuffix(){
      return this.showSuffix ? '月' : ''
    },
    daySuffix(){
      return this.showSuffix ? '日' : ''
    },
    hourSuffix(){
      return this.showSuffix ? '时' : ''
    },
    minuteSuffix(){
      return this.showSuffix ? '分' : ''
    },
    secondSuffix(){
      return this.showSuffix ? '秒' : ''
    },
    timeArray(){
      return this.value.split(':').map(x=>Number(x))
    },
    minTimeArray(){
      return this.minTime.split(':').map(x=>Number(x))
    },
    maxTimeArray(){
      return this.maxTime.split(':').map(x=>Number(x))
    },
    currentTimeHour(){
      return this.timeArray[0]
    },
    currentTimeMinute(){
      return this.timeArray[1] || 0
    },
    currentTimeSecond(){
      return this.timeArray[2] || 0
    },
    minTimeHour(){
      return this.minTimeArray[0] || 0
    },
    minTimeMinute(){
      return this.minTimeArray[1] || 0
    },
    minTimeSecond(){
      return this.minTimeArray[2] || 0
    },
    maxTimeHour(){
      return this.maxTimeArray[0] || 23
    },
    maxTimeMinute(){
      return this.maxTimeArray[1] || 59
    },
    maxTimeSecond(){
      return this.maxTimeArray[2] || 59
    },
    columns(){
      return this.getColumns()
    }
  },
  methods: {
    getColumns() {
      let res = [];
      switch (this.pattern) {
        case 'date':
          res = this.getDate();
          break;
        case 'time':
          res = this.getTimeSolely()
          break;
        case 'datetime':
          res = this.getDateTime()
          break;
      }
      return res;
    },
    getDate(){
      return [this.getYear(),this.getMonth(),this.getDay()]
    },
    getTime(){
      return [this.getHour(),this.getMinute(),this.getSecond()]
    },
    getDateTime(){
      return [...this.getDate(),...this.getTime()]
    },
    getMaxDayByLearMonth(year, month) {
      let res = 0;
      switch (month + 1) {
        case 2:
          if (DateExtension.IsLeapYear(year)) {
            res = 29;
          } else {
            res = 28;
          }
          break;
        case 4:
        case 6:
        case 9:
        case 11:
          res = 30;
          break;
        default:
          res = 31;
          break;
      }
      return res;
    },
    getYear(){
      const value = this.currentYear
      const min = this.minYear
      const max = this.maxYear
      const suffix = this.yearSuffix
      return this.getColumn(value,min,max,suffix,4)
    },
    getMonth(){
      const value = this.currentMonth
      const min = this.currentYear === this.minYear ? this.minMonth : 0
      const max = this.currentYear === this.maxYear ? this.maxMonth : 11
      const suffix = this.monthSuffix
      return this.getColumn(value,min,max,suffix,true)
    },
    getDay(){
      const value = this.currentDay
      const min = (this.value <= this.minDate) || (this.currentYear === this.minYear && this.currentMonth === this.minMonth) 
                  ? this.minDay : 1
      const max = (this.value >= this.maxDate) || (this.currentYear === this.maxYear && this.currentMonth === this.maxMonth) 
                  ? this.maxDay : this.getMaxDayByLearMonth(this.currentYear,this.currentMonth)
      const suffix = this.daySuffix
      return this.getColumn(value,min,max,suffix)
    },
    getHour(){
      const value = this.currentHour
      const min =  (this.value <= this.minDate) 
                  || (this.currentYear === this.minYear && this.currentMonth === this.minMonth && this.currentDay === this.minDay)
                  ? this.minHour
                  : 0
      const max = (this.value >= this.maxDate) 
                  || (this.currentYear >= this.maxYear && this.currentMonth === this.maxMonth &&  this.currentDay === this.maxDay)
                  ? this.maxtHour
                  : 23
      const suffix = this.hourSuffix
      return this.getColumn(value,min,max,suffix)
    },
    getMinute(){
      const value = this.currentMinute
      const min =  (this.value <= this.minDate) 
                  || (this.currentYear === this.minYear && this.currentMonth === this.minMonth && this.currentDay === this.minDay && this.currentHour === this.minHour)
                  ? this.minMinute
                  : 0
      const max = (this.value >= this.maxDate) 
                  || (this.currentYear === this.maxYear && this.currentMonth === this.maxMonth &&  this.currentDay === this.maxDay && this.currentHour === this.maxtHour)
                  ? this.maxMinute
                  : 59
      const suffix = this.minuteSuffix
      return this.getColumn(value,min,max,suffix)
    },
    getSecond(){
      const value = this.currentMinute
      const min = (this.value <= this.minDate)
                  || (this.currentYear === this.minYear && this.currentMonth === this.minMonth && this.currentDay === this.minDay && this.currentHour === this.minHour
                      && this.currentMinute === this.minMinute)
                  ? this.minSecond
                  : 0
      const max = (this.value >= this.maxDate)
                  ||( this.currentYear === this.maxYear && this.currentMonth === this.maxMonth &&  this.currentDay === this.maxDay && this.currentHour === this.maxtHour
                      && this.currentMinute === this.maxMinute)
                  ? this.maxSecond
                  : 59
      const suffix = this.secondSuffix
      return this.getColumn(value,min,max,suffix)
    },
    getTimeSolely(){
      return [this.getHourSolely(),this.getMinuteSolely(),this.getSecondSolely()]
    },
    getHourSolely(){
      const value = this.currentTimeHour
      const min = this.minTimeHour
      const max = this.maxTimeHour
      const suffix = this.hourSuffix
      return this.getColumn(value,min,max,suffix)
    },
    getMinuteSolely(){
      const value = this.currentTimeMinute
      const min = this.currentTimeHour === this.minTimeHour ? this.minTimeMinute : 0
      const max = this.currentTimeHour === this.maxTimeHour ? this.maxTimeMinute : 59
      const suffix = this.minuteSuffix
      return this.getColumn(value,min,max,suffix)
    },
    getSecondSolely(){
      const value = this.currentTimeSecond
      const min = this.currentTimeHour === this.minTimeHour && this.currentTimeMinute === this.minTimeMinute
                  ? this.minTimeSecond
                  : 0
      const max = this.currentTimeHour === this.maxTimeHour && this.currentTimeMinute === this.maxTimeMinute
                  ? this.maxTimeSecond
                  : 59
      const suffix = this.secondSuffix
      return this.getColumn(value,min,max,suffix)
    },
    getColumn(value,min,max,suffix='',isMonth=false,padLength = 2,padChar='0'){
      const items = this.generateItems(min,max,padLength,padChar,isMonth)
      const index = items.findIndex(x=>x.value === value)
      return {
        defaultIndex: index === -1 ? 0 : index,
        items,
        suffix
      }
    },
    generateItems(min,max,padLength = 2,padChar='0',isMonth){
      const res = []
      for(let i = min;i<= max;i++){
        res.push({
          text:  String( isMonth ? i+1 : i ).padStart(padLength,padChar),
          value: i
        })
      }
      return res
    },
    onChange(values, indexs) {
      if (this.isDate || this.isDateTime) {
        const parts = values.map(x=>x.value)
        this.$emit('change', new Date(...parts))
        return;
      }
      if (this.isTime) {
        this.$emit('change', values.join(':'));
      }
    },
    onCancel() {
      this.$emit('cancel');
    },
    onConfirm() {
      this.$emit('confirm');
    }
  },
  render(){
    return (
      <Picker
        readonly={this.readonly}
        title={this.title}
        item-height={this.itemHeight}
        visible-item-count={this.visibleItemCount}
        swipe-duration={this.swipeDuration}
        window-pattern={this.windowPattern}
        columns={this.columns}
        vOn:change={this.onChange}
        vOn:cancel={this.onCancel}
        vOn:confirm={this.onConfirm}
      />
    )
  }
}