import { AbstractControl, Validators, ValidatorFn } from '@angular/forms';
import { _Validators } from '@delon/util';
import { MESSAGE_UTIL } from 'src/app/conf/message';
import { AppUtils } from './app-utils';

export type AppValidatorsOptions = { errorTip: string } & Record<string, any>;
export type AppValidatorsErrors = Record<string, AppValidatorsOptions>;

export class AppValidators {
  static idCard(id: string, ...params: string[]): ValidatorFn {
    const messageParams = params.length === 0 ? [] : params;
    return (control: AbstractControl): AppValidatorsErrors | null => {
      if (AppUtils.isNull(control.value)) {
        return {};
      }
      if (_Validators.idCard(control) === null) {
        return null;
      }
      return { idcard: { errorTip: MESSAGE_UTIL.getMessage(id, messageParams) } };
    };
  }

  static maxLength(maxLength: number, id: string, ...params: string[]): ValidatorFn {
    const messageParams = params.length === 0 ? [maxLength.toString()] : params;
    return (control: AbstractControl): AppValidatorsErrors | null => {
      if (Validators.maxLength(maxLength)(control) === null) {
        return null;
      }
      return { maxlength: { errorTip: MESSAGE_UTIL.getMessage(id, messageParams) } };
    };
  }

  static minLength(minLength: number, id: string, ...params: string[]): ValidatorFn {
    const messageParams = params.length === 0 ? [minLength.toString()] : params;
    return (control: AbstractControl): AppValidatorsErrors | null => {
      if (Validators.minLength(minLength)(control) === null) {
        return null;
      }
      return { minLength: { errorTip: MESSAGE_UTIL.getMessage(id, messageParams) } };
    };
  }

  static required(id: string, ...params: string[]): ValidatorFn {
    const messageParams = params.length === 0 ? [] : params;
    return (control: AbstractControl): AppValidatorsErrors | null => {
      if (Validators.required(control) === null) {
        return null;
      }
      return { required: { errorTip: MESSAGE_UTIL.getMessage(id, messageParams) } };
    };
  }

  static email(id: string, ...params: string[]): ValidatorFn {
    const messageParams = params.length === 0 ? [] : params;
    return (control: AbstractControl): AppValidatorsErrors | null => {
      if (Validators.required(control) !== null) {
        return { required: { errorTip: MESSAGE_UTIL.getMessage(id, messageParams) } };
      }

      if (Validators.email(control) !== null) {
        return { email: { errorTip: MESSAGE_UTIL.getMessage(id, messageParams) } };
      }

      return null;
    };
  }

  static mobile(id: string, ...params: string[]): ValidatorFn {
    const messageParams = params.length === 0 ? [] : params;
    return (control: AbstractControl): AppValidatorsErrors | null => {
      if (!control.value) {
        return null;
      }
      if (_Validators.mobile(control) === null) {
        return null;
      }
      return { mobile: { errorTip: MESSAGE_UTIL.getMessage(id, messageParams) } };
    };
  }

  static pattern(patternStr: RegExp, id: string, ...params: string[]): ValidatorFn {
    const messageParams = params.length === 0 ? [] : params;
    return (control: AbstractControl): AppValidatorsErrors | null => {
      patternStr.lastIndex = 0;
      if (Validators.pattern(patternStr)(control) === null) {
        return null;
      }
      return { pattern: { errorTip: MESSAGE_UTIL.getMessage(id, messageParams) } };
    };
  }

  static other(fn: (control: AbstractControl) => AppValidatorsErrors | null): ValidatorFn {
    return (control: AbstractControl): AppValidatorsErrors | null => {
      return fn(control);
    };
  }
}
