"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var Calendar_exports = {};
__export(Calendar_exports, {
  default: () => Calendar_default
});
module.exports = __toCommonJS(Calendar_exports);
var import_jsx_runtime = require("react/jsx-runtime");
var import_react = __toESM(require("react"));
var import_styled_components = __toESM(require("styled-components"));
var import_yoga_icons = require("@gympass/yoga-icons");
var import_prop_types = require("prop-types");
var import_lodash = __toESM(require("lodash"));
var import__ = require("../..");
const CalendarWrapper = import_styled_components.default.div`
  ${({
  theme: {
    yoga: { spacing }
  }
}) => `
    padding: ${spacing.xsmall}px ${spacing.xsmall}px ${spacing.small}px ${spacing.xsmall}px;
  `}
`;
const DaysWrapper = import_styled_components.default.div`
  ${({
  theme: {
    yoga: { spacing }
  }
}) => `
    display: flex;
    justify-content: space-between;
    margin: ${spacing.xxsmall}px ${spacing.zero}px ${spacing.xsmall}px ${spacing.zero}px;
  `}
`;
const Day = (0, import_styled_components.default)(import__.Text.Overline)`
  ${({
  theme: {
    yoga: { colors }
  }
}) => `
    width: 40px;
    color: ${colors.elements.selectionAndIcons};
    text-align: center;
  `}
`;
const Month = (0, import_styled_components.default)(import__.Text.Body2)`
  ${({
  theme: {
    yoga: { colors, v3theme }
  }
}) => `
    color: ${v3theme ? colors.primary : colors.text.primary};
    align-self: center;
    &:first-letter {
      text-transform: capitalize;
    };
  `}
`;
const getDayFieldColor = (selected, disabled, colors, aux) => {
  if (selected && !disabled) {
    return colors.white;
  }
  if (disabled) {
    return colors.text.disabled;
  }
  const currentDate = /* @__PURE__ */ new Date();
  const { val, year, month } = aux;
  if (
    // if current date
    new Date(Date.UTC(year, month, val)).getTime() === new Date(
      Date.UTC(
        currentDate.getFullYear(),
        currentDate.getMonth(),
        currentDate.getDate()
      )
    ).getTime()
  ) {
    return colors.primary;
  }
  return colors.stamina;
};
const toUTCTime = (date) => Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
const isSameDate = (firstDate, secondDate) => firstDate.getUTCDate() === secondDate.getUTCDate() && firstDate.getUTCMonth() === secondDate.getUTCMonth() && firstDate.getUTCFullYear() === secondDate.getUTCFullYear();
const getDayFieldRadius = (aux, radii) => {
  var _a;
  const { val, startDate, endDate, year, month } = aux;
  const currentDate = (_a = new Date(Date.UTC(year, month, val))) == null ? void 0 : _a.getTime();
  if (currentDate === toUTCTime(startDate) && endDate) {
    return `${radii.circle}px ${radii.sharp}px ${radii.sharp}px ${radii.circle}px`;
  }
  if (currentDate === toUTCTime(endDate) && startDate) {
    return `${radii.sharp}px ${radii.circle}px ${radii.circle}px ${radii.sharp}px`;
  }
  return `${radii.sharp}px`;
};
const DayField = import_styled_components.default.div`
  ${({
  selected,
  inRange,
  disabled,
  aux,
  theme: {
    yoga: {
      colors,
      radii,
      spacing,
      components: { datepicker }
    }
  }
}) => `
    p {
        color: ${getDayFieldColor(selected, disabled, colors, aux)};
        z-index: 1;
        position: absolute;
    }
    width: ${datepicker.width.day}px;
    height: ${datepicker.width.day}px;
    padding: ${spacing.zero}px 21.3px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: ${inRange ? colors.elements.lineAndBorders : colors.white};
    position: relative;
    cursor: pointer;
    ${selected && inRange ? `border-radius: ${getDayFieldRadius(aux, radii)};` : ``}
    ${selected && !disabled ? `&:before {
            content: '';
            position: absolute;
            background: ${colors.primary};
            width: ${datepicker.width.day}px;
            height: ${datepicker.width.day}px;
            border-radius: ${radii.circle}px;
        };` : ``}
    ${!disabled ? `&:hover {
            &:before {
              content: '';
              position: absolute;
              border: 1px solid ${colors.secondary};
              width: ${datepicker.width.day}px;
              height: ${datepicker.width.day}px;
              border-radius: ${radii.circle}px;
            }
          };` : ``}
