import { CalendarDate } from '../../../../helpers/calendar';
import { isCalendarDateType } from '../../../../types/type-guard';
import { LogUtility } from '../../../../utils/log';
/** Calendar selection object. */
export class CalendarSelection {
  constructor(startDate, endDate, mode) {
    this.startDate = startDate;
    this.endDate = endDate;
    this.mode = mode;
    if (this.mode === 'range' && this.startDate && this.endDate && this.startDate.isAfter(this.endDate)) {
      const startDate = this.startDate;
      this.startDate = this.endDate;
      this.endDate = startDate;
    }
  }
  /**
   * Creates a CalendarSelection from a selection value.
   *
   * @param {DatePickerValueType<DatePickerModeType>} selection - The selection value.
   * @param {DatePickerModeType} mode - The mode of the date picker.
   * @param {string} format - The date format to use for string conversion.
   * @returns {CalendarSelection} - The created CalendarSelection instance.
   */
  static fromSelection(selection, mode, format) {
    let startDate = null;
    let endDate = null;
    if (this.isValidSelection(selection, mode, format)) {
      if (mode === 'single' && typeof selection === 'string') {
        const date = CalendarDate.fromString(selection, format);
        startDate = date;
        endDate = date;
      }
      else if (mode === 'range' && Array.isArray(selection)) {
        startDate = CalendarDate.fromString(selection[0], format);
        endDate = CalendarDate.fromString(selection[1], format);
      }
    }
    return new CalendarSelection(startDate, endDate, mode);
  }
  /**
   * Check if the selection is valid.
   *
   * @param {DatePickerValueType<DatePickerModeType>} selection - The selection value.
   * @param {DatePickerModeType} mode - The mode of the date picker.
   * @param {string} format - The date format to use for string conversion.
   * @returns {boolean} - True if the selection is valid, false otherwise.
   */
  static isValidSelection(selection, mode, format) {
    let isValid;
    switch (mode) {
      case 'single':
        isValid = this.isValidDateString(selection, format);
        break;
      case 'range':
        isValid =
          Array.isArray(selection) &&
            selection.length === 2 &&
            selection.every((item) => this.isValidDateString(item, format));
        break;
    }
    if (!isValid) {
      LogUtility.warn(`Invalid date picker calendar selection ${selection} for ${mode} mode`);
    }
    return isValid;
  }
  /**
   * Check if a date string is valid.
   *
   * @param {Nullable<string>} dateString - The date string to check.
   * @param {string} format - The date format to use for string conversion.
   * @returns {boolean} - True if the date string is valid, false otherwise.
   */
  static isValidDateString(dateString, format) {
    return ((dateString && typeof dateString === 'string' && !!CalendarDate.fromString(dateString, format)) ||
      dateString === '');
  }
  /**
   * Gets the selection value based on the current calendar selection.
   *
   * @param {string} format - The date format to use for string conversion.
   * @returns {DatePickerValueType<DatePickerModeType>} - The selection value.
   */
  toSelection(format) {
    var _a, _b, _c;
    if (this.mode === 'range') {
      return [((_a = this.startDate) === null || _a === void 0 ? void 0 : _a.toString(format)) || '', ((_b = this.endDate) === null || _b === void 0 ? void 0 : _b.toString(format)) || ''];
    }
    else {
      return ((_c = this.startDate) === null || _c === void 0 ? void 0 : _c.toString(format)) || '';
    }
  }
  /**
   * Checks if this calendar selection is equal to another.
   *
   * @param {CalendarSelection} other - The other calendar selection to compare with.
   * @returns {boolean} - True if both selections are equal, false otherwise.
   */
  equals(other) {
    if (!other)
      return false;
    const isStartDateEqual = this.startDate && other.startDate
      ? this.startDate.equal(other.startDate)
      : this.startDate === this.endDate;
    const isEndDateEqual = this.endDate && other.endDate
      ? this.endDate.equal(other.endDate)
      : this.endDate === other.endDate;
    return isStartDateEqual && isEndDateEqual;
  }
  /**
   * Checks if the calendar selection is completed.
   *
   * @returns {boolean} - True if the selection is completed, false otherwise.
   */
  isCompleted() {
    return (isCalendarDateType(this.startDate) &&
      (this.mode === 'range' ? isCalendarDateType(this.endDate) : true));
  }
  /**
   * Checks if the calendar selection is empty.
   *
   * @returns {boolean} - True if the selection is empty, false otherwise.
   */
  isEmpty() {
    return !isCalendarDateType(this.startDate) && !isCalendarDateType(this.endDate);
  }
}
