//  Copyright (c) 2024 Huawei Technologies Co., Ltd.
//  openUBMC is licensed under Mulan PSL v2.
//  You can use this software according to the terms and conditions of the Mulan PSL v2.
//  You may obtain a copy of Mulan PSL v2 at:
//        #  http://license.coscl.org.cn/MulanPSL2
//  THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
//  EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
//  MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
//  See the Mulan PSL v2 for more details.
import { traduction } from '@/utils/language';
import { getBytes } from '@/utils/utils';

interface IValidatorRule {
  field: string;
  fullFiled: string;
  message: string;
  type: 'string';
  validator?: () => void;
  transform?: () => void;
}

interface IParams {
  pattern?: RegExp;
  message?: string;
  trigger?: string;
  range?: number[];
  [propName: string]: any;
}

export class BaseValidators {
  constructor() {}

  public static Required = (param?: IParams) => {
    return {
      message: param?.message || ' ',
      trigger: param?.trigger ? 'change' : 'blur',
      validator: (rule: IValidatorRule, value: any, callback: (error?: Error) => void) => {
        if (value === null || value === undefined) {
          callback();
          return;
        }
        const pattern = /^\s*.+$/;
        const _value = String(value);
        if (pattern.test(_value)) {
          callback();
        } else {
          callback(new Error());
        }
      },
    };
  };

  public static Number = (param?: IParams) => {
    return {
      message: param?.message || traduction('VALIDTOR_FORMAT_ERROR'),
      trigger: param?.trigger ? 'change' : 'blur',
      validator: (rule: IValidatorRule, value: any, callback: (error?: Error) => void) => {
        if (value === null || value === undefined || value === '') {
          callback();
          return;
        }
        const pattern = /^[0-9]+\.?[0-9]*$/;
        if (pattern.test(value)) {
          callback();
        } else {
          callback(new Error());
        }
      },
    };
  };

  public static Integer = (param?: IParams) => {
    return {
      message: param?.message || traduction('VALIDTOR_FORMAT_ERROR'),
      trigger: param?.trigger ? 'change' : 'blur',
      validator: (rule: IValidatorRule, value: any, callback: (error?: Error) => void) => {
        if (value === null || value === undefined || value === '') {
          callback();
          return;
        }
        const pattern = /^[0-9]+$/;
        const _value = String(value);
        let result = pattern.test(_value);
        if (result) {
          callback();
        } else {
          callback(new Error());
        }
      },
    };
  };

  public static Range = (param?: IParams) => {
    const range = param?.range || [];
    return {
      type: 'number',
      message: param?.message || traduction('VALID_VALUE_RANGE_TIP', range),
      trigger: param?.trigger ? 'change' : 'blur',
      validator: (rule: IValidatorRule, value: any, callback: (error?: Error) => void) => {
        const min = range[0];
        const max = range[1];
        if (value === null || value === undefined || value === '') {
          callback();
          return;
        }

        if (Number(value) <= max && Number(value) >= min) {
          callback();
        } else {
          callback(new Error());
        }
      },
    };
  };

  public static Pattern = (param?: IParams) => {
    return {
      type: 'string',
      trigger: param?.trigger ? 'change' : 'blur',
      message: param?.message || traduction('VALIDTOR_FORMAT_ERROR'),
      validator: (rule: IValidatorRule, value: any, callback: (error?: Error) => void) => {
        if (value === '') {
          callback();
          return;
        }

        if (param?.pattern?.test(value)) {
          callback();
        } else {
          callback(new Error());
        }
      },
    };
  };

  public static NotAllWhiteSpace = (param?: IParams) => {
    return {
      type: 'string',
      trigger: param?.trigger ? 'change' : 'blur',
      message: param?.message || traduction('VALIDTOR_FORMAT_ERROR'),
      validator: (rule: IValidatorRule, value: any, callback: (error?: Error) => void) => {
        if (/^\s+$/.test(value)) {
          callback(new Error());
        } else {
          callback();
        }
      },
    };
  };

  public static MaxLength255 = (param?: IParams) => {
    return {
      type: 'string',
      trigger: param?.trigger ? 'change' : 'blur',
      message: param?.message || traduction('VALIDATOR_OUTOF_RANGE'),
      validator: (rule: IValidatorRule, value: any, callback: (error?: Error) => void) => {
        const length = getBytes(value);
        const max = param?.maxLength || 255;
        if (length > max) {
          callback(new Error());
        } else {
          callback();
        }
      },
    };
  };
}
