import { InternalFormFieldValidationRule } from './internal-form-field-validation-rule.abstract';
/**
 * A rule that checks if the value exists in the source or not
 *
 * @augments {InternalFormFieldValidationRule<SelectValueType<SelectType>>}
 */
export class InputSelectValueInSourceRule extends InternalFormFieldValidationRule {
  /**
   * It creates a new instance of the class with the given config.
   *
   * @param {() => SelectSourceItem[]} inputSelectSourceGetter - The input select source getter function
   */
  constructor(inputSelectSourceGetter) {
    super();
    this.inputSelectSourceGetter = inputSelectSourceGetter;
    /**
     * Generate an invalid result
     *
     * @param {string} message Error message
     * @returns {EvaluateResultTranslation} invalid validation result
     */
    this.invalidResult = (message) => ({
      isValid: false,
      message,
    });
    /**
     * Generate a valid result
     *
     * @returns {EvaluateResultTranslation} invalid validation result
     */
    this.validResult = () => ({
      isValid: true,
      message: '',
    });
  }
  /**
   * 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);
  }
  /**
   * check if the value exists in the source
   *
   * @param {SelectValueType<SelectType>} input - The input to be evaluated.
   * @returns {EvaluateResultTranslation} - The result of the evaluation.
   */
  evaluate(input) {
    if (typeof input === 'string' &&
      !this.inputSelectSourceGetter().find((item) => item.id === input)) {
      return this.invalidResult(`The value does not exist in the source`);
    }
    else if (Array.isArray(input) &&
      !input.every((value) => this.inputSelectSourceGetter().find((item) => item.id === value))) {
      return this.invalidResult(`There are values that do not exist in the source`);
    }
    return this.validResult();
  }
  /**
   * 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);
  }
  /**
   * It returns true if the input is a string or an array of two strings, and each string is a valid string
   *
   * @param {unknown} input - The input value to be validated.
   * @returns {boolean} A boolean value.
   */
  isAcceptedInputType(input) {
    return ((typeof input === 'string' ||
      (Array.isArray(input) && input.every((item) => typeof item === 'string'))) &&
      input.length > 0);
  }
}
