import { __assign, __spreadArray } from 'tslib';
import { withThemeableProps } from '../../useThemeable.js';
import { getDateRangeArray, getBoundedDateRange, isRestrictedDate, getDayGrid, DAYS_IN_WEEK, DateRangeType, compareDates } from '@fluentui/date-time-utilities';
import { classNamesFunction, getRTL } from '@uifabric-vue/utilities';
import Vue from 'vue';
import { CalendarGridRow } from './CalendarGridRow.js';
import { CalendarMonthHeaderRow } from './CalendarMonthHeaderRow.js';
import { withCalendarDayGridProps } from './useCalendarDayGrid.js';

var getClassNames = classNamesFunction();
function useWeeks(props, onSelectDate) {
  var _a;
  var weeksGrid = getDayGrid(props);
  var firstVisibleDay = weeksGrid[1][0].originalDate;
  var lastVisibleDay = weeksGrid[weeksGrid.length - 1][6].originalDate;
  var markedDays = ((_a = props.getMarkedDays) === null || _a === void 0 ? void 0 : _a.call(props, firstVisibleDay, lastVisibleDay)) || [];
  var returnValue = [];
  for (var weekIndex = 0; weekIndex < weeksGrid.length; weekIndex++) {
    var week = [];
    var _loop_1 = function(dayIndex2) {
      var day = weeksGrid[weekIndex][dayIndex2];
      var dayInfo = __assign(__assign({ onSelected: function() {
        return onSelectDate(day.originalDate);
      } }, day), { isMarked: day.isMarked || (markedDays === null || markedDays === void 0 ? void 0 : markedDays.some(function(markedDay) {
        return compareDates(day.originalDate, markedDay);
      })) });
      week.push(dayInfo);
    };
    for (var dayIndex = 0; dayIndex < DAYS_IN_WEEK; dayIndex++) {
      _loop_1(dayIndex);
    }
    returnValue.push(week);
  }
  return returnValue;
}
function useWeekCornerStyles(props) {
  var getWeekCornerStyles = function(classNames, initialWeeks) {
    var weekCornersStyled = {};
    var weeks = initialWeeks.slice(1, initialWeeks.length - 1);
    weeks.forEach(function(week, weekIndex) {
      week.forEach(function(day, dayIndex) {
        var above = weeks[weekIndex - 1] && weeks[weekIndex - 1][dayIndex] && isInSameHoverRange(weeks[weekIndex - 1][dayIndex].originalDate, day.originalDate, weeks[weekIndex - 1][dayIndex].isSelected, day.isSelected);
        var below = weeks[weekIndex + 1] && weeks[weekIndex + 1][dayIndex] && isInSameHoverRange(weeks[weekIndex + 1][dayIndex].originalDate, day.originalDate, weeks[weekIndex + 1][dayIndex].isSelected, day.isSelected);
        var left = weeks[weekIndex][dayIndex - 1] && isInSameHoverRange(weeks[weekIndex][dayIndex - 1].originalDate, day.originalDate, weeks[weekIndex][dayIndex - 1].isSelected, day.isSelected);
        var right = weeks[weekIndex][dayIndex + 1] && isInSameHoverRange(weeks[weekIndex][dayIndex + 1].originalDate, day.originalDate, weeks[weekIndex][dayIndex + 1].isSelected, day.isSelected);
        var style = [];
        style.push(calculateRoundedStyles(classNames, above, below, left, right));
        style.push(calculateBorderStyles(classNames, above, below, left, right));
        weekCornersStyled[weekIndex + "_" + dayIndex] = style.join(" ");
      });
    });
    return weekCornersStyled;
  };
  var calculateRoundedStyles = function(classNames, above, below, left, right) {
    var style = [];
    var roundedTopLeft = !above && !left;
    var roundedTopRight = !above && !right;
    var roundedBottomLeft = !below && !left;
    var roundedBottomRight = !below && !right;
    if (roundedTopLeft) {
      style.push(getRTL() ? classNames.topRightCornerDate : classNames.topLeftCornerDate);
    }
    if (roundedTopRight) {
      style.push(getRTL() ? classNames.topLeftCornerDate : classNames.topRightCornerDate);
    }
    if (roundedBottomLeft) {
      style.push(getRTL() ? classNames.bottomRightCornerDate : classNames.bottomLeftCornerDate);
    }
    if (roundedBottomRight) {
      style.push(getRTL() ? classNames.bottomLeftCornerDate : classNames.bottomRightCornerDate);
    }
    return style.join(" ");
  };
  var calculateBorderStyles = function(classNames, above, below, left, right) {
    var style = [];
    if (!above) {
      style.push(classNames.datesAbove);
    }
    if (!below) {
      style.push(classNames.datesBelow);
    }
    if (!left) {
      style.push(getRTL() ? classNames.datesRight : classNames.datesLeft);
    }
    if (!right) {
      style.push(getRTL() ? classNames.datesLeft : classNames.datesRight);
    }
    return style.join(" ");
  };
  var isInSameHoverRange = function(date1, date2, date1Selected, date2Selected) {
    var dateRangeType = props.dateRangeType, firstDayOfWeek = props.firstDayOfWeek, workWeekDays = props.workWeekDays;
    var dateRangeHoverType = dateRangeType === DateRangeType.WorkWeek ? DateRangeType.Week : dateRangeType;
    var dateRange = getDateRangeArray(date1, dateRangeHoverType, firstDayOfWeek, workWeekDays);
    if (date1Selected !== date2Selected) {
      return false;
    } else if (date1Selected && date2Selected) {
      return true;
    }
    return dateRange.filter(function(date) {
      return date.getTime() === date2.getTime();
    }).length > 0;
  };
  return [getWeekCornerStyles, calculateRoundedStyles];
}
var CalendarDayGridBase = Vue.extend({
  name: "CalendarDayGridBase",
  props: __assign(__assign(__assign({}, withThemeableProps()), withCalendarDayGridProps()), { showWeekNumbers: { type: Boolean, default: false }, lightenDaysOutsideNavigatedMonth: { type: Boolean, default: true }, animationDirection: { type: Number, default: void 0 }, minDate: { type: Date, default: void 0 }, maxDate: { type: Date, default: void 0 }, weeksToShow: { type: Number, default: void 0 } }),
  data: function() {
    return {
      animateBackwards: false
    };
  },
  computed: {
    classNames: function() {
      return getClassNames(this.styles, {
        theme: this.theme,
        className: this.className,
        dateRangeType: this.dateRangeType,
        showWeekNumbers: this.showWeekNumbers,
        lightenDaysOutsideNavigatedMonth: this.lightenDaysOutsideNavigatedMonth === void 0 ? true : this.lightenDaysOutsideNavigatedMonth,
        animationDirection: this.animationDirection,
        animateBackwards: this.animateBackwards
      });
    },
    weeks: function() {
      return useWeeks(this.$props, this.onSelectDate);
    },
    weekCornerStyles: function() {
      return useWeekCornerStyles(this.$props);
    },
    weekCorners: function() {
      var getWeekCornerStyles = this.weekCornerStyles[0];
      return getWeekCornerStyles(this.classNames, this.weeks);
    },
    partialWeekProps: function() {
      return {
        weeks: this.weeks,
        classNames: this.classNames,
        weekCorners: this.weekCorners
      };
    }
  },
  methods: {
    onSelectDate: function(selectedDate) {
      var _a = this.$props, dateRangeType = _a.dateRangeType, firstDayOfWeek = _a.firstDayOfWeek, minDate = _a.minDate, maxDate = _a.maxDate, workWeekDays = _a.workWeekDays, daysToSelectInDayView = _a.daysToSelectInDayView, restrictedDates = _a.restrictedDates;
      var restrictedDatesOptions = { minDate: minDate, maxDate: maxDate, restrictedDates: restrictedDates };
      var dateRange = getDateRangeArray(selectedDate, dateRangeType, firstDayOfWeek, workWeekDays, daysToSelectInDayView);
      dateRange = getBoundedDateRange(dateRange, minDate, maxDate);
      dateRange = dateRange.filter(function(d) {
        return !isRestrictedDate(d, restrictedDatesOptions);
      });
      this.$emit("onSelectDate", selectedDate, dateRange);
      this.$emit("onNavigateDate", selectedDate, true);
    }
  },
  render: function(h) {
    var _this = this;
    var _a = this, classNames = _a.classNames, weeks = _a.weeks, partialWeekProps = _a.partialWeekProps;
    return h("div", { class: classNames.wrapper }, [
      h("table", { class: classNames.table }, [
        h("tbody", __spreadArray(__spreadArray([
          h(CalendarMonthHeaderRow, {
            props: __assign(__assign({}, this.$props), { classNames: classNames, weeks: weeks })
          }),
          h(CalendarGridRow, {
            props: __assign(__assign(__assign({}, this.$props), partialWeekProps), { week: weeks[0], weekIndex: -1, rowClassName: classNames.firstTransitionWeek })
          })
        ], weeks.slice(1, weeks.length - 1).map(function(week, weekIndex) {
          return h(CalendarGridRow, {
            props: __assign(__assign(__assign({}, _this.$props), partialWeekProps), { week: week, weekIndex: weekIndex, rowClassName: classNames.weekRow })
          });
        }), true), [
          h(CalendarGridRow, {
            props: __assign(__assign(__assign({}, this.$props), partialWeekProps), { week: weeks[weeks.length - 1], weekIndex: -2, rowClassName: classNames.lastTransitionWeek })
          })
        ], false))
      ])
    ]);
  }
});

export { CalendarDayGridBase };
