function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
import Picker from '../picker';
import { getMonthEndDay, getTrueValue, times } from './utils';
import { raf } from '../utils/raf';
import { isDate } from '../utils/validate/date';
import { padZero } from '../utils';
import { useUpdateEffect } from '../hooks';
var DatePicker = /*#__PURE__*/forwardRef(function (props, ref) {
  var formatValue = function formatValue(value) {
    if (!isDate(value)) {
      value = props.minDate;
    }

    value = Math.max(value, props.minDate.getTime());
    value = Math.min(value, props.maxDate.getTime());
    return new Date(value);
  };

  var picker = useRef(null);

  var _useState = useState(function () {
    return formatValue(props.value);
  }),
      currentDate = _useState[0],
      setCurrentDate = _useState[1];

  var currentDateRef = useRef(undefined);
  currentDateRef.current = currentDate;

  var getBoundary = function getBoundary(type, value) {
    var _ref;

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

    if (type === 'max') {
      month = 12;
      date = getMonthEndDay(value.getFullYear(), value.getMonth() + 1);
      hour = 23;
      minute = 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();
          }
        }
      }
    }

    return _ref = {}, _ref[type + "Year"] = year, _ref[type + "Month"] = month, _ref[type + "Date"] = date, _ref[type + "Hour"] = hour, _ref[type + "Minute"] = minute, _ref;
  };

  var ranges = useMemo(function () {
    var _getBoundary = getBoundary('max', currentDate),
        maxYear = _getBoundary.maxYear,
        maxDate = _getBoundary.maxDate,
        maxMonth = _getBoundary.maxMonth,
        maxHour = _getBoundary.maxHour,
        maxMinute = _getBoundary.maxMinute;

    var _getBoundary2 = getBoundary('min', currentDate),
        minYear = _getBoundary2.minYear,
        minDate = _getBoundary2.minDate,
        minMonth = _getBoundary2.minMonth,
        minHour = _getBoundary2.minHour,
        minMinute = _getBoundary2.minMinute;

    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]
    }];

    switch (props.type) {
      case 'date':
        result = result.slice(0, 3);
        break;

      case 'year-month':
        result = result.slice(0, 2);
        break;

      case 'month-day':
        result = result.slice(1, 3);
        break;

      case 'datehour':
        result = result.slice(0, 4);
        break;

      default:
        break;
    }

    if (props.columnsOrder) {
      var columnsOrder = props.columnsOrder.concat(result.map(function (column) {
        return column.type;
      }));
      result.sort(function (a, b) {
        return columnsOrder.indexOf(a.type) - columnsOrder.indexOf(b.type);
      });
    }

    return result;
  }, [currentDate]);
  var originColumns = useMemo(function () {
    return ranges.map(function (_ref2) {
      var type = _ref2.type,
          rangeArr = _ref2.range;
      // 根据范围获取每列的值
      var values = times(rangeArr[1] - rangeArr[0] + 1, function (index) {
        return padZero(rangeArr[0] + index);
      });

      if (props.filter) {
        values = props.filter(type, values);
      }

      return {
        type: type,
        values: values
      };
    });
  }, [ranges]);

  var updateColumnValue = function updateColumnValue() {
    var formatter = props.formatter;
    var values = originColumns.map(function (column) {
      switch (column.type) {
        case 'year':
          return formatter('year', "" + currentDate.getFullYear());

        case 'month':
          return formatter('month', padZero(currentDate.getMonth() + 1));

        case 'day':
          return formatter('day', padZero(currentDate.getDate()));

        case 'hour':
          return formatter('hour', padZero(currentDate.getHours()));

        case 'minute':
          return formatter('minute', padZero(currentDate.getMinutes()));

        default:
          // no default
          return '';
      }
    });
    raf(function () {
      var _picker$current;

      (_picker$current = picker.current) == null ? void 0 : _picker$current.setValues(values);
    });
  };

  var updateInnerValue = function updateInnerValue() {
    var _picker$current2;

    var type = props.type;
    var indexes = (_picker$current2 = picker.current) == null ? void 0 : _picker$current2.getIndexes();

    var getValue = function getValue(datetimePickerColumnType) {
      var index = 0;
      originColumns.forEach(function (column, columnIndex) {
        if (datetimePickerColumnType === column.type) {
          index = columnIndex;
        }
      });
      var values = originColumns[index].values;
      return getTrueValue(values[indexes[index]]);
    };

    var year = null;
    var month = null;
    var day = null;

    if (type === 'month-day') {
      year = (currentDate || props.minDate).getFullYear();
      month = getValue('month');
      day = getValue('day');
    } else {
      year = getValue('year');
      month = getValue('month');
      day = type === 'year-month' ? 1 : getValue('day');
    }

    var maxDay = getMonthEndDay(year, month);
    day = day > maxDay ? maxDay : day;
    var hour = 0;
    var minute = 0;

    if (type === 'datehour') {
      hour = +getValue('hour');
    }

    if (type === 'datetime') {
      hour = +getValue('hour');
      minute = +getValue('minute');
    }

    var value = new Date(year, month - 1, day, hour, minute);
    setCurrentDate(formatValue(value));
  };

  var onChange = function onChange() {
    updateInnerValue();

    if (props.onChange) {
      props.onChange(currentDateRef.current);
    }
  };

  var onConfirm = function onConfirm() {
    if (props.onConfirm) {
      props.onConfirm(currentDate);
    }
  };

  var columns = useMemo(function () {
    return originColumns.map(function (column) {
      return {
        values: column.values.map(function (value) {
          return props.formatter(column.type, value);
        })
      };
    });
  }, [originColumns]);
  useEffect(function () {
    updateColumnValue();
  }, [columns]);
  useUpdateEffect(function () {
    updateInnerValue();
  }, [props.filter, props.maxDate]);
  useUpdateEffect(function () {
    setTimeout(updateInnerValue, 0);
  }, [props.minDate]);
  useUpdateEffect(function () {
    var value = formatValue(props.value);

    if (value && value.valueOf() !== (currentDate == null ? void 0 : currentDate.valueOf())) {
      setCurrentDate(value);
    }
  }, [props.value]);
  useImperativeHandle(ref, function () {
    return {
      getPicker: function getPicker() {
        return picker.current;
      }
    };
  });
  return /*#__PURE__*/React.createElement(Picker, _extends({}, props, {
    ref: picker,
    columns: columns,
    onChange: onChange,
    onConfirm: onConfirm,
    onCancel: props.onCancel
  }));
});
var currentYear = new Date().getFullYear();
DatePicker.defaultProps = {
  type: 'datetime',
  minDate: new Date(currentYear - 10, 0, 1),
  maxDate: new Date(currentYear + 10, 11, 31),
  formatter: function formatter(type, value) {
    return value;
  }
};
export default DatePicker;