import React, { useCallback, useMemo, useState, useEffect } from "react";
import classNames from "classnames";
import moment from "moment-timezone";
import { StyledButton, StyledButtonGroup, StyledDiv, StyledSpan, StyledControl } from "./Styles";
import { DatePicker } from "../../DatePicker/DatePicker";
import { ArrowRightIcon } from "../../Icons";
import ArrowLeftIcon from "../../Icons/collection/ArrowLeft";
/**
 * This component allow you to select date range. It accepts two parameters "from" and "to" as valid format
 * onChange and onBack and onForward it will return "from: Date" and "to: Date" as function arguments
 */

export const DateStepper = _ref => {
  let {
    step,
    formatCallback,
    onChange,
    from,
    to,
    onBack,
    onForward,
    minValue,
    maxValue,
    className,
    period = "week",
    withDatePicker = true,
    defaultMonth = moment(),
    enableYearPicker,
    position = "bottom",
    popperClassName,
    mode = "outlined",
    alwaysShowDate = false
  } = _ref;
  const [fromDate, setFromDate] = useState(moment.utc(from));
  const [toDate, setToDate] = useState(moment.utc(to));
  const getDatesByPeriod = useCallback(interval => {
    const date = fromDate ? fromDate : moment();
    if (step === "daily") {
      date.add(interval, "days");
      return [date, date.clone()];
    } else if (step === "weekly") {
      date.add(interval, "weeks");
      return [date.clone().startOf(period), date.clone().endOf(period)];
    } else if (step === "monthly") {
      date.add(interval, "months");
      return [date.clone().startOf("month"), date.clone().endOf("month")];
    } else if (step === "quarterly") {
      date.add(interval, "quarters");
      return [date.clone().startOf("quarter"), date.clone().endOf("quarter")];
    } else if (step === "yearly") {
      date.add(interval, "years");
      return [date.clone().startOf("year"), date.clone().endOf("year")];
    }
    return [date, date];
  }, [fromDate, period, step]);
  const getDateFormatted = useMemo(() => {
    if (formatCallback) {
      return formatCallback(fromDate, toDate);
    }
    const actualYear = moment().year();
    const showWeekOrCustomDateFormat = (start, end) => {
      if (start.year() === actualYear && end.year() === actualYear) {
        return start.utc().format("MMM DD") + " - " + end.utc().format("MMM DD");
      } else {
        return start.utc().format("MMM DD YYYY") + " - " + end.utc().format("MMM DD YYYY");
      }
    };
    if (step === "daily") {
      if (fromDate.year() === actualYear) {
        return fromDate.utc().format("MMM DD");
      }
      return fromDate.utc().format("MMM DD YYYY");
    } else if (step === "weekly") {
      const startDate = fromDate.clone().utc().startOf(period);
      const endDate = startDate.clone().utc().endOf(period);
      return showWeekOrCustomDateFormat(startDate, endDate);
    } else if (step === "monthly") {
      return fromDate.utc().format("MMM YYYY");
    } else if (step === "quarterly") {
      return "Q" + fromDate.utc().quarter() + "/" + fromDate.utc().format("YYYY");
    } else if (step === "yearly") {
      return fromDate.utc().format("YYYY");
    } else if (step === "range") {
      return showWeekOrCustomDateFormat(fromDate, toDate);
    }
    return "";
  }, [fromDate, toDate, step, formatCallback, period]);
  const datePickerMode = useMemo(() => {
    if (step === "range") return "custom";
    if (step === "yearly") return "custom";
    return step;
  }, [step]);
  const onDatePickerChange = useCallback(dates => {
    const fromDateTemp = moment.utc(Number(dates == null ? void 0 : dates.from) * 1000);
    const toDateTemp = moment.utc(Number(dates == null ? void 0 : dates.to) * 1000);
    setFromDate(fromDateTemp);
    setToDate(toDateTemp);
    if (onChange && moment.isMoment(fromDateTemp) && moment.isMoment(toDateTemp)) {
      onChange(fromDateTemp.toDate(), toDateTemp.toDate());
    }
  }, [onChange, setFromDate, setToDate]);
  const isAfterMaxDate = useMemo(() => {
    return moment.isMoment(maxValue) && moment(moment.utc(maxValue).format("YYYY-MM-DD")).isSameOrBefore(toDate.utc().format("YYYY-MM-DD"));
  }, [maxValue, toDate]);
  const isBeforeMinDate = useMemo(() => {
    return moment.isMoment(minValue) && moment.utc(moment.utc(minValue).format("YYYY-MM-DD")).isSameOrAfter(toDate.utc().format("YYYY-MM-DD"));
  }, [minValue, toDate]);
  useEffect(() => {
    if (isBeforeMinDate) {
      if (step === "daily") {
        setFromDate(moment.utc(minValue));
        setToDate(moment.utc(minValue));
      }
    }
    if (isAfterMaxDate) {
      if (step === "daily") {
        setFromDate(moment.utc(maxValue));
        setToDate(moment.utc(maxValue));
      }
    }
  }, [step, minValue, maxValue, isBeforeMinDate, isAfterMaxDate]);
  const onRightClickHandler = useCallback(() => {
    if (isAfterMaxDate) {
      return;
    }
    const [newFrom, newTo] = getDatesByPeriod(1);
    setFromDate(moment.utc(newFrom));
    setToDate(moment.utc(newTo));
    if (onChange) {
      onChange(moment.utc(newFrom), moment.utc(newTo));
    }
    if (onForward) {
      onForward(moment.utc(newFrom).toDate(), moment.utc(newTo).toDate());
    }
  }, [isAfterMaxDate, getDatesByPeriod, onChange, onForward]);
  const onLeftClickHandler = useCallback(() => {
    if (isBeforeMinDate) {
      return;
    }
    const [newFrom, newTo] = getDatesByPeriod(-1);
    setFromDate(moment.utc(newFrom));
    setToDate(moment.utc(newTo));
    if (onChange) {
      onChange(moment.utc(newFrom), moment.utc(newTo));
    }
    if (onBack) {
      onBack(moment.utc(newFrom).toDate(), moment.utc(newTo).toDate());
    }
  }, [isBeforeMinDate, getDatesByPeriod, onChange, onBack]);
  const renderLeftRightButtons = useMemo(() => {
    return step !== "range";
  }, [step]);
  useEffect(() => {
    setFromDate(moment.utc(from));
    setToDate(moment.utc(to));
  }, [from, to]);
  const dateStepperWidth = (fromDay, toDay, range) => {
    if (fromDay.utc().year() !== moment.utc().year() || toDay.utc().year() !== moment.utc().year()) {
      switch (range) {
        case "daily":
        case "monthly":
          return {
            minWidth: "122px"
          };
        case "weekly":
        case "custom":
          return {
            minWidth: "232px"
          };
      }
    }
    switch (range) {
      case "monthly":
        return {
          minWidth: "122px"
        };
      case "weekly":
      case "custom":
        return {
          minWidth: "182px"
        };
    }
    return {
      minWidth: "102px"
    };
  };
  const isDisabled = useCallback(day => {
    const dayFormat = moment.utc(day).format("YYYY-MM-DD");
    const isBefore = moment.isMoment(maxValue) && moment(moment.utc(maxValue).format("YYYY-MM-DD")).isBefore(dayFormat);
    const isAfter = moment.isMoment(minValue) && moment(moment.utc(minValue).format("YYYY-MM-DD")).isAfter(dayFormat);
    return isBefore || isAfter;
  }, [maxValue, minValue]);
  const modifiers = useMemo(() => ({
    disabled: day => ({
      matched: isDisabled(day),
      title: null
    }),
    nonWorkingDay: day => ({
      matched: isDisabled(day),
      title: null
    })
  }), [isDisabled]);
  return /*#__PURE__*/React.createElement(StyledButtonGroup, {
    className: classNames("c-date-stepper", className)
  }, renderLeftRightButtons ? /*#__PURE__*/React.createElement(StyledControl, {
    type: "button",
    variant: mode === "flat" ? "text gray" : "secondary",
    onClick: onLeftClickHandler,
    disabled: isBeforeMinDate
  }, /*#__PURE__*/React.createElement(ArrowLeftIcon, null)) : null, /*#__PURE__*/React.createElement(StyledDiv, {
    $isTargetable: step === "yearly" || !withDatePicker,
    $isRounded: step === "range",
    $mode: mode,
    $alwaysShowDate: alwaysShowDate,
    style: dateStepperWidth(fromDate, toDate, step)
  }, withDatePicker && step !== "yearly" ? /*#__PURE__*/React.createElement(DatePicker, {
    month: defaultMonth,
    target: /*#__PURE__*/React.createElement(StyledButton, {
      type: "button"
    }, getDateFormatted),
    mode: datePickerMode,
    selected: {
      from: moment.utc(fromDate).unix(),
      to: moment.utc(toDate).unix()
    },
    onChange: onDatePickerChange,
    firstDayOfWeek: period === "week" ? 0 : 1,
    modifiers: modifiers,
    disabledDaysAfter: maxValue,
    disabledDaysBefore: minValue,
    disableYearPicker: !enableYearPicker,
    popperClassName: popperClassName,
    position: position,
    key: datePickerMode,
    instant: true,
    required: true
  }) : /*#__PURE__*/React.createElement(StyledSpan, null, getDateFormatted)), renderLeftRightButtons ? /*#__PURE__*/React.createElement(StyledControl, {
    type: "button",
    variant: mode === "flat" ? "text gray" : "secondary",
    onClick: onRightClickHandler,
    disabled: isAfterMaxDate
  }, /*#__PURE__*/React.createElement(ArrowRightIcon, null)) : null);
};
DateStepper.displayName = "DateStepper";
//# sourceMappingURL=DateStepper.js.map