/*! bxs-vue-ui v3.3.0 */
import '../utils/entry-virtual.js';
import { C as create, _ as __vue_normalize__ } from '../utils/normalize-component.js';
import '../utils/object-create.js';
import '../utils/html.js';
import '../utils/es.number.constructor.js';
import '../utils/es.object.to-string.js';
import '../utils/array-iteration.js';
import '../utils/sloppy-array-method.js';
import '../utils/for-each.js';
import { _ as _mapInstanceProperty } from '../utils/map.js';
import { _ as _indexOfInstanceProperty } from '../utils/index-of.js';
import '../utils/string-trim.js';
import { _ as _parseInt } from '../utils/parse-int.js';
import '../utils/filter.js';
import { _ as _sliceInstanceProperty } from '../utils/slice.js';
import { _ as _extends } from '../utils/extends.js';
import 'better-scroll';
import '../utils/index.js';
import '../utils/some.js';
import Vue from 'vue';
import '../utils/env.js';
import '../safe-area-patch/index.js';
import '../icon/index.js';
import bottomSheets from '../bottom-sheets/index.js';
import '../utils/sloppy-array-method2.js';
import '../utils/es.array.join.js';
import { _ as _spliceInstanceProperty } from '../utils/splice.js';
import { _ as _Object$keys } from '../utils/keys.js';
import '../utils/a-function.js';
import '../utils/species-constructor.js';
import '../utils/es.string.split.js';
import { _ as _Number$isNaN } from '../utils/is-nan.js';
import { P as PickerView } from '../utils/picker.js';
import '../utils/stringify.js';

var _components;

function range(num, min, max) {
  return Math.min(Math.max(num, min), max);
}

var currentYear = new Date().getFullYear();

var isValidDate = function isValidDate(date) {
  return Object.prototype.toString.call(date) === '[object Date]' && !_Number$isNaN(date.getTime());
};

var isValidType = function isValidType(type) {
  var _context;

  return _indexOfInstanceProperty(_context = ['datetime', 'date', 'time', 'year-month']).call(_context, type) !== -1;
};

