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 { VegaSlimmer, MapToComponentField, MapToComponentMethod } from 'vega-slimmer/core';
import { isTimeStr, pad } from '../../../../utils/date';
/** The `VegaTimePickerDropdownSelectedItemsController` class is responsible for managing the selected items in the dropdown of a time picker component. */
export class VegaTimePickerDropdownSelectedItemsController extends VegaSlimmer {
  constructor() {
    super(...arguments);
    this.DROPDOWN_ITEM_DEFAULT_HEIGHT = 32;
    /**
     * The selected fill time is displayed in the dropdown, increments is set to handle the filled minute mismatch option.
     *
     * @param {string} value time picker value
     */
    this.initSelectedItemsByString = (value) => {
      if (value === '' || !isTimeStr(value, this.timeFormat)) {
        this.selectedTimeValue = {};
      }
      else {
        this.selectedTimeValue = this.getClosetTimeValue(value);
      }
    };
    /*
     * The height of the scroll is based on the default height of the current element 32 * the index of the element.
     * The below method is e2e-test covered in
     * @see{module:vega-time-picker-select-time-e2e}
     * @see{module:vega-time-picker-scroll-top-e2e}
     */
    /* istanbul ignore next */
    /**
     * scroll the selected item to top
     *
     * @param {HTMLElement} element the element which should scroll to top
     */
    this.scrollToSelectedElement = (element) => {
      const parentElement = element.closest('ul');
      const scrollTop = Number(element.dataset['index']) * this.DROPDOWN_ITEM_DEFAULT_HEIGHT;
      parentElement.scrollTop = scrollTop;
    };
    /**
     * It is responsible for finding the closest minute value in the dropdown source that is less than or equal to the current minute value.
     *
     * @param {string} currentMinute minute string
     * @returns {string} the minute string which find in list
     */
    this.getClosestMinuteForCurrent = (currentMinute) => {
      const lessCurrentMinuteStrings = this.dropdownSource.minutes.filter((minute) => Number(minute) <= Number(currentMinute));
      return lessCurrentMinuteStrings[lessCurrentMinuteStrings.length - 1];
    };
    /**
     * It is responsible for getting the current time based on the specified time format (either '12-hour' or '24-hour').
     *
     * @param {TimeFormat} timeFormat time format string
     * @returns {TimeValue} time value object
     */
    this.getCurrentTime = (timeFormat) => {
      const curHour = new Date(Date.now()).getHours();
      const minute = pad(new Date(Date.now()).getMinutes());
      if (timeFormat === '12-hour') {
        return {
          hour: curHour > 12
            ? pad(curHour - 12)
            : pad(curHour === 0 ? 12 : curHour),
          minute: minute,
          amPm: curHour >= 12 ? 'PM' : 'AM',
        };
      }
      else {
        return {
          hour: pad(curHour),
          minute: minute,
        };
      }
    };
    /*
     * The selected element scrolls to the top by default.
     * The below method is e2e-test covered in
     * @see{module:vega-time-picker-select-time-e2e}
     * @see{module:vega-time-picker-scroll-top-e2e}
     */
    /* istanbul ignore next */
    /** The `selectedElementScrollTop` method is responsible for scrolling the selected element to the top of the dropdown list. */
    this.selectedElementScrollTop = () => {
      const elements = this.mode === 'single'
        ? this.singleDropdownRenderer.getSelectedItem()
        : this.rangeDropdownRenderer.getSelectedItem();
      elements.forEach((element) => {
        this.scrollToSelectedElement(element);
      });
    };
  }
  /**
   * The function syncSelectedItemsByValueChange updates the selected items based on a new value, if the value is a valid time string or empty.
   *
   *  @param {string} newValue - The `newValue` parameter is a string value that represents the new value that needs to be synchronized with the selected items.
   */
  syncSelectedItemsByValueChange(newValue) {
    if (this.mode === 'single') {
      if (isTimeStr(newValue, this.timeFormat) || !newValue) {
        this.initSelectedItemsByString(newValue);
      }
    }
  }
  /*
   * The below method is e2e-test covered in
   * @see{module:vega-time-picker-keyboard-control-e2e}
   */
  /* istanbul ignore next */
  /**
   * The function syncSelectedItemsPositionWhenDropdownShow scrolls the selected element to the top when the dropdown is shown, but only if the dropdown is not disabled.
   *
   * @param {boolean} newValue - A boolean value indicating whether the dropdown is being shown or hidden.
   */
  syncSelectedItemsPositionWhenDropdownShow(newValue) {
    if (newValue) {
      if (!this.disabled) {
        this.selectedElementScrollTop();
      }
    }
  }
  /**
   * The function syncSelectedItemsPosition checks if there are selected items and scrolls to the
   * selected element if necessary.
   */
  syncSelectedItemsPosition() {
    if ((this.mode === 'single' && Object.keys(this.selectedTimeValue).length > 0) ||
      (this.mode === 'range' && Array.isArray(this.value) && (this.value[0] || this.value[1]))) {
      this.selectedElementScrollTop();
    }
  }
  /**
   * The function setSelectedItems sets the selectedTimeValue to the provided value.
   *
   * @param {TimeValue} value - The value parameter is of type TimeValue.
   */
  setSelectedItems(value) {
    this.selectedTimeValue = value;
  }
  /**
   * The function "setSelectedItemsToCurrentTime" sets the selectedTimeValue to the current time in the specified time format.
   */
  setSelectedItemsToCurrentTime() {
    this.selectedTimeValue = this.getCurrentTime(this.timeFormat);
  }
  /**
   * The getClosetTimeValue function takes a current time string and returns an object with the hour, minute, and amPm values.
   *
   * @param {string} currentTime - The `currentTime` parameter is a string representing the current time. It should be in the format "HH:mm" for 24-hour format or "HH:mm AM/PM" for 12-hour format.
   * @returns {TimeValue} an object of type TimeValue.
   */
  getClosetTimeValue(currentTime) {
    const timeArray = currentTime.replace(' ', ':').split(':');
    return {
      hour: timeArray[0],
      minute: this.increments > 1 ? this.getClosestMinuteForCurrent(timeArray[1]) : timeArray[1],
      amPm: this.timeFormat === '12-hour' ? timeArray[2] : undefined,
    };
  }
}
__decorate([
  MapToComponentField({ writable: true })
], VegaTimePickerDropdownSelectedItemsController.prototype, "selectedTimeValue", void 0);
__decorate([
  MapToComponentField()
], VegaTimePickerDropdownSelectedItemsController.prototype, "mode", void 0);
__decorate([
  MapToComponentField()
], VegaTimePickerDropdownSelectedItemsController.prototype, "value", void 0);
__decorate([
  MapToComponentField()
], VegaTimePickerDropdownSelectedItemsController.prototype, "timeFormat", void 0);
__decorate([
  MapToComponentField()
], VegaTimePickerDropdownSelectedItemsController.prototype, "dropdownSource", void 0);
__decorate([
  MapToComponentField()
], VegaTimePickerDropdownSelectedItemsController.prototype, "increments", void 0);
__decorate([
  MapToComponentField()
], VegaTimePickerDropdownSelectedItemsController.prototype, "disabled", void 0);
__decorate([
  MapToComponentField()
], VegaTimePickerDropdownSelectedItemsController.prototype, "singleDropdownRenderer", void 0);
__decorate([
  MapToComponentField()
], VegaTimePickerDropdownSelectedItemsController.prototype, "rangeDropdownRenderer", void 0);
__decorate([
  MapToComponentMethod('watchValue')
], VegaTimePickerDropdownSelectedItemsController.prototype, "syncSelectedItemsByValueChange", null);
__decorate([
  MapToComponentMethod('watchIsDropdownShow')
], VegaTimePickerDropdownSelectedItemsController.prototype, "syncSelectedItemsPositionWhenDropdownShow", null);
__decorate([
  MapToComponentMethod('componentDidRender')
], VegaTimePickerDropdownSelectedItemsController.prototype, "syncSelectedItemsPosition", null);
