'use strict';

var iconsReact = require('@cloudtower/icons-react');
var parrot = require('@cloudtower/parrot');
var core = require('@linaria/core');
var index$2 = require('../../core/Button/index.js');
var index$3 = require('../../core/Icon/index.js');
var index$1 = require('../../core/Input/index.js');
var index = require('../../core/Typo/index.js');
var useElementIntersectionRatio = require('../../hooks/useElementIntersectionRatio.js');
var useParrotTranslation = require('../../hooks/useParrotTranslation.js');
var unit = require('../../utils/unit.js');
var dayjs = require('dayjs');
var React = require('react');
var common = require('./common.js');
var DateRangePicker_style = require('./DateRangePicker.style.js');
var utils = require('./utils.js');
var getCalendarTitle = require('../common/getCalendarTitle.js');

function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }

var dayjs__default = /*#__PURE__*/_interopDefault(dayjs);
var React__default = /*#__PURE__*/_interopDefault(React);

const Year = (props) => {
  const { year, onChange } = props;
  const { t } = useParrotTranslation();
  const [tmpYear, setTmpYear] = React.useState(year);
  const [edit, setEdit] = React.useState(false);
  function handleChangeYear() {
    if (tmpYear <= 1900 || tmpYear >= 2500) {
      setTmpYear(year);
      onChange(year);
    } else {
      onChange(tmpYear);
    }
    setEdit(false);
  }
  return /* @__PURE__ */ React__default.default.createElement(DateRangePicker_style.CalendarStyle.Year, null, /* @__PURE__ */ React__default.default.createElement("div", { className: core.cx("year-number", index.Typo.Label.l1_bold) }, edit ? /* @__PURE__ */ React__default.default.createElement(
    index$1,
    {
      className: "year-number-input",
      value: tmpYear,
      onChange: (event) => {
        const newYear = parseInt(event.target.value);
        if (Number.isInteger(newYear)) {
          setTmpYear(newYear);
        } else {
          setTmpYear(year);
        }
      },
      onBlur: handleChangeYear,
      onKeyDown: (event) => {
        if (event.keyCode === 13) {
          handleChangeYear();
        }
      }
    }
  ) : /* @__PURE__ */ React__default.default.createElement("span", { className: "year-number-text", onClick: () => setEdit(true) }, year), t("common.year")), /* @__PURE__ */ React__default.default.createElement("div", { className: "year-control" }, /* @__PURE__ */ React__default.default.createElement(
    index$2,
    {
      prefixIcon: /* @__PURE__ */ React__default.default.createElement(index$3, { src: iconsReact.ArrowChevronUp16BoldBlueIcon }),
      size: "small",
      type: "secondary",
      shape: "circle",
      onClick: () => onChange(year - 1)
    }
  ), /* @__PURE__ */ React__default.default.createElement(
    index$2,
    {
      prefixIcon: /* @__PURE__ */ React__default.default.createElement(index$3, { src: iconsReact.ArrowChevronDown16BoldBlueIcon }),
      size: "small",
      type: "secondary",
      shape: "circle",
      onClick: () => onChange(year + 1)
    }
  )));
};
const MonthItem = (props) => {
  var _a, _b, _c;
  const {
    year: initYear,
    month: initMonth,
    range,
    highlightDay,
    minDate,
    maxDate,
    maxRange,
    parentElement,
    onRangeChange,
    onMouseEnter
  } = props;
  useParrotTranslation();
  const containerRef = React.useRef(null);
  const datesContainerRef = React.useRef(null);
  const headerRef = React.useRef(null);
  const entry = useElementIntersectionRatio(datesContainerRef, parentElement);
  const mapOfHighlightDay = highlightDay.reduce(
    (map, day, currentIndex) => {
      map.set(day, currentIndex);
      return map;
    },
    /* @__PURE__ */ new Map()
  );
  const scrollTop = ((_a = parentElement == null ? void 0 : parentElement.current) == null ? void 0 : _a.scrollTop) || 0;
  const offsetTop = ((_b = datesContainerRef.current) == null ? void 0 : _b.offsetTop) || 0;
  const headerHeight = ((_c = headerRef.current) == null ? void 0 : _c.offsetHeight) || 0;
  const isPinned = scrollTop - offsetTop + headerHeight > 0 && (entry == null ? void 0 : entry.isIntersecting);
  const [rangeStart, rangeEnd] = range;
  React.useEffect(() => {
    var _a2, _b2;
    if (dayjs__default.default().month() + 1 === initMonth.month && containerRef.current && !rangeStart && !rangeEnd) {
      (_a2 = containerRef.current) == null ? void 0 : _a2.scrollIntoView();
    } else if (rangeStart && rangeEnd && rangeEnd.month() + 1 === initMonth.month) {
      (_b2 = containerRef.current) == null ? void 0 : _b2.scrollIntoView({
        block: "center"
      });
    }
  }, []);
  function clickDate(date) {
    let _range = [...range];
    const month = initMonth.month;
    if (!rangeStart && !rangeEnd) {
      _range = [common.getTime(initYear, month, date), null];
    } else if (rangeStart && !rangeEnd) {
      _range[1] = dayjs__default.default(
        `${initYear}-${month}-${date} 23:59:59`,
        "YYYY-M-D HH:mm:ss"
      );
      _range = _range.sort((a, b) => {
        return ((a == null ? void 0 : a.valueOf()) || 0) - ((b == null ? void 0 : b.valueOf()) || 0);
      });
    } else if (rangeStart && rangeEnd) {
      _range = [common.getTime(initYear, month, date), null];
    }
    onRangeChange(_range);
  }
  const datesElements = React.useMemo(() => {
    return initMonth.dates.map((date) => {
      const _date = common.getTime(initYear, initMonth.month, date);
      const { number: maxRangeNumber, unit: maxRangeUnit } = unit.parseNumberAndUnit(maxRange || "") || {};
      const dateNotIncludeInRange = common.checkDateNotInRange(
        _date,
        minDate,
        maxDate
      );
      const isLimitRangeEnd = !!rangeStart && !rangeEnd;
      const isDateBeforeRangeStart = isLimitRangeEnd ? _date.valueOf() < rangeStart.valueOf() : false;
      const isDateNotIncludeInMaxRange = isLimitRangeEnd && maxRangeNumber && maxRangeUnit ? rangeStart.add(maxRangeNumber, maxRangeUnit).valueOf() <= _date.valueOf() : false;
      const disabled = Boolean(isDateBeforeRangeStart || isDateNotIncludeInMaxRange) || !dateNotIncludeInRange;
      const dateClassName = common.getClassNameForDateBlock(
        range,
        _date,
        mapOfHighlightDay,
        disabled
      );
      const highlightIndex = mapOfHighlightDay.get(_date.format("YYYY-MM-DD"));
      const isFirstDayInWeek = _date.day() === 1;
      const isLastDayInWeek = _date.day() === 0;
      const isFirstDayInMonth = _date.date() === 1;
      const isLastDayInMonth = _date.date() === _date.daysInMonth();
      const isLastDayIsSingleDayInWeek = isLastDayInMonth && isFirstDayInWeek;
      const isFirstHighlight = highlightIndex === 0 || isFirstDayInWeek || isFirstDayInMonth || isLastDayIsSingleDayInWeek;
      const isLastHighlight = highlightIndex === Math.max(mapOfHighlightDay.size - 1, 0) || isLastDayInWeek || isLastDayInMonth;
      return /* @__PURE__ */ React__default.default.createElement(
        "span",
        {
          key: `date-${date}`,
          className: core.cx(
            "date-block",
            dateClassName,
            isFirstHighlight && "first-highlight",
            isLastHighlight && "last-highlight"
          ),
          onClick: () => {
            if (disabled) {
              return;
            }
            clickDate(date);
          },
          onMouseEnter: () => {
            if (disabled) {
              onMouseEnter(null);
            } else if (rangeStart && !rangeEnd) {
              onMouseEnter(_date);
            }
          }
        },
        /* @__PURE__ */ React__default.default.createElement("span", { className: core.cx("date-text", dateClassName) }, date)
      );
    });
  }, [
    initMonth.dates,
    initMonth.month,
    initYear,
    maxRange,
    minDate,
    maxDate,
    rangeStart,
    rangeEnd,
    range,
    mapOfHighlightDay,
    clickDate,
    onMouseEnter
  ]);
  return /* @__PURE__ */ React__default.default.createElement("li", { className: "month-container", ref: containerRef }, /* @__PURE__ */ React__default.default.createElement(
    "header",
    {
      className: core.cx(index.Typo.Label.l1_bold, isPinned && "pinned"),
      ref: headerRef
    },
    getCalendarTitle.getCalendarTitle(initMonth.month.toString(), parrot.parrotI18n.t, parrot.parrotI18n)
  ), /* @__PURE__ */ React__default.default.createElement("div", { className: "dates-in-month", ref: datesContainerRef }, new Array(initMonth.firstDateOfDay).fill(null).map((value, index) => /* @__PURE__ */ React__default.default.createElement("span", { key: `blank-date-${index}`, className: "blank" })), datesElements));
};
const Month = (props) => {
  const { year, range, minDate, maxDate, maxRange, onRangeChange } = props;
  const monthContainerRef = React.useRef(null);
  const [month, setMonth] = React.useState([]);
  const [highlightDay, setHighlightDay] = React.useState(() => {
    if (range[0] && range[1]) {
      return common.getDiffMonthAndDate(range[0], range[1]);
    }
    return null;
  });
  const controlHighlightDay = range[0] && range[1] ? common.getDiffMonthAndDate(range[0], range[1]) : null;
  React.useEffect(() => {
    const monthAndDate = [];
    for (let month2 = 1; month2 <= 12; month2++) {
      const time = dayjs__default.default(`${year}-${month2}`, "YYYY-M");
      const allDateInMonth = time.daysInMonth();
      const dates = new Array(allDateInMonth).fill(1).map((value, index) => index + 1);
      monthAndDate.push({
        month: month2,
        dates,
        firstDateOfDay: utils.getFirstDateOfMonth(time)
      });
    }
    setMonth(monthAndDate);
  }, [year]);
  function handleMouseEnterDate(date) {
    if (range[0] && date) {
      const diffDay = common.getDiffMonthAndDate(range[0], date);
      setHighlightDay(diffDay);
    } else {
      setHighlightDay(null);
    }
  }
  function handleMouseOutMonthUl(event) {
    if (!range[0] || range[1] || !event.target) {
      return;
    }
    if (event.target.classList.contains("disabled")) {
      return;
    }
    if (!event.target.classList.contains("date")) {
      setHighlightDay(null);
    }
  }
  return /* @__PURE__ */ React__default.default.createElement(
    DateRangePicker_style.CalendarStyle.Month,
    {
      ref: monthContainerRef,
      onMouseMove: handleMouseOutMonthUl
    },
    /* @__PURE__ */ React__default.default.createElement("ul", null, month.map((m) => /* @__PURE__ */ React__default.default.createElement(
      MonthItem,
      {
        key: m.month,
        year,
        month: m,
        range,
        minDate,
        maxDate,
        maxRange,
        highlightDay: controlHighlightDay || highlightDay || [],
        parentElement: monthContainerRef,
        onRangeChange,
        onMouseEnter: handleMouseEnterDate
      }
    )))
  );
};
const Week = () => {
  const { t } = useParrotTranslation();
  return /* @__PURE__ */ React__default.default.createElement(DateRangePicker_style.CalendarStyle.Week, null, /* @__PURE__ */ React__default.default.createElement("li", { className: index.Typo.Label.l1_regular }, t("components.monday-simple")), /* @__PURE__ */ React__default.default.createElement("li", { className: index.Typo.Label.l1_regular }, t("components.tuesday-simple")), /* @__PURE__ */ React__default.default.createElement("li", { className: index.Typo.Label.l1_regular }, t("components.wednesday-simple")), /* @__PURE__ */ React__default.default.createElement("li", { className: index.Typo.Label.l1_regular }, t("components.thursday-simple")), /* @__PURE__ */ React__default.default.createElement("li", { className: index.Typo.Label.l1_regular }, t("components.friday-simple")), /* @__PURE__ */ React__default.default.createElement("li", { className: index.Typo.Label.l1_regular }, t("components.saturday-simple")), /* @__PURE__ */ React__default.default.createElement("li", { className: index.Typo.Label.l1_regular }, t("components.sunday-simple")));
};
const Calendar = (props) => {
  const { range: initRange, minDate, maxDate, maxRange, onChange } = props;
  const [year, setYear] = React.useState(dayjs__default.default().year());
  const [range, setRange] = React.useState(
    initRange || [null, null]
  );
  React.useEffect(() => {
    setRange(initRange || [null, null]);
  }, [initRange]);
  function handleRangeChange(newRange) {
    setRange(newRange);
    onChange == null ? void 0 : onChange(newRange);
  }
  return /* @__PURE__ */ React__default.default.createElement(DateRangePicker_style.CalendarStyle.Wrapper, { className: "date-range-picker-calendar" }, /* @__PURE__ */ React__default.default.createElement(Year, { year, onChange: setYear }), /* @__PURE__ */ React__default.default.createElement(Week, null), /* @__PURE__ */ React__default.default.createElement(
    Month,
    {
      year,
      range,
      minDate,
      maxDate,
      maxRange,
      onRangeChange: handleRangeChange
    }
  ));
};
var Calendar$1 = Calendar;

module.exports = Calendar$1;