var script = create({
  name: 'datetime-picker',
  components: (_components = {}, _components[PickerView.name] = PickerView, _components),
  props: {
    value: [Date, String],
    title: String,
    type: {
      type: String,
      default: 'datetime',
      validator: isValidType
    },
    formatter: {
      type: Function,
      default: function _default(type, value) {
        return value;
      }
    },
    minDate: {
      type: Date,
      default: function _default() {
        return new Date(currentYear - 10, 0, 1);
      },
      validator: isValidDate
    },
    maxDate: {
      type: Date,
      default: function _default() {
        return new Date(currentYear + 10, 11, 31);
      },
      validator: isValidDate
    },
    minHour: {
      type: Number,
      default: 0
    },
    maxHour: {
      type: Number,
      default: 23
    },
    minMinute: {
      type: Number,
      default: 0
    },
    maxMinute: {
      type: Number,
      default: 59
    },
    minSecond: {
      type: Number,
      default: 0
    },
    maxSecond: {
      type: Number,
      default: 59
    }
  },
  data: function data() {
    return {
      innerValue: this.correctValue(this.value)
    };
  },
  watch: {
    value: function value(val) {
      var v = this.correctValue(val);
      var isEqual = this.type === 'time' ? v === this.innerValue : v.valueOf() === this.innerValue.valueOf();
      if (!isEqual) this.innerValue = v;
    },
    innerValue: function innerValue(val) {
      this.$emit('input', val);
    },
    columns: function columns() {
      this.updateColumnValue(this.innerValue);
    }
  },
  computed: {
    ranges: function ranges() {
      if (this.type === 'time') {
        return [{
          type: 'hour',
          range: [this.minHour, this.maxHour]
        }, {
          type: 'minute',
          range: [this.minMinute, this.maxMinute]
        }, {
          type: 'second',
          range: [this.minSecond, this.maxSecond]
        }];
      }

      var _this$getBoundary = this.getBoundary('max', this.innerValue),
          maxYear = _this$getBoundary.maxYear,
          maxDate = _this$getBoundary.maxDate,
          maxMonth = _this$getBoundary.maxMonth,
          maxHour = _this$getBoundary.maxHour,
          maxMinute = _this$getBoundary.maxMinute,
          maxSecond = _this$getBoundary.maxSecond;

      var _this$getBoundary2 = this.getBoundary('min', this.innerValue),
          minYear = _this$getBoundary2.minYear,
          minDate = _this$getBoundary2.minDate,
          minMonth = _this$getBoundary2.minMonth,
          minHour = _this$getBoundary2.minHour,
          minMinute = _this$getBoundary2.minMinute,
          minSecond = _this$getBoundary2.minSecond;

      var result = [{
        type: 'year',
        range: [minYear, maxYear]
      }, {
        type: 'month',
        range: [minMonth, maxMonth]
      }, {
        type: 'day',
        range: [minDate, maxDate]
      }, {
        type: 'hour',
        range: [minHour, maxHour]
      }, {
        type: 'minute',
        range: [minMinute, maxMinute]
      }, {
        type: 'second',
        range: [minSecond, maxSecond]
      }];
      if (this.type === 'date') _spliceInstanceProperty(result).call(result, 3, 3);
      if (this.type === 'year-month') _spliceInstanceProperty(result).call(result, 2, 4);
      return result;
    },
    columns: function columns() {
      var _context2,
          _this = this;

      var results = _mapInstanceProperty(_context2 = this.ranges).call(_context2, function (item) {
        var rg = item.range;
        var tp = item.type;

        var values = _this.times(rg[1] - rg[0] + 1, function (index) {
          var value = rg[0] + index;
          value = value < 10 ? "0" + value : "" + value;
          return _this.iFormatter(tp, value);
        });

        return {
          values: values
        };
      });

      return results;
    }
  },
  methods: {
    pad: function pad(val) {
      var _context3;

      return _sliceInstanceProperty(_context3 = "00" + val).call(_context3, -2);
    },
    iFormatter: function iFormatter(type, value) {
      return this.ranges.length > 3 ? value : this.formatter(type, value);
    },
    correctValue: function correctValue(value) {
      var val = value;
      var isDateType = this.type !== 'time';

      if (isDateType && !isValidDate(val)) {
        val = this.minDate;
      } else if (!val) {
        var minHour = this.minHour;
        val = (minHour > 9 ? minHour : "0" + minHour) + ":00:00";
      } // time type


      if (!isDateType) {
        var _val$split = val.split(':'),
            hour = _val$split[0],
            minute = _val$split[1],
            second = _val$split[2];

        hour = this.pad(range(hour, this.minHour, this.maxHour));
        minute = this.pad(range(minute, this.minMinute, this.maxMinute));
        second = this.pad(range(second, this.minSecond, this.maxSecond));
        return hour + ":" + minute + ":" + second;
      } // date type


      val = range(val, this.minDate, this.maxDate);
      return new Date(val);
    },
    times: function times(n, iteratee) {
      var index = 0;
      var result = Array(n);

      while (index < n) {
        result[index] = iteratee(index);
        index += 1;
      }

      return result;
    },
    getBoundary: function getBoundary(type, value) {
      var _ref;

      var boundary = this[type + "Date"];
      var year = boundary.getFullYear();
      var month = 1;
      var date = 1;
      var hour = 0;
      var minute = 0;
      var second = 0;

      if (type === 'max') {
        month = 12;
        date = this.getMonthEndDay(value.getFullYear(), value.getMonth() + 1);
        hour = 23;
        minute = 59;
        second = 59;
      }

      if (value.getFullYear() === year) {
        month = boundary.getMonth() + 1;

        if (value.getMonth() + 1 === month) {
          date = boundary.getDate();

          if (value.getDate() === date) {
            hour = boundary.getHours();

            if (value.getHours() === hour) {
              minute = boundary.getMinutes();

              if (value.getMinutes() === minute) {
                second = boundary.getSeconds();
              }
            }
          }
        }
      }

      return _ref = {}, _ref[type + "Year"] = year, _ref[type + "Month"] = month, _ref[type + "Date"] = date, _ref[type + "Hour"] = hour, _ref[type + "Minute"] = minute, _ref[type + "Second"] = second, _ref;
    },
    getTrueValue: function getTrueValue(formattedValue) {
      var fv = formattedValue;
      if (!fv) return null;

      while (_Number$isNaN(_parseInt(fv, 10))) {
        fv = _sliceInstanceProperty(fv).call(fv, 1);
      }

      return _parseInt(fv, 10);
    },
    getMonthEndDay: function getMonthEndDay(year, month) {
      return 32 - new Date(year, month - 1, 32).getDate();
    },
    onConfirm: function onConfirm() {
      this.$emit('confirm', this.innerValue);
    },
    onCancel: function onCancel() {
      this.$emit('cancel');
    },
    onChange: function onChange(picker) {
      var _this2 = this;

      var values = picker.getValues();
      var value = null;

      if (this.type === 'time') {
        value = values.join(':');
      } else {
        var year = this.getTrueValue(values[0]);
        var month = this.getTrueValue(values[1]);
        var maxDate = this.getMonthEndDay(year, month);
        var date = this.getTrueValue(values[2]);

        if (this.type === 'year-month') {
          date = 1;
        }

        date = date > maxDate ? maxDate : date;
        var hour = 0;
        var minute = 0;
        var second = 0;

        if (this.type === 'datetime') {
          hour = this.getTrueValue(values[3]);
          minute = this.getTrueValue(values[4]);
          second = this.getTrueValue(values[5]);
        }

        value = new Date(year, month - 1, date, hour, minute, second);
      }

      value = this.correctValue(value);
      this.innerValue = value;
      this.$nextTick(function () {
        _this2.$nextTick(function () {
          _this2.$emit('change', value);
        });
      });
    },
    updateColumnValue: function updateColumnValue(value) {
      var _this3 = this;

      var values = [];
      var iFormatter = this.iFormatter,
          pad = this.pad;

      if (this.type === 'time') {
        var currentValue = value.split(':');
        values = [iFormatter('hour', currentValue[0]), iFormatter('minute', currentValue[1]), iFormatter('second', currentValue[2])];
      } else {
        values = [iFormatter('year', "" + value.getFullYear()), iFormatter('month', pad(value.getMonth() + 1)), iFormatter('day', pad(value.getDate()))];

        if (this.type === 'datetime') {
          values.push(iFormatter('hour', pad(value.getHours())), iFormatter('minute', pad(value.getMinutes())), iFormatter('second', pad(value.getSeconds())));
        }

        if (this.type === 'year-month') {
          values = _sliceInstanceProperty(values).call(values, 0, 2);
        }
      }

      this.$nextTick(function () {
        _this3.$refs.picker.setValues(values);
      });
    }
  },
  mounted: function mounted() {
    this.updateColumnValue(this.innerValue);
  }
});

