import type { Rule } from './types';

// ==================== 工具函数 ====================

// 获取值长度（支持字符串和数组）
export function getLength(value: any): number {
  if (typeof value === 'string') return value.length;
  if (Array.isArray(value)) return value.length;
  return 0;
}

// 校验函数
export async function validateRule<TValue>(
  rule: Rule<TValue>,
  value: TValue,
  formValues: Record<string, any>
): Promise<string | undefined> {
  // 必填校验
  if ('required' in rule && rule.required) {
    if (value === undefined || value === null || value === '') {
      return rule.message || '此字段为必填项';
    }
  }

  // 最小值校验（数字）
  if ('min' in rule && typeof value === 'number') {
    if (value < rule.min) {
      return rule.message || `值不能小于 ${rule.min}`;
    }
  }

  // 最大值校验（数字）
  if ('max' in rule && typeof value === 'number') {
    if (value > rule.max) {
      return rule.message || `值不能大于 ${rule.max}`;
    }
  }

  // 最小长度校验
  if ('minLength' in rule) {
    const length = getLength(value);
    if (length < rule.minLength) {
      return rule.message || `长度不能少于 ${rule.minLength} 个字符`;
    }
  }

  // 最大长度校验
  if ('maxLength' in rule) {
    const length = getLength(value);
    if (length > rule.maxLength) {
      return rule.message || `长度不能超过 ${rule.maxLength} 个字符`;
    }
  }

  // 自定义校验函数
  if ('validator' in rule) {
    try {
      const result = await rule.validator(value, formValues);
      if (result) {
        return result;
      }
    } catch (error) {
      if (typeof error === 'string') {
        return error;
      }
      return rule.message || '校验失败';
    }
  }

  return undefined;
}

// 工具函数：根据路径获取/设置对象值
export function getByPath(obj: any, path: string): any {
  const segments = path.split('.');
  let current = obj;
  for (const key of segments) {
    if (current == null) return undefined;
    current = current[key];
  }
  return current;
}

export function setByPath(obj: any, path: string, value: any): void {
  const segments = path.split('.');
  let current = obj;
  for (let i = 0; i < segments.length - 1; i++) {
    const key = segments[i];
    if (current[key] == null) {
      current[key] = {};
    }
    current = current[key];
  }
  current[segments[segments.length - 1]] = value;
}
