import moment from 'moment';

export default class WsDatePickerController {
  static $inject = ['$timeout', '$filter', '$translate', 'wsDatePickerService'];
  $timeout
  $filter
  $translate
  wsDatePickerService

  constructor($timeout, $filter, $translate, wsDatePickerService) {
    this.$timeout = $timeout;
    this.$filter = $filter;
    this.$translate = $translate;
    this.wsDatePickerService = wsDatePickerService;
  }

  $onInit() {
    this.model = {
      minDate: this.getMinDate(),
      maxDate: this.getMaxDate(),
      firstDayOfWeek: moment().day(this.firstDayOfWeek || 'sunday').weekday(),
      disableWeekends: this.disableWeekends || false,
      disableNextNDays: this.disableNextNDays || 0,
      disableNextNBusinessDays: this.disableNextNBusinessDays || 0,
    };
    this.placeholderText = this.placeholderText || this.$translate.instant('date-picker.start-date');
    this.sizeCssClass = this.sizeCssClass === 'size-md' ? 'size-md' : 'size-sm';

    if (this._areAnyDatesDisabled()) {
      let allDisabledDates = this.disabledDates || [];
      if (this.disableWeekends) {
        allDisabledDates = allDisabledDates.concat(
          this.wsDatePickerService.getWeekendDates(this.model.minDate, this.model.maxDate));
      }
      if (this.disableNextNDays) {
        allDisabledDates = allDisabledDates.concat(
          this.wsDatePickerService.getDatesFromNowToN(this.disableNextNDays));
      }
      if (this.disableNextNBusinessDays) {
        allDisabledDates = allDisabledDates.concat(
          this.wsDatePickerService.getDatesFromNowToN(this.disableNextNBusinessDays, true));
      }
      this.model.filteredDisabledDates = allDisabledDates.map(date => moment(new Date(date)).format('YYYY/MM/DD'));
    }
    /* Current date has to be set after initialization due to a bug in the
     the angular datepicker. https://github.com/720kb/angular-datepicker/issues/167 */
    this.$timeout(() => {
      if (this.model.selectedDate && moment(this.model.selectedDate).isValid()) {
        this.model.defaultDate = this.model.selectedDate;
      } else if (this.defaultDate) {
        this.model.defaultDate = this.defaultDate.toString();
      } else if (this.ngModel) {
        this.model.defaultDate = this.ngModel.toString();
      } else if (this.allowBlank) {
        this.model.defaultDate = null;
      } else {
        this.model.defaultDate = moment(this.minDate).add(1, 'day').toString();
      }
      this.model.defaultDate = this.wsDatePickerService.getNextAvailableDate(
        this.model.filteredDisabledDates, moment(new Date(this.model.defaultDate)));
    });
    this.model.renderDatepicker = true;
  }

  $onChanges(changes) {
    // Set the displayed value with the correct format when the parent changes the ngModel value
    if (this.model && changes.ngModel) {
      this.model.selectedDate = this.$filter('date')(changes.ngModel.currentValue, this.format || 'MMM d, yyyy');
      this.onDateSelection();
    }
  }

  onDateSelection() {
    if (this.ctrlNgModel) {
      // Update ctrlNgModel
      if (this.ctrlNgModel && this.model.selectedDate) {
        this.ctrlNgModel.$setViewValue(this.wsDatePickerService
         .convertDisplayInputDateToServerFormat(this.model.selectedDate));
      } else if (this._isDateFieldCleared()) {
        this.ctrlNgModel.$setViewValue(null);
      }
      // Verify ctrlNgModel
      const date = moment(this.ctrlNgModel.$viewValue, moment.momentFormat);
      const DATE_INCLUSIVE = '[]';
      const isDatePickerBlank = this.model.selectedDate === '';
      const minDateMoment = moment(new Date(this.model.minDate));
      const maxDateMoment = moment(new Date(this.model.maxDate));
      const isDateWithinTheMinAndMaxDateRange = date.isValid() && date.isBetween(
        minDateMoment, maxDateMoment, DATE_INCLUSIVE);
      const isValidDateForDatePicker = isDatePickerBlank
        || isDateWithinTheMinAndMaxDateRange || date.isSame(this.defaultDate);
      this.ctrlNgModel.$setValidity(this.name, isValidDateForDatePicker);
    }
  }

  getMinDate() {
    if (this.minDate) {
      return this.minDate;
    } else if (this.minYear) {
      return moment(new Date()).year(this.minYear).startOf('year').toString();
    }
    return this.wsDatePickerService.getYesterdayDateAsString();
  }

  getMaxDate() {
    if (this.maxDate) {
      return this.maxDate;
    } else if (this.maxYear) {
      return moment(new Date()).year(this.maxYear).endOf('year').toString();
    }
    return this.wsDatePickerService.getNextYearDateAsString();
  }

  _areAnyDatesDisabled() {
    return (this.disabledDates && this.disabledDates.length) ||
            this.disableWeekends ||
            this.disableNextNDays ||
            this.disableNextNBusinessDays;
  }

  _isDateFieldCleared() {
    return this.allowBlank && this.model.selectedDate === '';
  }
}
