var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { MapToComponentField, MapToComponentMethod } from 'vega-slimmer/core';
import { MonthPeriod } from '../../../../../helpers/calendar';
import { isCalendarDateType } from '../../../../../types/type-guard';
import { MonthNames } from '../../constants';
import { VegaDatePickerCalendarStateBaseAbstract } from './vega-date-picker-calendar-state-base.abstract';
import { VegaInternalDatePickerCalendarUpdatePeriodByUser } from '../../../../../helpers/event-manager/event-id/vega-internal-event-id';
import { DomNodeSubjectObserverFactory } from '../../../../../helpers/change-manager/subject/dom-node-subject/dom-node-subject-observer-factory';
/** Current period controller. */
export class VegaDatePickerCalendarCurrentPeriodController extends VegaDatePickerCalendarStateBaseAbstract {
  /** connectedCallback */
  connectedCallback() {
    super.connectedCallback();
    this.initCalendarPeriodUpdateObserver();
  }
  /** disconnectedCallback */
  disconnectedCallback() {
    super.disconnectedCallback();
    this.removeCalendarPeriodUpdateObserver();
  }
  /** componentWillLoad */
  componentWillLoad() {
    this.setCurrentMonthPeriod();
  }
  /** Listen maxDate changed */
  watchMaxCalendarDate() {
    this.setCurrentMonthPeriod();
  }
  /** Listen minDate changed */
  watchMinCalendarDate() {
    this.setCurrentMonthPeriod();
  }
  /** Listen currentPeriod changed */
  watchCurrentPeriod() {
    this.monthYearChangeEventEmitter.emit(this.getCurrentYearMonthByPeriod());
  }
  /** reset current period */
  resetCurrentPeriod() {
    this.setCurrentMonthPeriod();
  }
  /** Clear current period */
  clear() {
    this.setCurrentMonthPeriod();
  }
  /**
   * Goto next month period while single mode.
   * Goto next two month period while range mode.
   */
  gotoNextPeriod() {
    const period = this.isDualMonths
      ? this.currentPeriod.next().next()
      : this.currentPeriod.next();
    this.updateCalendarPeriod(period);
  }
  /**
   * Goto previous month period while single mode.
   * Goto previous two month period while range mode.
   */
  gotoPreviousPeriod() {
    const period = this.isDualMonths
      ? this.currentPeriod.previous().previous()
      : this.currentPeriod.previous();
    this.updateCalendarPeriod(period);
  }
  /**
   * set current period
   *
   * @param {MonthPeriod} period current period
   */
  updateCalendarPeriod(period) {
    if (!this.currentPeriod || !this.currentPeriod.equal(period)) {
      this.currentPeriod = period;
    }
  }
  /**
   * Current period follow below rules:
   * - Go to the value date month if the value is set.
   * - Go to the minDate month if only set the minDate and today is before than minDate.
   * - Go to the minDate month if minDate and maxDate are both set and today is after than maxDate.
   * - Go to the maxDate month if only set maxDate and today is after than maxDate.
   * - Go to today month if the value, minDate and maxDate all are empty.
   */
  setCurrentMonthPeriod() {
    let currentDate;
    const startDate = this.calendarSelection.startDate;
    if (isCalendarDateType(startDate)) {
      currentDate = startDate;
    }
    else if (this.minCalendarDate &&
      (this.today.isBefore(this.minCalendarDate) ||
        (this.maxCalendarDate && this.today.isAfter(this.maxCalendarDate)))) {
      currentDate = this.minCalendarDate;
    }
    else if (this.maxCalendarDate && this.today.isAfter(this.maxCalendarDate)) {
      currentDate = this.maxCalendarDate;
    }
    else {
      currentDate = this.today;
    }
    this.updateCalendarPeriod(new MonthPeriod(currentDate, true, this.timezone));
  }
  /**
   * Get current year month by period
   *
   * @returns {DatePickerMonthYearTypes} - month and year info
   */
  getCurrentYearMonthByPeriod() {
    const startMonthYear = {
      month: MonthNames[this.currentPeriod.current.month - 1],
      year: `${this.currentPeriod.current.year}`,
    };
    if (this.mode === 'range') {
      return [
        startMonthYear,
        {
          month: MonthNames[this.currentPeriod.endDate.month - 1],
          year: `${this.currentPeriod.endDate.year}`,
        },
      ];
    }
    else {
      return startMonthYear;
    }
  }
  /**
   * Initialize calendar clear observer
   */
  initCalendarPeriodUpdateObserver() {
    DomNodeSubjectObserverFactory.addUniqueObserverToNode(this.host, VegaInternalDatePickerCalendarUpdatePeriodByUser, this.setCurrentMonthPeriod.bind(this));
  }
  /**
   * Remove calendar clear observer
   */
  removeCalendarPeriodUpdateObserver() {
    DomNodeSubjectObserverFactory.removeUniqueObserverFromNode(this.host, VegaInternalDatePickerCalendarUpdatePeriodByUser);
  }
}
__decorate([
  MapToComponentField({ writable: true })
], VegaDatePickerCalendarCurrentPeriodController.prototype, "currentPeriod", void 0);
__decorate([
  MapToComponentField()
], VegaDatePickerCalendarCurrentPeriodController.prototype, "host", void 0);
__decorate([
  MapToComponentField()
], VegaDatePickerCalendarCurrentPeriodController.prototype, "today", void 0);
__decorate([
  MapToComponentField()
], VegaDatePickerCalendarCurrentPeriodController.prototype, "mode", void 0);
__decorate([
  MapToComponentField()
], VegaDatePickerCalendarCurrentPeriodController.prototype, "format", void 0);
__decorate([
  MapToComponentField()
], VegaDatePickerCalendarCurrentPeriodController.prototype, "timezone", void 0);
__decorate([
  MapToComponentField()
], VegaDatePickerCalendarCurrentPeriodController.prototype, "minCalendarDate", void 0);
__decorate([
  MapToComponentField()
], VegaDatePickerCalendarCurrentPeriodController.prototype, "maxCalendarDate", void 0);
__decorate([
  MapToComponentField()
], VegaDatePickerCalendarCurrentPeriodController.prototype, "isMobileDevice", void 0);
__decorate([
  MapToComponentField()
], VegaDatePickerCalendarCurrentPeriodController.prototype, "monthYearChangeEventEmitter", void 0);
__decorate([
  MapToComponentField()
], VegaDatePickerCalendarCurrentPeriodController.prototype, "calendarSelection", void 0);
__decorate([
  MapToComponentField()
], VegaDatePickerCalendarCurrentPeriodController.prototype, "isDualMonths", void 0);
__decorate([
  MapToComponentMethod('connectedCallback')
], VegaDatePickerCalendarCurrentPeriodController.prototype, "connectedCallback", null);
__decorate([
  MapToComponentMethod('disconnectedCallback')
], VegaDatePickerCalendarCurrentPeriodController.prototype, "disconnectedCallback", null);
__decorate([
  MapToComponentMethod('componentWillLoad')
], VegaDatePickerCalendarCurrentPeriodController.prototype, "componentWillLoad", null);
__decorate([
  MapToComponentMethod('watchMaxCalendarDate')
], VegaDatePickerCalendarCurrentPeriodController.prototype, "watchMaxCalendarDate", null);
__decorate([
  MapToComponentMethod('watchMinCalendarDate')
], VegaDatePickerCalendarCurrentPeriodController.prototype, "watchMinCalendarDate", null);
__decorate([
  MapToComponentMethod('watchCurrentPeriod')
], VegaDatePickerCalendarCurrentPeriodController.prototype, "watchCurrentPeriod", null);
__decorate([
  MapToComponentMethod('reset')
], VegaDatePickerCalendarCurrentPeriodController.prototype, "resetCurrentPeriod", null);
