/**
 * YAML 配置验证器
 * 
 * 支持的配置格式：
 * - 完整配置：详细指定所有选项
 * - 简化配置：自动推断字段名和选择器
 * - 人类行为：框架自动添加延迟，无需手动配置
 */
class ConfigValidator {
  constructor() {
    // 定义每个 action 的必需字段
    this.actionSchemas = {
      navigate: {
        required: ['url'],
        optional: ['name', 'options', 'verifyUrl', 'verifyElements', 'waitAfter', 'maxRetries', 'retryDelay', 'totalTimeout']
      },
      fillForm: {
        required: ['fields'],
        optional: ['name', 'humanLike', 'autoRetry', 'clearTimes']
        // 注意：humanLike 已废弃，框架默认使用人类行为
        // fields 支持：字符串（自动推断）或对象（完整配置）
      },
      click: {
        required: ['selector'],
        optional: ['name', 'verifyAfter', 'waitForPageChange', 'waitAfter', 'optional', 'timeout', 'waitForEnabled', 'humanLike', 'checkSelector']
      },
      wait: {
        required: ['type'],
        optional: ['name', 'duration', 'find', 'timeout', 'urlContains', 'handler']
      },
      extract: {
        required: ['selector', 'contextKey'],
        optional: ['name', 'extractType', 'regex', 'saveTo', 'filter', 'multiple', 'required', 'attribute']
      },
      verify: {
        required: ['conditions'],
        optional: ['name', 'timeout', 'pollInterval', 'onSuccess', 'onFailure', 'onTimeout']
      },
      retryBlock: {
        required: ['steps'],
        optional: ['name', 'maxRetries', 'retryDelay', 'onRetryBefore', 'onRetryAfter']
      },
      scroll: {
        required: [],
        optional: ['name', 'type', 'selector', 'x', 'y', 'behavior', 'direction']
      },
      custom: {
        required: ['handler'],
        optional: ['name', 'params', 'optional']
      }
    };
  }
  
  /**
   * 验证完整配置
   */
  validate(config) {
    const errors = [];
    
    // 验证基本结构
    if (!config.site) {
      errors.push('缺少 site 配置');
    }
    
    if (!config.workflow || !Array.isArray(config.workflow)) {
      errors.push('缺少 workflow 或 workflow 不是数组');
      return { valid: false, errors };
    }
    
    // 验证每个步骤
    config.workflow.forEach((step, index) => {
      const stepErrors = this.validateStep(step, index);
      errors.push(...stepErrors);
    });
    
    return {
      valid: errors.length === 0,
      errors
    };
  }
  
  /**
   * 验证单个步骤
   */
  validateStep(step, index) {
    const errors = [];
    const stepLabel = `步骤 ${index + 1} (${step.name || step.action})`;
    
    // 检查是否有 action
    if (!step.action) {
      errors.push(`${stepLabel}: 缺少 action 字段`);
      return errors;
    }
    
    // 检查 action 是否支持
    const schema = this.actionSchemas[step.action];
    if (!schema) {
      errors.push(`${stepLabel}: 未知的 action 类型 "${step.action}"`);
      return errors;
    }
    
    // 检查必需字段
    schema.required.forEach(field => {
      if (step[field] === undefined) {
        errors.push(`${stepLabel}: 缺少必需字段 "${field}"`);
      }
    });
    
    // 类型检查
    errors.push(...this.validateFieldTypes(step, stepLabel));
    
    // 检查未知字段（警告）
    const allFields = [...schema.required, ...schema.optional, 'action'];
    Object.keys(step).forEach(field => {
      if (!allFields.includes(field)) {
        errors.push(`${stepLabel}: 警告 - 未知字段 "${field}"`);
      }
    });
    
    // 特定 action 的额外验证
    if (step.action === 'verify') {
      if (step.conditions) {
        if (!step.conditions.success && !step.conditions.failure) {
          errors.push(`${stepLabel}: conditions 必须包含 success 或 failure`);
        }
      }
    }
    
    if (step.action === 'retryBlock') {
      if (step.steps && Array.isArray(step.steps)) {
        step.steps.forEach((subStep, subIndex) => {
          const subErrors = this.validateStep(subStep, subIndex);
          errors.push(...subErrors.map(e => `${stepLabel} -> ${e}`));
        });
      }
    }
    
    return errors;
  }
  
  /**
   * 类型检查
   */
  validateFieldTypes(step, stepLabel) {
    const errors = [];
    
    // fillForm 的 fields 应该是对象
    if (step.action === 'fillForm' && step.fields) {
      if (typeof step.fields !== 'object' || Array.isArray(step.fields)) {
        errors.push(`${stepLabel}: fields 必须是对象类型`);
      }
    }
    
    // 数字类型字段检查
    const numberFields = ['timeout', 'maxRetries', 'retryDelay', 'duration', 'totalTimeout', 'pollInterval'];
    numberFields.forEach(field => {
      if (step[field] !== undefined && typeof step[field] !== 'number') {
        errors.push(`${stepLabel}: ${field} 必须是数字类型，当前为 ${typeof step[field]}`);
      }
    });
    
    // 布尔类型字段检查
    const booleanFields = ['humanLike', 'optional', 'waitForEnabled'];
    booleanFields.forEach(field => {
      if (step[field] !== undefined && typeof step[field] !== 'boolean') {
        errors.push(`${stepLabel}: ${field} 必须是布尔类型，当前为 ${typeof step[field]}`);
      }
    });
    
    // 数组类型字段检查
    if (step.steps && !Array.isArray(step.steps)) {
      errors.push(`${stepLabel}: steps 必须是数组类型`);
    }
    
    if (step.verifyElements && !Array.isArray(step.verifyElements)) {
      errors.push(`${stepLabel}: verifyElements 必须是数组类型`);
    }
    
    return errors;
  }
  
  /**
   * 验证并打印结果
   */
  validateAndReport(config, logger = console) {
    const result = this.validate(config);
    
    if (result.valid) {
      logger.log('✓ 配置验证通过');
      return true;
    } else {
      logger.error('✗ 配置验证失败:');
      result.errors.forEach(error => {
        logger.error(`  - ${error}`);
      });
      return false;
    }
  }
}

module.exports = ConfigValidator;
