var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __objRest = (source, exclude) => {
  var target = {};
  for (var prop in source)
    if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
      target[prop] = source[prop];
  if (source != null && __getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(source)) {
      if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
        target[prop] = source[prop];
    }
  return target;
};
function _extends() {
  _extends = Object.assign ? Object.assign.bind() : 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, memo, useCallback } from "react";
import Picker from "../picker";
import { getMonthEndDay, getTrueValue, times } from "./utils";
import { useUpdateEffect } from "../hooks";
import { isDate } from "../utils/validate/date";
import { padZero } from "../utils";
import { doubleRaf } from "../utils/raf";
import useRefState from "../hooks/use-ref-state";
const DatePicker = /* @__PURE__ */ forwardRef((props, ref) => {
  const _a = props, {
    value,
    formatter,
    columnsOrder,
    type: datePickerType,
    filter,
    minDate: datePickerMinDate,
    maxDate: datePickerMaxDate
  } = _a, pickerProps = __objRest(_a, [
    "value",
    "formatter",
    "columnsOrder",
    "type",
    "filter",
    "minDate",
    "maxDate"
  ]);
  const formatValue = (date) => {
    if (!isDate(date)) {
      date = props.minDate;
    }
    date = Math.max(new Date(date).getTime(), props.minDate.getTime());
    date = Math.min(date, props.maxDate.getTime());
    return new Date(date);
  };
  const pickerRef = useRef(null);
  const [currentDate, setCurrentDate, currentDateRef] = useRefState(formatValue(value));
  const getBoundary = (type, dateValue) => {
    const boundary = props[`${type}Date`];
    const year = boundary.getFullYear();
    let month = 1;
    let date = 1;
    let hour = 0;
    let minute = 0;
    if (type === "max") {
      month = 12;
      date = getMonthEndDay(dateValue.getFullYear(), dateValue.getMonth() + 1);
      hour = 23;
      minute = 59;
    }
    if (dateValue.getFullYear() === year) {
      month = boundary.getMonth() + 1;
      if (dateValue.getMonth() + 1 === month) {
        date = boundary.getDate();
        if (dateValue.getDate() === date) {
          hour = boundary.getHours();
          if (dateValue.getHours() === hour) {
            minute = boundary.getMinutes();
          }
        }
      }
    }
    return {
      [`${type}Year`]: year,
      [`${type}Month`]: month,
      [`${type}Date`]: date,
      [`${type}Hour`]: hour,
      [`${type}Minute`]: minute
    };
  };
  const ranges = useMemo(() => {
    const {
      maxYear,
      maxDate: maxDate2,
      maxMonth,
      maxHour,
      maxMinute
    } = getBoundary("max", currentDateRef.current);
    const {
      minYear,
      minDate: minDate2,
      minMonth,
      minHour,
      minMinute
    } = getBoundary("min", currentDateRef.current);
    let result = [{
      type: "year",
      range: [minYear, maxYear]
    }, {
      type: "month",
      range: [minMonth, maxMonth]
    }, {
      type: "day",
      range: [minDate2, maxDate2]
    }, {
      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 (columnsOrder) {
      const columnsOrderArr = columnsOrder.concat(result.map((column) => column.type));
      result.sort((a, b) => columnsOrderArr.indexOf(a.type) - columnsOrderArr.indexOf(b.type));
    }
    return result;
  }, [columnsOrder, props.type, currentDateRef.current]);
  const originColumns = useMemo(() => ranges.map(({
    type,
    range: rangeArr
  }) => {
    let values = times(rangeArr[1] - rangeArr[0] + 1, (index) => {
      return padZero(rangeArr[0] + index);
    });
    if (filter) {
      values = filter(type, values);
    }
    return {
      type,
      values
    };
  }), [filter, ranges]);
  const columns = useMemo(() => {
    return originColumns.map((column) => ({
      values: column.values.map((e) => formatter(column.type, e))
    }));
  }, [originColumns, formatter]);
  const updateColumnValue = useCallback(() => {
    const values = originColumns.map((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:
          return null;
      }
    });
    doubleRaf(() => {
      var _a2;
      (_a2 = pickerRef.current) == null ? void 0 : _a2.setValues(values);
    });
  }, [currentDate, formatter, originColumns]);
  const updateInnerValue = (indexes) => {
    const {
      type
    } = props;
    const getValue = (datetimePickerColumnType) => {
      let index = 0;
      originColumns.forEach((column, columnIndex) => {
        if (datetimePickerColumnType === column.type) {
          index = columnIndex;
        }
      });
      const {
        values
      } = originColumns[index];
      return getTrueValue(values[indexes[index]]);
    };
    let year = null;
    let month = null;
    let 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");
    }
    const maxDay = getMonthEndDay(year, month);
    day = day > maxDay ? maxDay : day;
    let hour = 0;
    let minute = 0;
    if (type === "datehour") {
      hour = +getValue("hour");
    }
    if (type === "datetime") {
      hour = +getValue("hour");
      minute = +getValue("minute");
    }
    return formatValue(new Date(year, month - 1, day, hour, minute));
  };
  const onChange = () => {
    var _a2;
    if (pickerRef.current) {
      const indexes = pickerRef.current.getIndexes();
      const nextValue = updateInnerValue(indexes);
      setCurrentDate(nextValue);
      (_a2 = props.onChange) == null ? void 0 : _a2.call(props, nextValue);
    }
  };
  const onConfirm = () => {
    var _a2;
    (_a2 = props.onConfirm) == null ? void 0 : _a2.call(props, currentDate);
  };
  useEffect(() => {
    updateColumnValue();
  }, [updateColumnValue]);
  const {
    minDate,
    maxDate
  } = props;
  useUpdateEffect(() => {
    const nextValue = formatValue(value);
    if (nextValue && nextValue.valueOf() !== (currentDate == null ? void 0 : currentDate.valueOf())) {
      setCurrentDate(nextValue);
    }
  }, [value, filter, minDate, maxDate]);
  useImperativeHandle(ref, () => ({
    getPicker: () => pickerRef.current
  }));
  return /* @__PURE__ */ React.createElement(Picker, _extends({}, pickerProps, {
    ref: pickerRef,
    columns,
    onChange,
    onConfirm,
    onCancel: props.onCancel
  }));
});
const currentYear = new Date().getFullYear();
DatePicker.defaultProps = {
  type: "datetime",
  minDate: new Date(currentYear - 10, 0, 1),
  maxDate: new Date(currentYear + 10, 11, 31),
  formatter: (type, value) => value
};
DatePicker.displayName = "DatePicker";
var stdin_default = /* @__PURE__ */ memo(DatePicker);
export {
  stdin_default as default
};