/* script */
var __vue_script__ = script;
/* template */

var __vue_render__ = function __vue_render__() {
  var _vm = this;

  var _h = _vm.$createElement;

  var _c = _vm._self._c || _h;

  return _c('bxs-picker', {
    ref: "picker",
    attrs: {
      "picker-data": _vm.columns
    },
    on: {
      "change": _vm.onChange
    }
  });
};

var __vue_staticRenderFns__ = [];
/* style */

var __vue_inject_styles__ = undefined;
/* scoped */

var __vue_scope_id__ = undefined;
/* module identifier */

var __vue_module_identifier__ = undefined;
/* functional template */

var __vue_is_functional_template__ = false;
/* style inject */

/* style inject SSR */

var DatePickerView = __vue_normalize__({
  render: __vue_render__,
  staticRenderFns: __vue_staticRenderFns__
}, __vue_inject_styles__, __vue_script__, __vue_scope_id__, __vue_is_functional_template__, __vue_module_identifier__, undefined, undefined);

var _components$1;
var currentYear$1 = new Date().getFullYear();

var isValidDate$1 = function isValidDate(date) {
  return Object.prototype.toString.call(date) === '[object Date]' && !_Number$isNaN(date.getTime());
};

var isValidType$1 = function isValidType(type) {
  var _context;

  return _indexOfInstanceProperty(_context = ['datetime', 'date', 'time', 'year-month']).call(_context, type) !== -1;
};

