/**
 * 공통 유효성 검사 유틸리티
 * 
 * 모든 폼에서 재사용 가능한 유효성 검사 규칙과 함수를 제공합니다.
 */

export interface ValidationRule {
  field: string;
  fieldLabel: string;
  rules: {
    required?: boolean;
    minLength?: number;
    maxLength?: number;
    min?: number;
    max?: number;
    email?: boolean;
    phone?: boolean;
    number?: boolean;
    positive?: boolean;
    integer?: boolean;
    pattern?: RegExp;
    custom?: (value: any, formData?: any) => string | null; // 커스텀 검사, null이면 통과
  };
}

export interface ValidationResult {
  isValid: boolean;
  errors: string[];
  firstError?: string;
  fieldErrors?: Record<string, string>; // 필드별 에러 맵
}

/**
 * 유효성 검사 실행
 */
export function validateForm(formData: any, validationRules: ValidationRule[]): ValidationResult {
  const errors: string[] = [];
  const fieldErrors: Record<string, string> = {};
  
  for (const rule of validationRules) {
    const value = formData[rule.field];
    const fieldErrorsList = validateField(value, rule, formData);
    errors.push(...fieldErrorsList);
    if (fieldErrorsList.length > 0) {
      fieldErrors[rule.field] = fieldErrorsList[0];
    }
  }
  
  return {
    isValid: errors.length === 0,
    errors,
    firstError: errors.length > 0 ? errors[0] : undefined,
    fieldErrors: Object.keys(fieldErrors).length > 0 ? fieldErrors : undefined,
  };
}

/**
 * 개별 필드 유효성 검사
 */
export function validateField(value: any, rule: ValidationRule, formData?: any): string[] {
  const errors: string[] = [];
  const { field, fieldLabel, rules } = rule;
  
  // 필수 입력 검사
  if (rules.required) {
    if (value === null || value === undefined || value === '' || 
        (Array.isArray(value) && value.length === 0)) {
      errors.push(`${fieldLabel}은(는) 필수 입력 항목입니다.`);
      return errors; // 필수 검사 실패 시 다른 검사는 하지 않음
    }
  }
  
  // 값이 없으면 나머지 검사 스킵 (필수가 아닌 경우)
  if (value === null || value === undefined || value === '') {
    return errors;
  }
  
  // 최소 길이 검사
  if (rules.minLength !== undefined && typeof value === 'string') {
    if (value.length < rules.minLength) {
      errors.push(`${fieldLabel}은(는) 최소 ${rules.minLength}자 이상이어야 합니다.`);
    }
  }
  
  // 최대 길이 검사
  if (rules.maxLength !== undefined && typeof value === 'string') {
    if (value.length > rules.maxLength) {
      errors.push(`${fieldLabel}은(는) 최대 ${rules.maxLength}자 이하여야 합니다.`);
    }
  }
  
  // 숫자 검사
  if (rules.number) {
    const numValue = Number(value);
    if (isNaN(numValue)) {
      errors.push(`${fieldLabel}은(는) 숫자여야 합니다.`);
      return errors; // 숫자가 아니면 다른 숫자 관련 검사 스킵
    }
    
    // 최소값 검사
    if (rules.min !== undefined && numValue < rules.min) {
      errors.push(`${fieldLabel}은(는) ${rules.min} 이상이어야 합니다.`);
    }
    
    // 최대값 검사
    if (rules.max !== undefined && numValue > rules.max) {
      errors.push(`${fieldLabel}은(는) ${rules.max} 이하여야 합니다.`);
    }
    
    // 양수 검사
    if (rules.positive && numValue <= 0) {
      errors.push(`${fieldLabel}은(는) 양수여야 합니다.`);
    }
    
    // 정수 검사
    if (rules.integer && !Number.isInteger(numValue)) {
      errors.push(`${fieldLabel}은(는) 정수여야 합니다.`);
    }
  }
  
  // 이메일 검사
  if (rules.email && typeof value === 'string') {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(value)) {
      errors.push(`${fieldLabel}의 형식이 올바르지 않습니다.`);
    }
  }
  
  // 전화번호 검사
  if (rules.phone && typeof value === 'string') {
    const phoneRegex = /^[0-9-+().\s]+$/;
    if (!phoneRegex.test(value)) {
      errors.push(`${fieldLabel}의 형식이 올바르지 않습니다.`);
    }
  }
  
  // 정규식 패턴 검사
  if (rules.pattern && typeof value === 'string') {
    if (!rules.pattern.test(value)) {
      errors.push(`${fieldLabel}의 형식이 올바르지 않습니다.`);
    }
  }
  
  // 커스텀 검사
  if (rules.custom) {
    const customError = rules.custom(value, formData);
    if (customError) {
      errors.push(customError);
    }
  }
  
  return errors;
}

/**
 * 빠른 검사 헬퍼 함수들
 */
export const ValidationHelpers = {
  /**
   * 필수 입력 규칙
   */
  required(field: string, fieldLabel: string): ValidationRule {
    return {
      field,
      fieldLabel,
      rules: { required: true }
    };
  },
  
  /**
   * 필수 + 최소/최대 길이
   */
  requiredText(field: string, fieldLabel: string, minLength?: number, maxLength?: number): ValidationRule {
    return {
      field,
      fieldLabel,
      rules: { 
        required: true,
        minLength,
        maxLength
      }
    };
  },
  
  /**
   * 필수 + 숫자
   */
  requiredNumber(field: string, fieldLabel: string, min?: number, max?: number): ValidationRule {
    return {
      field,
      fieldLabel,
      rules: { 
        required: true,
        number: true,
        min,
        max
      }
    };
  },
  
  /**
   * 필수 + 양수
   */
  requiredPositive(field: string, fieldLabel: string): ValidationRule {
    return {
      field,
      fieldLabel,
      rules: { 
        required: true,
        number: true,
        positive: true
      }
    };
  },
  
  /**
   * 필수 + 이메일
   */
  requiredEmail(field: string, fieldLabel: string): ValidationRule {
    return {
      field,
      fieldLabel,
      rules: { 
        required: true,
        email: true
      }
    };
  },
  
  /**
   * 필수 + 전화번호
   */
  requiredPhone(field: string, fieldLabel: string): ValidationRule {
    return {
      field,
      fieldLabel,
      rules: { 
        required: true,
        phone: true
      }
    };
  },
};

/**
 * 사용 예시:
 * 
 * ```tsx
 * const validationRules: ValidationRule[] = [
 *   ValidationHelpers.required('customerName', '고객명'),
 *   ValidationHelpers.requiredEmail('email', '이메일'),
 *   ValidationHelpers.requiredPositive('quantity', '수량'),
 *   {
 *     field: 'customField',
 *     fieldLabel: '커스텀 필드',
 *     rules: {
 *       required: true,
 *       custom: (value, formData) => {
 *         if (formData.type === 'A' && value < 100) {
 *           return '타입 A의 경우 100 이상이어야 합니다.';
 *         }
 *         return null;
 *       }
 *     }
 *   }
 * ];
 * 
 * const result = validateForm(formData, validationRules);
 * if (!result.isValid) {
 *   toast.error(result.firstError);
 * }
 * ```
 */