<template>
  <div>
    <div v-if="$slots.beforeCalendarHeaderYear">
      <slot name="beforeCalendarHeaderYear" />
    </div>

    <PickerHeader
      v-if="showHeader"
      ref="pickerHeader"
      :is-next-disabled="isNextDisabled"
      :is-previous-disabled="isPreviousDisabled"
      @focus-input="focusInput"
      @page-change="changePage($event)"
      @set-focus="$emit('set-focus', $event)"
    >
      <template #prevIntervalBtn>
        <slot name="prevIntervalBtn" />
      </template>
      <UpButton ref="up" :is-disabled="true">
        {{ pageTitleYear }}
      </UpButton>
      <template #nextIntervalBtn>
        <slot name="nextIntervalBtn" />
      </template>
    </PickerHeader>

    <div class="cells-wrapper">
      <Transition :name="transitionName">
        <PickerCells
          ref="cells"
          :key="pageTitleYear"
          v-slot="{ cell }"
          :cells="cells"
          :tabbable-cell-id="tabbableCellId"
          view="year"
          @arrow="handleArrow($event)"
          @select="select($event)"
        >
          {{ cell.year }}
        </PickerCells>
      </Transition>
    </div>

    <div v-if="$slots.calendarFooterYear">
      <slot name="calendarFooterYear" />
    </div>
  </div>
</template>

<script>
import pickerMixin from "../mixins/pickerMixin.vue";
import DisabledDate from "../utils/DisabledDate.js";
import PickerCells from "./PickerCells.vue";
import UpButton from "./UpButton.vue";
export default {
  name: "PickerYear",
  components: { PickerCells, UpButton },
  mixins: [pickerMixin],
  props: {
    yearRange: {
      type: Number,
      default: 12,
    },
  },
  computed: {
    /**
     * Sets an array with all years to show this decade (or yearRange)
     * @return {Array}
     */
    // eslint-disable-next-line complexity,max-statements
    cells() {
      const d = this.pageDate;
      const years = [];
      const year = this.useUtc
        ? Math.floor(d.getUTCFullYear() / this.yearRange) * this.yearRange
        : Math.floor(d.getFullYear() / this.yearRange) * this.yearRange;
      // set up a new date object to the beginning of the current 'page'
      const dObj = this.useUtc
        ? new Date(Date.UTC(year, d.getUTCMonth(), d.getUTCDate()))
        : new Date(
            year,
            d.getMonth(),
            d.getDate(),
            d.getHours(),
            d.getMinutes()
          );
      const todayYear = this.utils.getFullYear(this.utils.getNewDateObject());
      for (let i = 0; i < this.yearRange; i += 1) {
        years.push({
          year: this.utils.getFullYear(dObj),
          timestamp: dObj.valueOf(),
          isDisabled: this.isDisabledYear(dObj),
          isOpenDate: this.isOpenYear(dObj),
          isSelected: this.isSelectedYear(dObj),
          isToday: dObj.getFullYear() === todayYear,
        });
        this.utils.setFullYear(dObj, this.utils.getFullYear(dObj) + 1);
      }
      // Fill any remaining cells with blanks to position trailing cells correctly when rtl
      const cellsInGrid = Math.ceil(this.yearRange / 3) * 3;
      for (let i = years.length; i < cellsInGrid; i += 1) {
        years.push({
          id: i,
          isDisabled: true,
        });
      }
      return years;
    },
    /**
     * Is the next decade disabled?
     * @return {Boolean}
     */
    isNextDisabled() {
      if (!this.disabledConfig.has.from) {
        return false;
      }
      return this.disabledConfig.from.year <= this.pageDecadeEnd;
    },
    /**
     * Is the previous decade disabled?
     * @return {Boolean}
     */
    isPreviousDisabled() {
      if (!this.disabledConfig.has.to) {
        return false;
      }
      return this.disabledConfig.to.year >= this.pageDecadeStart;
    },
    /**
     * The year at which the current yearRange starts
     * @return {Number}
     */
    pageDecadeStart() {
      return Math.floor(this.pageYear / this.yearRange) * this.yearRange;
    },
    /**
     * The year at which the current yearRange ends
     * @return {Number}
     */
    pageDecadeEnd() {
      return this.pageDecadeStart + this.yearRange - 1;
    },
    /**
     * Display the current page's decade (or year range) as the title.
     * @return {String}
     */
    pageTitleYear() {
      const { yearSuffix } = this.translation;
      return `${this.pageDecadeStart} - ${this.pageDecadeEnd}${yearSuffix}`;
    },
  },
  methods: {
    /**
     * Whether a year is disabled
     * @param {Date} date
     * @return {Boolean}
     */
    isDisabledYear(date) {
      return new DisabledDate(this.utils, this.disabledDates).isYearDisabled(
        date
      );
    },
    /**
     * Should the calendar open on this year?
     * @return {Boolean}
     */
    isOpenYear(date) {
      if (!this.openDate) {
        return false;
      }
      const openDateYear = this.utils.getFullYear(this.openDate);
      const thisDateYear = this.utils.getFullYear(date);
      return openDateYear === thisDateYear;
    },
    /**
     * Whether the selected date is in this year
     * @param {Date} date
     * @return {Boolean}
     */
    isSelectedYear(date) {
      const year = this.utils.getFullYear(date);
      return (
        this.selectedDate && year === this.utils.getFullYear(this.selectedDate)
      );
    },
  },
};
</script>
