import { __assign } from 'tslib';
import { compareDates, addWeeks, addDays, findAvailableDate } from '@fluentui/date-time-utilities';
import { KeyCodes, getRTLSafeKeyCode, css } from '@uifabric-vue/utilities';
import Vue from 'vue';
import { withCalendarProps } from '../Calendar/useCalendar.js';
import { withCalendarGridRowProps } from './useCalendarDayGrid.js';

var CalendarGridDayCell = Vue.extend({
  name: "CalendarGridDayCell",
  props: __assign(__assign(__assign({}, withCalendarProps()), withCalendarGridRowProps()), { day: { type: Object, required: true }, dayIndex: { type: Number, required: true } }),
  data: function() {
    return {
      isHovering: false,
      isPressing: false
    };
  },
  computed: {
    cornerStyle: function() {
      var _a, _b;
      return (_b = (_a = this.weekCorners) === null || _a === void 0 ? void 0 : _a[this.weekIndex + "_" + this.dayIndex]) !== null && _b !== void 0 ? _b : "";
    },
    isNavigatedDate: function() {
      var _a = this, navigatedDate = _a.navigatedDate, day = _a.day;
      return compareDates(navigatedDate, day.originalDate);
    },
    ariaLabel: function() {
      var _a = this, day = _a.day, strings = _a.strings;
      return [
        day.originalDate.getDate(),
        strings.months[day.originalDate.getMonth()],
        day.originalDate.getFullYear(),
        day.isMarked && strings.dayMarkedAriaLabel
      ].filter(function(e) {
        return e;
      }).join(", ");
    }
  },
  methods: {
    navigateMonthEdge: function(ev, date) {
      var _a = this, restrictedDates = _a.restrictedDates, minDate = _a.minDate, maxDate = _a.maxDate, weeks = _a.weeks;
      var targetDate;
      var direction = 1;
      if (ev.which === KeyCodes.up) {
        targetDate = addWeeks(date, -1);
        direction = -1;
      } else if (ev.which === KeyCodes.down) {
        targetDate = addWeeks(date, 1);
      } else if (ev.which === getRTLSafeKeyCode(KeyCodes.left)) {
        targetDate = addDays(date, -1);
        direction = -1;
      } else if (ev.which === getRTLSafeKeyCode(KeyCodes.right)) {
        targetDate = addDays(date, 1);
      }
      if (!targetDate) {
        return;
      }
      var findAvailableDateOptions = {
        initialDate: date,
        targetDate: targetDate,
        direction: direction,
        restrictedDates: restrictedDates,
        minDate: minDate,
        maxDate: maxDate
      };
      var nextDate = findAvailableDate(findAvailableDateOptions);
      if (!nextDate) {
        findAvailableDateOptions.direction = -direction;
        nextDate = findAvailableDate(findAvailableDateOptions);
      }
      var isInCurrentView = weeks && nextDate && weeks.slice(1, weeks.length - 1).some(function(week) {
        return week.some(function(dayToCompare) {
          return compareDates(dayToCompare.originalDate, nextDate);
        });
      });
      if (isInCurrentView) {
        return;
      }
      if (nextDate) {
        this.$emit("onNavigateDate", nextDate, true);
        ev.preventDefault();
      }
    },
    onMouseOverDay: function(ev) {
      this.isHovering = true;
    },
    onMouseOutDay: function(ev) {
      this.isHovering = false;
      this.isPressing = false;
    },
    onMouseDownDay: function(ev) {
      this.isPressing = true;
    },
    onMouseUpDay: function(ev) {
      this.isPressing = false;
    },
    onDayKeyDown: function(ev, day) {
      if (ev.which === KeyCodes.enter) {
        this.$emit("onSelectDate", day.originalDate);
      } else {
        this.navigateMonthEdge(ev, day.originalDate);
      }
    }
  },
  render: function(h) {
    var _this = this;
    var _a = this, allFocusable = _a.allFocusable, ariaHidden = _a.ariaHidden, ariaLabel = _a.ariaLabel, classNames = _a.classNames, day = _a.day, dateTimeFormatter = _a.dateTimeFormatter, weekCorners = _a.weekCorners, activeDescendantId = _a.activeDescendantId, cornerStyle = _a.cornerStyle, isNavigatedDate = _a.isNavigatedDate;
    return h("td", {
      class: css(classNames.dayCell, weekCorners && cornerStyle, day.isSelected && classNames.daySelected, day.isSelected && "ms-CalendarDay-daySelected", !day.isInBounds && classNames.dayOutsideBounds, !day.isInMonth && classNames.dayOutsideNavigatedMonth, this.isHovering && "ms-CalendarDay-hoverStyle", this.isPressing && "ms-CalendarDay-pressedStyle"),
      attrs: {
        role: "gridcell",
        tabIndex: isNavigatedDate ? 0 : void 0,
        "aria-hidden": ariaHidden,
        "aria-disabled": !ariaHidden && !day.isInBounds,
        "aria-readonly": true,
        "aria-current": day.isSelected ? "date" : void 0,
        "aria-selected": day.isInBounds ? day.isSelected : void 0,
        "data-is-focusable": !ariaHidden && (allFocusable || (day.isInBounds ? true : void 0))
      },
      on: __assign(__assign({}, day.isInBounds && !ariaHidden && { click: day.onSelected }), !ariaHidden && {
        mouseover: this.onMouseOverDay,
        mouseout: this.onMouseOutDay,
        mousedown: this.onMouseDownDay,
        mouseup: this.onMouseUpDay,
        keydown: function(e) {
          return _this.onDayKeyDown(e, day);
        }
      })
    }, [
      h("button", {
        key: day.key + "button",
        class: css(classNames.dayButton, day.isToday && classNames.dayIsToday, day.isToday && "ms-CalendarDay-dayIsToday"),
        attrs: {
          "aria-hidden": ariaHidden,
          "aria-label": ariaLabel,
          id: isNavigatedDate ? activeDescendantId : void 0,
          disabled: !ariaHidden && !day.isInBounds,
          type: "button",
          tabIndex: -1,
          "data-is-focusable": false
        }
      }, [
        h("span", { attrs: { "aria-hidden": "true" } }, dateTimeFormatter.formatDay(day.originalDate)),
        day.isMarked && h("div", { attrs: { "aria-hidden": "true" }, class: classNames.dayMarker })
      ])
    ]);
  }
});

export { CalendarGridDayCell };
