//  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 { IRule } from '@/model/Service/vnc-interface';
import { securityColors } from '@/model/colors';
import { pwdLevelFn } from '@/validators/get-security-level';

// 表单-区间数字-校验
export function rangeVerification(rule: IRule, val: string | number, callback: any) {
  const { max, min, message, required, isInteger } = rule;
  // 为空校验
  if (required && !val && val !== 0) {
    callback(new Error(message));
    return false;
  }
  if (val || val === 0) {
    // 输入的要是数字字符串 或者 数字
    const reg = /^[+-]?(0|([1-9]\d*))(\.\d+)?$/;
    if (!reg.test(String(val))) {
      callback(new Error(message));
      return false;
    }

    // 判断是否是整数
    if (isInteger && (String(val)).indexOf('.') >= 0) {
      callback(new Error(message));
      return false;
    }

    const valTemp = Number(val);

    if (!rangeVerificationOfMinMax({max, min, valTemp, callback, message})) {
      return false;
    }
  }
  callback();
  return true;
}

// 数字区间校验-最大值-最小值
function rangeVerificationOfMinMax(actions: any) {
  const { max, min, valTemp, callback, message } = actions;

  // 最小值
  if ((min || min === 0) && valTemp < min) {
    callback(new Error(message));
    return false;
  }
  // 最大值
  if ((max || max === 0) && valTemp > max) {
    callback(new Error(message));
    return false;
  }
  return true;
}

// 长度和正则表达式的校验
function lenAndMatchValidate(
  val: string,
  callback: any,
  containsEmptyString: any,
  matchRule: any,
  minLength?: number,
  message?: string,
  maxLength?: number,
): boolean {
  // 最小长度
  if (minLength && val.length < minLength) {
    callback(new Error(message));
    return false;
  }
  // 最大长度
  if (maxLength && val.length > maxLength) {
    callback(new Error(message));
    return false;
  }
  // 空字符串
  if (!containsEmptyString && val.indexOf(' ') > -1) {
    callback(new Error(message));
    return false;
  }
  
  // 正则表达式校验
  if (matchRule) {
    // 只传一个正则校验表达式
    if (matchRule instanceof RegExp && !matchRule.test(val)) {
      callback(new Error(message));
      return false;
    } else if (matchRule instanceof Array) {
      // 传一个数组，数组元素是正则校验表达式
      for (let i = 0; i < matchRule.length; i++) {
        if (matchRule[i] instanceof RegExp && !matchRule[i].test(val)) {
          callback(new Error(message));
          return false;
        }
      }
    }
  }
  
  return true;
}

// 字符串-校验
export function strVerification(rule: IRule, val: string, callback: any) {
  // matchRule 正则表达式校验规则
  // equals 相等的值 可能是对象，也可能普通数据类型
  const { maxLength, minLength, message, errorMsg, required, matchRule, equals, containsEmptyString } = rule;
  // 为空校验
  const str = traduction('COMMON_FORMAT_ERROR');
  if (required && !val) {
    callback(new Error(str));
    return false;
  }

  const errMsg = message || errorMsg;
  if (val) {
    if (!lenAndMatchValidate(val, callback, containsEmptyString, matchRule, minLength, errMsg, maxLength)) {
      return false;
    }
  }
  // 是否与某个字符串相等
  if (equals) {
    if (typeof equals === 'object' && equals instanceof Object && val !== equals.aimObj[equals.aimObjKey]) {
      equals.aimObj[equals.aimObjKey];
      callback(new Error(errMsg));
      return false;
    } else if (val !== equals && typeof equals === 'string') {
      callback(new Error(errMsg));
      return false;
    }
  }
  callback();
  return true;
}

// 必传和安全校验
function requiredAndSecurity(
  val: string,
  callback: any,
  verificationList: any,
  security: boolean,
  message?: string,
  required?: boolean,
) {
  // 如果不是必传且没有输入内容
  if (!required && !val) {
    callback();
    return true;
  } else {
    let num = 0;
    verificationList.forEach((item: any) => {
      if (item.state) {
        num++;
      }
    });

    // 根据满足条件个数来判断是否返回校验错误
    // 如果有安全程度
    if (security) {
      if (num === verificationList.length - 1) {
        callback();
        return true;
      }
    } else {
      // 如果没有安全程度
      if (num === verificationList.length) {
        callback();
        return true;
      }
    }

    callback(new Error(message));
    return false;
  }
}