var script$1 = create({
  name: 'pop-datetime-picker',
  props: {
    value: [Date, String],
    title: String,
    type: {
      type: String,
      default: 'datetime',
      validator: isValidType$1
    },
    formatter: {
      type: Function,
      default: function _default(type, value) {
        return value;
      }
    },
    minDate: {
      type: Date,
      default: function _default() {
        return new Date(currentYear$1 - 10, 0, 1);
      },
      validator: isValidDate$1
    },
    maxDate: {
      type: Date,
      default: function _default() {
        return new Date(currentYear$1 + 10, 11, 31);
      },
      validator: isValidDate$1
    },
    minHour: {
      type: Number,
      default: 0
    },
    maxHour: {
      type: Number,
      default: 23
    },
    minMinute: {
      type: Number,
      default: 0
    },
    maxMinute: {
      type: Number,
      default: 59
    },
    minSecond: {
      type: Number,
      default: 0
    },
    maxSecond: {
      type: Number,
      default: 59
    },
    confirmButtonColor: String
  },
  data: function data() {
    return {
      isShow: false,
      innerValue: ''
    };
  },
  computed: {},
  methods: {
    onConfirm: function onConfirm() {
      this.isShow = false;
      this.$emit('confirm', this.innerValue);
    },
    onCancel: function onCancel() {
      this.isShow = false;
      this.$emit('cancel');
    },
    onChange: function onChange(value) {
      this.$emit('change', value);
    }
  },
  watch: {
    value: function value(val) {
      this.innerValue = val;
    }
  },
  components: (_components$1 = {}, _components$1[bottomSheets.name] = bottomSheets, _components$1)
});

/* script */
var __vue_script__$1 = script$1;
/* template */

var __vue_render__$1 = function __vue_render__() {
  var _vm = this;

  var _h = _vm.$createElement;

  var _c = _vm._self._c || _h;

  return _c('bxs-bottom-sheets', {
    attrs: {
      "prevent-scroll-through": true
    },
    on: {
      "after-leave": function afterLeave($event) {
        _vm.$emit('after-leave');
      }
    },
    model: {
      value: _vm.isShow,
      callback: function callback($$v) {
        _vm.isShow = $$v;
      },
      expression: "isShow"
    }
  }, [_c('div', {
    staticClass: "bx-picker-sheets-header",
    attrs: {
      "slot": "header"
    },
    slot: "header"
  }, [_c('div', {
    staticClass: "bx-picker-header bx-hairline--bottom"
  }, [_c('p', {
    staticClass: "bx-picker-cancel",
    on: {
      "click": function click($event) {
        _vm.onCancel();
      }
    }
  }, [_vm._v("\n        取消\n      ")]), _c('p', {
    staticClass: "bx-picker-title"
  }, [_vm._v("\n        " + _vm._s(_vm.title) + "\n      ")]), _c('p', {
    staticClass: "bx-picker-sure",
    style: {
      color: _vm.confirmButtonColor
    },
    on: {
      "click": function click($event) {
        _vm.onConfirm();
      }
    }
  }, [_vm._v("\n        确定\n      ")])])]), _c('bxs-datetime-picker', {
    ref: "datetimePicker",
    attrs: {
      "type": _vm.type,
      "min-date": _vm.minDate,
      "max-date": _vm.maxDate,
      "max-hour": _vm.maxHour,
      "min-hour": _vm.minHour,
      "max-minite": _vm.maxMinute,
      "min-minite": _vm.minHour,
      "max-second": _vm.maxSecond,
      "min-second": _vm.minSecond,
      "formatter": _vm.formatter
    },
    on: {
      "change": _vm.onChange
    },
    model: {
      value: _vm.innerValue,
      callback: function callback($$v) {
        _vm.innerValue = $$v;
      },
      expression: "innerValue"
    }
  })], 1);
};

