<template>
  <n-options-date ref="options" v-model="isFocus" v-bind="{disabled, activeValue: nValue, type, min, max, maxlength, options, autoClose: false, footer: {option, options}}"
                  @u-change="onUChange" @option-click="onOptionClick">
    <n-date-picker-refer class="n-date-picker" v-model="isFocus" v-bind="{name, size, border, labels, disabled, placeholder, clearable}"
                         @u-update="onReferUpdateValues" @user-input="onUserInput"></n-date-picker-refer>
  </n-options-date>
</template>
<script>
import NOptionsDate from '@uif/next/lib/components/options-date'
import NDatePickerRefer from './date-picker-refer'
import {isArray, propsArray, prop, normalizeArray, normalizeValue} from '@uif/next/lib/utils/tools'
import {isRangeType, toLabels, formatUserInput, getDateRangeOptions} from '_common/dateUtils'
import vModel from '_common/vModel'

export default {
  inheritAttrs: false,
  name: 'n-date-picker',
  mixins: [vModel],
  components: {
    NOptionsDate,
    NDatePickerRefer
  },
  props: {
    // 表单名
    name: prop.string(),
    // 'date', 'minute', 'time', 'month' => '2022-02-02 02:02:02'   能够使用dayjs序列化的时间格式
    // 'dates', 'months' => ['2022-01-02 02:02:02', '2022-02-02 03:02:02'] 能够使用dayjs序列化的时间格式数组
    value: {
      type: [Array, String],
      default: ''
    },
    // 序列化格式
    format: prop.string('YYYY-MM-DD HH:mm:ss'),
    // 类型
    type: prop.inArray(['date', 'minute', 'time', 'dates', 'month', 'months'], 'date'),
    // 最小时间
    min: prop.stringNumber('1700-01-01'),
    // 最大时间
    max: prop.stringNumber('2700-01-01'),
    // 最大时间跨度(天) date-range有效
    maxlength: prop.stringNumber(),
    // 可响应的option 仅range有效
    defaultOption: {type: [String, Object]},
    // 底部选项 =>
    // options: [{
    //   label: 'xxx', // 显示的label
    //   skip: true, // 不需要 emit(u-update/u-change) 事件
    //   value: [], // Function/Array date数组
    // }],
    options: prop.array(null),
    // 选择框提示文本
    placeholder: prop.string('请选择'),
    // 大小
    size: propsArray(['small', 'middle', 'large'], 'middle'),
    // 边框
    border: propsArray(['none', 'line', 'rect'], 'rect'),
    // 禁用
    disabled: prop.boolean(),
    // 可删除
    clearable: prop.boolean(true)
  },
  data () {
    return {
      // 下拉框可见
      isFocus: false,
      nValue: isRangeType(this.type) && !isArray(this.value) ? [] : this.value,
      option: getDateRangeOptions([this.defaultOption])[0]
    }
  },
  computed: {
    labels ({option, nValue, type}) {
      return isRangeType(type) && option?.label ? [option.label] : toLabels(nValue, type)
    }
  },
  watch: {
    isFocus (value) {
      value ? this.onFocus() : this.onBlur()
    },
    defaultOption (option) {
      this.option = getDateRangeOptions([option])[0]
      if (this.option?.label) {
        const values = normalizeArray(normalizeValue(this.option.value)).map(date => date.format(this.format))
        this.nValue = isRangeType(this.type) ? values : values[0]
      }
    }
  },
  methods: {
    // 点击选项
    onUChange (value) {
      this.option = null
      const values = normalizeArray(value).map(date => date.format(this.format))
      this.nValue = isRangeType(this.type) ? values : values[0]
      this.$emit('u-update', this.nValue)
      this.isFocus = false
    },
    // refer 点击删除按钮
    onReferUpdateValues () {
      this.option = null
      this.nValue = isRangeType(this.type) ? [] : ''
      this.$emit('u-update', this.nValue)
      // 非 focus 状态下 改变值 需要
      if (!this.isFocus) {
        this.$emit('u-change', this.nValue)
      }
      this.isFocus = false
    },
    // refer 用户输入
    onUserInput (keyword) {
      const values = formatUserInput(keyword)
      if (values.length === (isRangeType(this.type) ? 2 : 1)) {
        this.onUChange(values)
        this.isFocus = false
      }
    },
    // 点击 option
    onOptionClick (option) {
      this.option = option
      const values = normalizeArray(normalizeValue(option.value)).map(date => date.format(this.format))
      this.nValue = isRangeType(this.type) ? values : values[0]
      this.$emit('option-click', option)
      if (!option.skip) {
        this.$emit('u-update', this.nValue)
        this.$emit('u-change', this.nValue)
      }
      this.isFocus = false
      // 销毁 paster 下次进入以nValue重置
      setTimeout(() => this.$refs.options.destroyPaster(), 200)
    },
    // focus回调
    onFocus () {
      this.backup = normalizeArray(this.nValue).join('&')
      this.$emit('u-focus', this)
    },
    // blur回调
    onBlur () {
      this.$emit('u-blur', this)
      if (!this.option && this.backup !== normalizeArray(this.nValue).join('&')) {
        this.$emit('u-change', this.nValue)
      }
    }
  }
}
</script>
