import { DateTimeFormatter, getStartDayOfTheWeek } from '@procore/globalization-toolkit';
import { addDays as addDaysFn, addMonths as addMonthsFn, eachDayOfInterval as eachDayFn, format as formatFn, getDate as getDateFn, getDay as getDayFn, getMonth as getMonthFn, getYear as getYearFn, isAfter as isAfterFn, isBefore as isBeforeFn, isSameDay as isSameDayFn, isSameMonth as isSameMonthFn, isToday as isTodayFn, isWithinInterval as isWithinRangeFn, startOfMonth as startOfMonthFn, startOfWeek, subDays as subDaysFn, subMonths as subMonthsFn, subYears as subYearsFn } from 'date-fns';
import { de, enUS as en, es, fr, is, it, ja, nb, pl, pt, ptBR, th, zhCN, zhTW } from 'date-fns/esm/locale';
import { range, splitEvery } from 'ramda';
var dateFnsLocales = {
  en: en,
  'en-CA': en,
  'fr-CA': fr,
  'fr-FR': fr,
  es: es,
  'es-ES': es,
  'en-AE': en,
  'en-AU': en,
  'en-GB': en,
  'en-SG': en,
  'th-TH': th,
  'pt-BR': ptBR,
  'ja-JP': ja,
  'is-IS': is,
  'de-DE': de,
  'zh-SG': zhCN,
  pseudo: en,
  'pl-PL': pl,
  'nb-NO': nb,
  'zh-TW': zhTW,
  'it-IT': it,
  'pt-PT': pt
};
export var maxMonth = 12;
export var minYear = 1000;

// need to be function to make mocking of new Date works in tests.
export var getMaxYear = function getMaxYear() {
  return new Date().getFullYear() + 100;
};

// rows in calendar
var calendarWeeks = 6;
var daysInWeek = 7;
export var daysInCalendar = calendarWeeks * daysInWeek;
export var addDays = addDaysFn;
export var addMonths = addMonthsFn;
export var eachDay = function eachDay(date1, date2) {
  return eachDayFn({
    start: date1,
    end: date2
  });
};
export var format = formatFn;

// An entire date object has to be formed, format(month, 'MMM') breaks for month >= 10 (it just outputs 'Dec')
export var formatMonth = function formatMonth(month) {
  return formatFn(normalizeNewDate(2019, month, 2), 'MMM');
};
export var getDate = getDateFn;
export var getDates = function getDates(date, locale) {
  var startDayOfWeek = getStartDayOfTheWeek(locale);

  // Shift first day appearing on the calendar based on day of the week of the first day of the month and based on the start day of the week
  var dayShift = 7 - startDayOfWeek;
  var subDays = (getDayFn(startOfMonthFn(date)) + dayShift) % 7;
  var start = subDaysFn(startOfMonthFn(date), subDays);
  var end = addDaysFn(start, daysInCalendar - 1);
  return eachDayFn({
    start: start,
    end: end
  });
};
export var getMonth = getMonthFn;
export var getRows = splitEvery(7);
export var getYear = getYearFn;
export var isAfter = function isAfter(date1, date2) {
  return isAfterFn(normalizeExistingDate(date1), normalizeExistingDate(date2));
};
export var isBefore = function isBefore(date1, date2) {
  return isBeforeFn(normalizeExistingDate(date1), normalizeExistingDate(date2));
};
export var isSameDay = function isSameDay(date1, date2) {
  return isSameDayFn(normalizeExistingDate(date1), normalizeExistingDate(date2));
};
export var isSameMonth = isSameMonthFn;
export var isToday = isTodayFn;
export var isWithinRange = function isWithinRange(date, start, end) {
  if (!start || !end || start > end) {
    return false;
  }
  return isWithinRangeFn(normalizeExistingDate(date), {
    start: normalizeExistingDate(start),
    end: normalizeExistingDate(end)
  });
};
export var normalizeExistingDate = function normalizeExistingDate(day) {
  return normalizeNewDate(getYearFn(day), getMonthFn(day), getDateFn(day));
};
export var normalizeNewDate = function normalizeNewDate(year, month, day) {
  var hour = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
  var minute = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
  var second = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
  var millisecond = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 0;
  var normalizedDate = new Date();
  normalizedDate.setFullYear(year, month, day);
  normalizedDate.setHours(hour);
  normalizedDate.setMinutes(minute);
  normalizedDate.setSeconds(second);
  normalizedDate.setMilliseconds(millisecond);
  return normalizedDate;
};
export var getMonthLabel = function getMonthLabel(month) {
  var locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'en';
  var date = normalizeNewDate(1970, month, 1);
  var options = {
    locale: locale || 'en',
    year: 'numeric',
    month: 'short',
    day: 'numeric'
  };
  var formatter = new DateTimeFormatter(options);
  var monthPart = formatter.formatDateTimeToParts(date).find(function (part) {
    return part.type === 'month';
  }).value;
  return monthPart;
};
export var getMonthOptions = function getMonthOptions(locale) {
  return range(0, 12).map(function (value) {
    return {
      value: value,
      label: getMonthLabel(value, locale)
    };
  });
};
export var getYearOptions = function getYearOptions(date) {
  var start = Math.max(minYear, getYear(subYearsFn(date, 10)));
  return range(start, start + 21).map(function (value) {
    return {
      value: value,
      label: String(value).padStart(4, '0')
    };
  });
};
export var getDayOfWeekLabel = function getDayOfWeekLabel(day) {
  var locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'en';
  return formatFn(addDaysFn(startOfWeek(new Date()), day), 'iiiiii', {
    locale: dateFnsLocales[locale]
  });
};
export var updateMonth = function updateMonth(date, month) {
  return normalizeNewDate(getYear(date), month, getDate(date));
};
export var updateYear = function updateYear(date, year) {
  return normalizeNewDate(year, getMonth(date), getDate(date));
};
export var subDays = subDaysFn;
export var subMonths = subMonthsFn;
var CalendarHelpers = {
  addDays: addDays,
  addMonths: addMonths,
  eachDay: eachDay,
  format: format,
  formatMonth: formatMonth,
  getDate: getDate,
  getDates: getDates,
  getMonth: getMonth,
  getMonthLabel: getMonthLabel,
  getMonthOptions: getMonthOptions,
  getRows: getRows,
  getYear: getYear,
  getYearOptions: getYearOptions,
  isAfter: isAfter,
  isBefore: isBefore,
  isSameDay: isSameDay,
  isSameMonth: isSameMonth,
  isToday: isToday,
  isWithinRange: isWithinRange,
  normalizeExistingDate: normalizeExistingDate,
  normalizeNewDate: normalizeNewDate,
  subDays: subDays,
  subMonths: subMonths,
  updateMonth: updateMonth,
  updateYear: updateYear
};
export default CalendarHelpers;
//# sourceMappingURL=CalendarHelpers.js.map