import { ArrowChevronUp16BoldBlueIcon, ArrowChevronDown16BoldBlueIcon } from '@cloudtower/icons-react';
import { parrotI18n } from '@cloudtower/parrot';
import { cx } from '@linaria/core';
import Button from '../../core/Button/index.js';
import Icon from '../../core/Icon/index.js';
import Input from '../../core/Input/index.js';
import { Typo } from '../../core/Typo/index.js';
import useElementIntersectionRatio from '../../hooks/useElementIntersectionRatio.js';
import useParrotTranslation from '../../hooks/useParrotTranslation.js';
import dayjs from 'dayjs';
import React__default, { useState, useEffect, useRef } from 'react';
import { getDiffMonthAndDate, getTime, checkDateNotInRange, getClassNameForDateBlock } from './common.js';
import { CalendarStyle } from './DateRangePicker.style.js';
import { getCalendarTitle } from '../common/getCalendarTitle.js';

const Year = (props) => {
  const { year, onChange } = props;
  const { t } = useParrotTranslation();
  const [tmpYear, setTmpYear] = useState(year);
  const [edit, setEdit] = useState(false);
  function handleChangeYear() {
    if (tmpYear <= 1900 || tmpYear >= 2500) {
      setTmpYear(year);
      onChange(year);
    } else {
      onChange(tmpYear);
    }
    setEdit(false);
  }
  return /* @__PURE__ */ React__default.createElement(CalendarStyle.Year, null, /* @__PURE__ */ React__default.createElement("div", { className: cx("year-number", Typo.Label.l1_bold) }, edit ? /* @__PURE__ */ React__default.createElement(
    Input,
    {
      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.createElement("span", { className: "year-number-text", onClick: () => setEdit(true) }, year), t("common.year")), /* @__PURE__ */ React__default.createElement("div", { className: "year-control" }, /* @__PURE__ */ React__default.createElement(
    Button,
    {
      prefixIcon: /* @__PURE__ */ React__default.createElement(Icon, { src: ArrowChevronUp16BoldBlueIcon }),
      size: "small",
      type: "secondary",
      shape: "circle",
      onClick: () => onChange(year - 1)
    }
  ), /* @__PURE__ */ React__default.createElement(
    Button,
    {
      prefixIcon: /* @__PURE__ */ React__default.createElement(Icon, { src: 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,
    parentElement,
    onRangeChange,
    onMouseEnter
  } = props;
  useParrotTranslation();
  const containerRef = useRef(null);
  const datesContainerRef = useRef(null);
  const headerRef = 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;
  useEffect(() => {
    var _a2, _b2;
    if (dayjs().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 = [getTime(initYear, month, date), null];
    } else if (rangeStart && !rangeEnd) {
      _range[1] = dayjs(
        `${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 = [getTime(initYear, month, date), null];
    }
    onRangeChange(_range);
  }
  return /* @__PURE__ */ React__default.createElement("li", { className: "month-container", ref: containerRef }, /* @__PURE__ */ React__default.createElement(
    "header",
    {
      className: cx(Typo.Label.l1_bold, isPinned && "pinned"),
      ref: headerRef
    },
    getCalendarTitle(initMonth.month.toString(), parrotI18n.t, parrotI18n)
  ), /* @__PURE__ */ React__default.createElement("div", { className: "dates-in-month", ref: datesContainerRef }, new Array(initMonth.firstDateOfDay).fill(null).map((value, index) => /* @__PURE__ */ React__default.createElement("span", { key: `blank-date-${index}`, className: "blank" })), initMonth.dates.map((date) => {
    const _date = getTime(initYear, initMonth.month, date);
    const dateNotIncludeInRange = checkDateNotInRange(
      _date,
      minDate,
      maxDate
    );
    const disabled = Boolean(
      rangeStart && !rangeEnd && rangeStart.valueOf() > _date.valueOf()
    ) || !dateNotIncludeInRange;
    const dateClassName = 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.createElement(
      "span",
      {
        key: `date-${date}`,
        className: 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.createElement("span", { className: cx("date-text", dateClassName) }, date)
    );
  })));
};
const Month = (props) => {
  const { year, range, minDate, maxDate, onRangeChange } = props;
  const monthContainerRef = useRef(null);
  const [month, setMonth] = useState([]);
  const [highlightDay, setHighlightDay] = useState(() => {
    if (range[0] && range[1]) {
      return getDiffMonthAndDate(range[0], range[1]);
    }
    return null;
  });
  const controlHighlightDay = range[0] && range[1] ? getDiffMonthAndDate(range[0], range[1]) : null;
  useEffect(() => {
    const monthAndDate = [];
    for (let month2 = 1; month2 <= 12; month2++) {
      const time = dayjs(`${year}-${month2}`, "YYYY-M");
      const allDateInMonth = time.daysInMonth();
      const dates = new Array(allDateInMonth).fill(1).map((value, index) => index + 1);
      const firstDateOfDay = time.set("date", dates[0]).day();
      monthAndDate.push({
        month: month2,
        dates,
        firstDateOfDay: Math.max(firstDateOfDay - 1, 0)
      });
    }
    setMonth(monthAndDate);
  }, [year]);
  function handleMouseEnterDate(date) {
    if (range[0] && date) {
      const diffDay = 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.createElement(
    CalendarStyle.Month,
    {
      ref: monthContainerRef,
      onMouseMove: handleMouseOutMonthUl
    },
    /* @__PURE__ */ React__default.createElement("ul", null, month.map((m) => /* @__PURE__ */ React__default.createElement(
      MonthItem,
      {
        key: m.month,
        year,
        month: m,
        range,
        minDate,
        maxDate,
        highlightDay: highlightDay || controlHighlightDay || [],
        parentElement: monthContainerRef,
        onRangeChange,
        onMouseEnter: handleMouseEnterDate
      }
    )))
  );
};
const Week = () => {
  const { t } = useParrotTranslation();
  return /* @__PURE__ */ React__default.createElement(CalendarStyle.Week, null, /* @__PURE__ */ React__default.createElement("li", { className: Typo.Label.l1_regular }, t("components.monday-simple")), /* @__PURE__ */ React__default.createElement("li", { className: Typo.Label.l1_regular }, t("components.tuesday-simple")), /* @__PURE__ */ React__default.createElement("li", { className: Typo.Label.l1_regular }, t("components.wednesday-simple")), /* @__PURE__ */ React__default.createElement("li", { className: Typo.Label.l1_regular }, t("components.thursday-simple")), /* @__PURE__ */ React__default.createElement("li", { className: Typo.Label.l1_regular }, t("components.friday-simple")), /* @__PURE__ */ React__default.createElement("li", { className: Typo.Label.l1_regular }, t("components.saturday-simple")), /* @__PURE__ */ React__default.createElement("li", { className: Typo.Label.l1_regular }, t("components.sunday-simple")));
};
const Calendar = (props) => {
  const { range: initRange, minDate, maxDate, onChange } = props;
  const [year, setYear] = useState(dayjs().year());
  const [range, setRange] = useState(
    initRange || [null, null]
  );
  useEffect(() => {
    setRange(initRange || [null, null]);
  }, [initRange]);
  function handleRangeChange(newRange) {
    setRange(newRange);
    onChange == null ? void 0 : onChange(newRange);
  }
  return /* @__PURE__ */ React__default.createElement(CalendarStyle.Wrapper, { className: "date-range-picker-calendar" }, /* @__PURE__ */ React__default.createElement(Year, { year, onChange: setYear }), /* @__PURE__ */ React__default.createElement(Week, null), /* @__PURE__ */ React__default.createElement(
    Month,
    {
      year,
      range,
      minDate,
      maxDate,
      onRangeChange: handleRangeChange
    }
  ));
};
var Calendar$1 = Calendar;

export { Calendar$1 as default };
