import Joi from "joi";
import { UndefinedOr } from "../../../../../../utilities";
import { RuleValidator } from "../../../RuleValidator";
import { Result } from "../../Result";
import { StringValueObject } from "../../StringValueObject";

export interface IQuickSearchCriteria {
  searchTerm: string;
  toJSON(): string;
  toString(): string;
}

export class QuickSearchCriteria
  extends StringValueObject
  implements IQuickSearchCriteria
{
  protected static validate(value: UndefinedOr<string>) {
    const searchString = value;

    if (
      RuleValidator.validate(
        RuleValidator.RULE_NOT_NULL_OR_UNDEFINED,
        searchString,
      ).isSuccess
    ) {
      const stringOrError = RuleValidator.validate<string>(
        RuleValidator.RULE_IS_TYPE_STRING,
        searchString,
      );

      if (stringOrError.isFailure) {
        return stringOrError;
      }
    }

    return Result.ok(searchString);
  }

  public static create(value: UndefinedOr<string>) {
    const stringOrError = this.validate(value);

    if (stringOrError.isFailure) {
      return Result.fail(stringOrError.error);
    }

    const _term = QuickSearchCriteria.sanitize(stringOrError.object);

    return Result.ok<QuickSearchCriteria>(new QuickSearchCriteria(_term));
  }

  private static sanitize(searchTerm: UndefinedOr<string>): string {
    return String(Joi.string().default("").trim().validate(searchTerm).value);
  }

  get searchTerm(): string {
    return this.toString();
  }

  public toJSON(): string {
    return JSON.stringify(this.toString());
  }

  public toPrimitive(): string {
    return this.toString();
  }
}