var __vue_staticRenderFns__$1 = [];
/* style */

var __vue_inject_styles__$1 = undefined;
/* scoped */

var __vue_scope_id__$1 = undefined;
/* module identifier */

var __vue_module_identifier__$1 = undefined;
/* functional template */

var __vue_is_functional_template__$1 = false;
/* style inject */

/* style inject SSR */

var PopDatePickerView = __vue_normalize__({
  render: __vue_render__$1,
  staticRenderFns: __vue_staticRenderFns__$1
}, __vue_inject_styles__$1, __vue_script__$1, __vue_scope_id__$1, __vue_is_functional_template__$1, __vue_module_identifier__$1, undefined, undefined);

function isObj(x) {
  var type = typeof x;
  return x !== null && (type === 'object' || type === 'function');
}

var defaultOptions = {
  title: '选择日期',
  type: 'date'
};

var currentOptions = _extends({}, defaultOptions);

var instance = {};

function createInstance() {
  var datePicker = new (Vue.extend(PopDatePickerView))({
    el: document.createElement('div')
  });
  document.body.appendChild(datePicker.$el);
  instance = datePicker;
  return instance;
}

function destroy() {
  if (_Object$keys(instance).length === 0) return;
  instance.isShow = false;
  instance.$on('after-leave', function () {
    return instance.$destroy();
  });
}

function functionCheck(target, targetStr, callback) {
  if (typeof target === 'function') {
    callback();
  } else {
    console.error("type check failed for \"" + targetStr + "\"  Expected Function!");
  }
}

function DatePicker(options) {
  if (options === void 0) {
    options = {};
  }

  var datePicker = createInstance();

  if (!isObj(options)) {
    console.error('type check failed for "options". Expected Object!');
  } else {
    var opt = _extends({}, currentOptions, {}, options);

    _extends(datePicker, opt);

    datePicker.isShow = true;
    datePicker.$on('cancel', function () {
      functionCheck(opt.cancel, 'cancel', function () {
        opt.cancel();
        destroy();
      });
    });
    datePicker.$on('confirm', function (innerValue) {
      functionCheck(opt.confirm, 'confirm', function () {
        opt.confirm(innerValue);
        destroy();
      });
    });
    datePicker.$on('change', function (picker) {
      functionCheck(opt.change, 'change', function () {
        opt.change(picker);
      });
    });
    return datePicker;
  }
}

DatePicker.close = function () {
  destroy();
};
/**
 * TODO:经过create.js的封装，组件都会有默认的install方法，Vue.use的作用就是全局注册该组件。
 * 外层注册DatePickerView是为了在组件内全局注册，从而使pop-datetime-picker可以引入。install函数内使用传入的全局对象注册，从而使得宿主环境可以直接标签式引入组件。
 * 疑问： DatePickerView组件只在pop-datetime-picker组件内局部引用的时候，会无法注册。待解决！

*/
// 组件全局注册datetime-picker


Vue.use(DatePickerView);

DatePicker.install = function (vueGlobal) {
  /* eslint no-param-reassign: ["error", { "props": false }] */
  // 宿主环境注册datetime-picker
  vueGlobal.use(DatePickerView);
  vueGlobal.prototype.$datetime = DatePicker;
};

export default DatePicker;