`}
`;
const Row = import_styled_components.default.div`
  ${({
  theme: {
    yoga: { radii, spacing }
  }
}) => `
    display: flex;
    div:first-child {
        border-radius: ${radii.regular}px 0 0 ${radii.regular}px;
    }
    div:last-child {
        border-radius: 0 ${radii.regular}px ${radii.regular}px 0;
    }
    padding: ${spacing.xxxsmall}px 0px;
`}
`;
function Calendar({
  type,
  startDate,
  endDate,
  onSelectSingle = null,
  onSelectRange = null,
  disablePastDates = false,
  disableFutureDates = false,
  disablePastFrom,
  disableFutureFrom,
  locale
}) {
  const [month, setMonth] = (0, import_react.useState)((/* @__PURE__ */ new Date()).getUTCMonth());
  const [year, setYear] = (0, import_react.useState)((/* @__PURE__ */ new Date()).getUTCFullYear());
  (0, import_react.useEffect)(() => {
    if (endDate) {
      setMonth(endDate.getUTCMonth());
      setYear(endDate.getUTCFullYear());
    } else if (startDate) {
      setMonth(startDate.getUTCMonth());
      setYear(startDate.getUTCFullYear());
    }
  }, [startDate, endDate]);
  const getDayOfWeek = (day) => {
    return new Date(Date.UTC(year, month, day)).getUTCDay();
  };
  const getDaysInMonth = () => {
    return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
  };
  const getDaysInMonthBefore = () => {
    return new Date(Date.UTC(year, month, 0)).getUTCDate();
  };
  const toUTCTimeByDay = (day) => {
    return Date.UTC(year, month, day);
  };
  const isEqual = (day) => {
    const utcDate = new Date(toUTCTimeByDay(day));
    return startDate && isSameDate(startDate, utcDate) || endDate && isSameDate(endDate, utcDate);
  };
  const inRange = (day) => {
    return startDate && toUTCTime(startDate) <= toUTCTimeByDay(day) && endDate && endDate.getTime() >= toUTCTimeByDay(day);
  };
  const isDisabled = (day) => {
    const local = Date.UTC(year, month, day);
    const now = /* @__PURE__ */ new Date();
    const nowUTC = Date.UTC(now.getFullYear(), now.getMonth(), now.getDate());
    const pastDatesDisabled = disablePastDates && local < nowUTC || disablePastFrom && local < toUTCTime(disablePastFrom);
    const futureDateDisabled = disableFutureDates && local > nowUTC || disableFutureFrom && local > toUTCTime(disableFutureFrom);
    return pastDatesDisabled || futureDateDisabled;
  };
  const onClick = (day) => {
    const selectedDate = new Date(Date.UTC(year, month, day));
    if (isDisabled(day))
      return;
    if (type === "single") {
      onSelectSingle(selectedDate);
    } else if (type === "range") {
      onSelectRange(selectedDate);
    }
  };
  const getFirstWeek = () => {
    const day = getDayOfWeek(1);
    let week = import_lodash.default.range(1, 7 - day + 1);
    const lastDayBefore = getDaysInMonthBefore();
    const daysBefore = [];
    for (let i = lastDayBefore - (day - 1); i <= lastDayBefore; i += 1) {
      daysBefore.push(i);
    }
    week = import_lodash.default.concat(daysBefore, week);
    return week.map((val) => {
      return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
        DayField,
        {
          disabled: val > 7 || isDisabled(val),
          selected: isEqual(val),
          onClick: () => val <= 7 && onClick(val),
          inRange: type === "range" && val <= 7 && inRange(val),
          aux: { val, startDate, endDate, year, month },
          children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.Text.Body2, { bold: isEqual(val), children: val })
        },
        val
      );
    });
  };
  const getMiddleWeeks = () => {
    const day = getDayOfWeek(1);
    let firstDay = 7 - day + 1;
    const weeks = [];
    while (firstDay + 7 <= getDaysInMonth()) {
      weeks.push(import_lodash.default.range(firstDay, firstDay + 7));
      firstDay += 7;
    }
    return weeks.map((week, i) => {
      const days = week.map((val) => {
        return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
          DayField,
          {
            selected: isEqual(val),
            onClick: () => onClick(val),
            inRange: type === "range" && inRange(val),
            disabled: isDisabled(val),
            aux: { val, startDate, endDate, year, month },
            children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.Text.Body2, { bold: isEqual(val), children: val })
          },
          val
        );
      });
      return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Row, { children: days }, i);
    });
  };
  const getLastWeek = () => {
    const lastDay = getDaysInMonth();
    const day = getDayOfWeek(lastDay);
    let week = import_lodash.default.range(lastDay - day, lastDay + 1);
    week = import_lodash.default.concat(week, import_lodash.default.range(1, 7 - day));
    return week.map((val) => {
      return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
        DayField,
        {
          disabled: val < 7 || isDisabled(val),
          selected: isEqual(val),
          onClick: () => val > 7 && onClick(val),
          inRange: type === "range" && val > 7 && inRange(val),
          aux: { val, startDate, endDate, year, month },
          children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.Text.Body2, { bold: isEqual(val), children: val })
        },
        val
      );
    });
  };
  const getDays = () => {
    return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
      /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Row, { children: getFirstWeek() }),
      getMiddleWeeks(),
      /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Row, { children: getLastWeek() })
    ] });
  };
  const getLocale = () => {
    return Intl.DateTimeFormat.supportedLocalesOf(locale).length > 0 ? locale : "en-US";
  };
  const weekDays = Array.from(
    { length: 7 },
    (__, i) => new Intl.DateTimeFormat(getLocale(), {
      weekday: "short",
      timeZone: "UTC"
    }).format(new Date(Date.UTC(2024, 0, 7 + i)))
  );
  const prior = () => {
    let local = month - 1;
    if (local < 0) {
      local = 11;
      setYear(year - 1);
    }
    setMonth(local);
  };
  const next = () => {
    let local = month + 1;
    if (local > 11) {
      local = 0;
      setYear(year + 1);
    }
    setMonth(local);
  };
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CalendarWrapper, { children: [
    /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
      import__.Box,
      {
        display: "flex",
        justifyContent: "space-between",
        m: "xxsmall",
        mb: "zero",
        pb: "small",
        children: [
          /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
            import__.Icon,
            {
              style: { cursor: "pointer" },
              as: import_yoga_icons.ChevronLeft,
              width: "large",
              height: "large",
              onClick: prior,
              fill: "primary",
              "data-testid": "previous-month-arrow"
            }
          ),
          /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Month, { bold: true, children: new Intl.DateTimeFormat(getLocale(), {
            month: "long",
            year: "numeric"
          }).format(new Date(year, month, 1, 0, 0, 0)) }),
          /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
            import__.Icon,
            {
              style: { cursor: "pointer" },
              as: import_yoga_icons.ChevronRight,
              width: "large",
              height: "large",
              onClick: next,
              fill: "primary",
              "data-testid": "next-month-arrow"
            }
          )
        ]
      }
    ),
    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DaysWrapper, { children: weekDays.map((weekDay) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Day, { children: weekDay.toLocaleUpperCase().charAt(0) }, `${weekDay}`)) }),
    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.Box, { children: getDays() })
  ] });
}
Calendar.propTypes = {
  type: (0, import_prop_types.oneOf)(["single", "range"]).isRequired,
  startDate: (0, import_prop_types.instanceOf)(Date),
  endDate: (0, import_prop_types.instanceOf)(Date),
  onSelectSingle: import_prop_types.func,
  onSelectRange: import_prop_types.func,
  disablePastDates: import_prop_types.bool,
  disableFutureDates: import_prop_types.bool,
  disablePastFrom: (0, import_prop_types.instanceOf)(Date),
  disableFutureFrom: (0, import_prop_types.instanceOf)(Date),
  locale: import_prop_types.string
};
var Calendar_default = Calendar;
