const BaseAction = require('../core/base-action');

/**
 * 导航动作 - 打开页面
 */
class NavigateAction extends BaseAction {
  async execute() {
    const url = this.replaceVariables(this.config.url);
    const options = this.config.options || {
      waitUntil: 'networkidle2',
      timeout: 30000
    };
    
    // 重试配置
    const maxRetries = this.config.maxRetries || 5;
    const retryDelay = this.config.retryDelay || 3000;
    const totalTimeout = this.config.totalTimeout || 180000; // 默认3分钟
    
    const startTime = Date.now();
    let lastError = null;
    
    for (let attempt = 0; attempt < maxRetries; attempt++) {
      // 检查总超时
      if (Date.now() - startTime > totalTimeout) {
        this.log('error', `总超时 ${totalTimeout}ms，停止重试`);
        break;
      }
      
      try {
        if (attempt > 0) {
          this.log('info', `第 ${attempt + 1} 次尝试导航...`);
        } else {
          this.log('info', `导航到: ${url}`);
        }
        
        // 尝试导航
        await this.page.goto(url, options);
        
        // 验证页面URL是否正确（避免重定向到会员中心等）
        const currentUrl = this.page.url();
        if (this.config.verifyUrl && !currentUrl.includes(this.config.verifyUrl)) {
          throw new Error(`页面跳转异常: 期望包含 "${this.config.verifyUrl}", 实际为 "${currentUrl}"`);
        }
        
        // 验证关键元素存在（确保页面加载正确）
        if (this.config.verifyElements) {
          await this.verifyElements(this.config.verifyElements);
        }
        
        // 可选的等待时间
        if (this.config.waitAfter) {
          await new Promise(resolve => setTimeout(resolve, this.config.waitAfter));
        }
        
        this.log('info', `✓ 页面加载完成${attempt > 0 ? ` (尝试 ${attempt + 1} 次)` : ''}`);
        
        return { success: true, url: currentUrl };
        
      } catch (error) {
        lastError = error;
        this.log('warn', `导航失败 (尝试 ${attempt + 1}/${maxRetries}): ${error.message}`);
        
        // 如果不是最后一次尝试，等待后重试
        if (attempt < maxRetries - 1) {
          this.log('debug', `等待 ${retryDelay}ms 后重试...`);
          await new Promise(resolve => setTimeout(resolve, retryDelay));
        }
      }
    }
    
    // 所有重试都失败
    this.log('error', `导航失败: ${lastError.message}`);
    throw lastError;
  }
  
  /**
   * 验证关键元素存在
   */
  async verifyElements(selectors) {
    this.log('debug', '验证页面元素...');
    
    for (const selector of selectors) {
      try {
        await this.page.waitForSelector(selector, { timeout: 10000 });
      } catch (error) {
        throw new Error(`页面元素验证失败: 找不到 "${selector}"`);
      }
    }
    
    this.log('debug', `✓ 已验证 ${selectors.length} 个关键元素`);
  }
}

module.exports = NavigateAction;