// 密码检查
export function passwordVerification(rule: IRule, val: string, callback: any) {
  const { message, required } = rule;
  // 为空校验
  if (required && !val) {
    callback(new Error(message));
    return false;
  }

  let security = false;
  const { verificationList } = rule;
  if (verificationList && typeof verificationList === 'object' && verificationList instanceof Array) {
    verificationList.forEach((item: any) => {
      const { validator } = item;
      if (validator && typeof validator === 'function' && validator instanceof Function) {
        // 对每一项进行校验,设置其验证结果
        item.state = validator(item, val);
        // 如果有安全程度
        if (item.security) {
          security = true;
          // 0、1、2
          const level = pwdLevelFn(val, verificationList);
          setCircleAndLineStyle(level, item, val);
        }
      }
    });
  } else {
    // 没有设置校验规则
    callback();
    return false;
  }

  return requiredAndSecurity(val, callback, verificationList, security, message, required);
}

// 长度校验
export function lengthVerification(rule: IRule, val: string) {
  const { rangeSize } = rule;
  // 传两个值 [number, number]
  if (rangeSize && typeof rangeSize === 'object' && rangeSize instanceof Array && rangeSize.length >= 2) {
    return val.length >= rangeSize[0] && val.length <= rangeSize[1];
  } else if (rangeSize && typeof rangeSize === 'object' && rangeSize instanceof Array && rangeSize.length === 1) {
    // 只传一个值： [number]
    return val.length === rangeSize[0];
  } else if (rangeSize && typeof rangeSize === 'number') {
    // 只传一个值： number
    return val.length === rangeSize;
  }
  return false;
}

// 设置安全程度
export function setCircleAndLineStyle(level: number, securityItem: any, value: any) {
  if (value === '') {
    securityItem.circleAndLineStyles = ['', '', ''];
    securityItem.securityDescription = '';
    securityItem.descriptionTextColor = '';
    return;
  }

  let background = 'background:';
  switch (level) {
    case 1: {
      background += securityColors.middle;
      securityItem.circleAndLineStyles = [background, background, ''];
      securityItem.securityDescription = traduction('COMMON_SECURITY_MIDDLE');
      securityItem.descriptionTextColor = securityColors.middle;
      break;
    }
    case 2: {
      background += securityColors.strong;
      securityItem.circleAndLineStyles = [background, background, background];
      securityItem.securityDescription = traduction('COMMON_SECURITY_STRONG');
      securityItem.descriptionTextColor = securityColors.strong;
      break;
    }
    default: {
      background += securityColors.weak;
      securityItem.circleAndLineStyles = [background, '', ''];
      securityItem.securityDescription = traduction('COMMON_SECURITY_WEAK');
      securityItem.descriptionTextColor = securityColors.weak;
    }
  }
}

// 正则表达式匹配
export function matchRuleVerification(rule: IRule, val: string) {
  // 匹配规则，可以是正则表达式数组也可以是单纯一个正则表达式
  const { matchRule } = rule;
  if (matchRule) {
    if (typeof matchRule === 'object' && matchRule instanceof Array) {
      const { minCharType } = rule;
      let num = 0;
      matchRule.forEach((item: any) => {
        if (item instanceof RegExp && item.test(val)) {
          num++;
        }
      });
      // 如果不传最少要满足的条目，那么默认是所有都要满足
      if (minCharType) {
        return num >= minCharType;
      } else {
        return num === matchRule.length;
      }
    } else if (typeof matchRule === 'object' && matchRule instanceof RegExp) {
      return matchRule.test(val);
    }
  }

  // 传入的内容不合理
  return false;
}

// 包含空格校验
export function containsEmptyStringVerification(rule: IRule, val: string) {
  if (!val) {
    return false;
  }

  const { containsEmptyString } = rule;
  if (!containsEmptyString && val.indexOf(' ') > -1) {
    return false;
  }
  return true;
}
