import { convert12HourTo24HourFormat, isTimeStr } from '../../../utils/date';
import { InternalFormFieldValidationRule } from './internal-form-field-validation-rule.abstract';
/**
 * A rule that checks if start time is before than end time
 */
export class TimeRangeRule extends InternalFormFieldValidationRule {
  /**
   * It creates a new instance of the class with the given config.
   *
   * @param {{ timeFormat: TimeFormat }} config - config including the timeFormat for time value
   * @param {TimeFormat} config.timeFormat - The timeFormat for time value
   */
  constructor(config) {
    super();
    this.config = config;
  }
  /**
   * If the input is accepted and the status is not disabled and visible, then return true
   *
   * @param {unknown} input - The input to be evaluated.
   * @param {FormFieldStatusMeta} [status] - FormFieldStatusMeta
   * @returns {boolean} A boolean value.
   */
  canEvaluate(input, status) {
    return status
      ? this.isAcceptedInputType(input) && !status.disabled && status.visible
      : this.isAcceptedInputType(input);
  }
  /**
   * If the field is not disabled, visible, and has been touched or modified, then show the error
   *
   * @param {FormFieldStatusMeta} status - FormFieldStatusMeta
   * @returns {boolean} A boolean value.
   */
  shouldShowError(status) {
    return !status.disabled && status.visible && (status.touched || status.modified);
  }
  /**
   * Check if the start time is before than end time
   *
   * @param {string | string[]} input - The value of the time picker.
   * @returns  {EvaluateResultTranslation} - The result of the evaluation.
   */
  evaluate(input) {
    if (!this.isAcceptedInputType(input)) {
      throw new Error(`Unexpected type of input: ${typeof input}: ${input}`);
    }
    const isValid = this.isStartTimeBeforeEndTime(input[0], input[1]);
    return {
      isValid: isValid,
      message: isValid ? '' : 'The end time should be later than start time',
    };
  }
  /**
   * If the input is an array of two strings, and each string is a valid date, then return true.
   *
   * @param {unknown} input - The input value to be validated.
   * @returns {boolean} A boolean value.
   */
  isAcceptedInputType(input) {
    return (Array.isArray(input) &&
      input.length === 2 &&
      input.every((item) => isTimeStr(item, this.config.timeFormat)));
  }
  /**
   * check if start time before end time, the 12-hour time should convert to 24-hour time format, the safari, 'fire fox' do not support 12-hour
   *
   * @param {string} startTime time string
   * @param  {string} endTime time string
   * @returns {boolean} boolean value
   */
  isStartTimeBeforeEndTime(startTime, endTime) {
    const date = new Date();
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    const baseDate = `${year}-${month}-${day}`;
    return (new Date(`${baseDate}T${convert12HourTo24HourFormat(endTime)}`) >
      new Date(`${baseDate}T${convert12HourTo24HourFormat(startTime)}`));
  }
}
