/**
 * Windsurf Register - Windsurf网站注册
 * https://windsurf.com/account/register
 * 
 * 注册流程：
 * Step 1: 填写基本信息（First Name, Last Name, Email）
 * Step 2: 设置密码
 * Step 3: 邮箱验证
 * Step 4: 完善个人信息
 * ... 根据实际情况继续添加步骤
 */

const AccountDataGenerator = require('../generator');
const HumanBehavior = require('../utils/human-behavior');
const CloudflareHandler = require('../utils/cloudflare-handler');
const logger = require('../../../shared/logger');
const EmailVerificationService = require('../email-verification');
const { DEFAULT_CONFIG } = require('../config');
const CardGenerator = require('../../card-generator/generator');
const database = require('../../database');
const CapSolverAPI = require('../utils/capsolver-api');
const BrowserManager = require('../utils/browser-manager');

class WindsurfRegister {
  constructor(options = {}) {
    this.siteName = 'Windsurf';
    this.siteUrl = 'https://windsurf.com/account/register';
    this.dataGen = new AccountDataGenerator();
    this.human = new HumanBehavior();
    this.emailService = new EmailVerificationService();
    this.capsolver = new CapSolverAPI();
    
    // 浏览器管理器（支持多profile并发）
    this.browserManager = new BrowserManager({
      profileId: options.adspowerUserId || process.env.ADSPOWER_USER_ID,
      siteName: this.siteName
    });
    this.browser = null;
    this.page = null;
    this.currentStep = 0;
    this.accountData = null;
    
    // 记录注册时间和额外信息
    this.registrationTime = null;
    this.quotaInfo = null;
    this.billingInfo = null;
    this.cardInfo = null;
    
    // 定义所有步骤
    this.steps = [
      { id: 1, name: '填写基本信息', method: 'step1_fillBasicInfo' },
      { id: 2, name: '设置密码', method: 'step2_setPassword' },
      { id: 3, name: '邮箱验证', method: 'step3_emailVerification' },
      { id: 4, name: '跳过问卷', method: 'step4_skipSurvey' },
      { id: 5, name: '选择计划', method: 'step5_selectPlan' },
      { id: 6, name: '填写支付信息', method: 'step6_fillPayment' },
      { id: 7, name: '获取订阅信息', method: 'step7_getSubscriptionInfo' },
      { id: 8, name: '保存到数据库', method: 'step8_saveToDatabase' },
      { id: 9, name: '清理并关闭浏览器', method: 'step9_clearAndCloseBrowser' },
    ];
  }
  
  /**
   * 获取步骤总数
   */
  getTotalSteps() {
    return this.steps.length;
  }
  
  /**
   * 获取当前步骤信息
   */
  getCurrentStepInfo() {
    if (this.currentStep === 0) {
      return { id: 0, name: '未开始', total: this.getTotalSteps() };
    }
    const step = this.steps[this.currentStep - 1];
    return { 
      ...step, 
      current: this.currentStep, 
      total: this.getTotalSteps() 
    };
  }

  /**
   * 通用方法：等待按钮激活并点击，然后等待页面内容变化
   * @param {Object} options - 配置选项
   * @param {string} options.buttonText - 按钮文本（用于识别，如'Continue'）
   * @param {Function} options.checkContentChanged - 检查页面内容是否已变化的函数，返回Promise<boolean>
   * @param {number} options.waitButtonTimeout - 等待按钮激活的超时时间（毫秒），默认30000
   * @param {number} options.waitContentTimeout - 等待内容变化的超时时间（毫秒），默认15000
   * @param {string} options.actionName - 操作名称（用于日志）
   * @returns {Promise<boolean>} - 是否成功完成
   */
  async clickButtonAndWaitForPageChange(options) {
    const {
      buttonText = 'Continue',
      checkContentChanged,
      waitButtonTimeout = 30000,
      waitContentTimeout = 15000,
      actionName = '点击按钮'
    } = options;
    
    try {
      // 阶段1: 等待按钮变为可点击状态（enabled）
      logger.info(this.siteName, `  → 等待"${buttonText}"按钮激活...`);
      
      const buttonStartTime = Date.now();
      let buttonEnabled = false;
      
      while (Date.now() - buttonStartTime < waitButtonTimeout) {
        buttonEnabled = await this.page.evaluate((btnText) => {
          const buttons = Array.from(document.querySelectorAll('button'));
          const targetButton = buttons.find(btn => 
            btn.textContent.trim() === btnText && !btn.disabled
          );
          return !!targetButton;
        }, buttonText);
        
        if (buttonEnabled) {
          const elapsed = ((Date.now() - buttonStartTime) / 1000).toFixed(1);
          logger.success(this.siteName, `  → ✓ 按钮已激活 (耗时: ${elapsed}秒)`);
          break;
        }
        
        // 每5秒输出一次进度
        const elapsed = Date.now() - buttonStartTime;
        if (elapsed > 0 && elapsed % 5000 === 0) {
          logger.info(this.siteName, `  → 等待按钮激活中... 已用时 ${(elapsed/1000).toFixed(0)}秒`);
        }
        
        await new Promise(resolve => setTimeout(resolve, 1000));
      }
      
      if (!buttonEnabled) {
        logger.error(this.siteName, `  → ⚠️ 等待${waitButtonTimeout/1000}秒后按钮仍未激活`);
        return false;
      }
      
      // 阶段2: 点击按钮
      logger.info(this.siteName, `  → ${actionName}...`);
      await this.human.humanClick(this.page, `button:not([disabled])`);
      await this.human.randomDelay(1000, 2000);
      
      // 阶段3: 等待页面内容变化
      logger.info(this.siteName, `  → 等待页面内容变化...`);
      
      const contentStartTime = Date.now();
      let contentChanged = false;
      
      while (Date.now() - contentStartTime < waitContentTimeout) {
        contentChanged = await checkContentChanged();
        
        if (contentChanged) {
          const elapsed = ((Date.now() - contentStartTime) / 1000).toFixed(1);
          logger.success(this.siteName, `  → ✓ 页面内容已变化 (耗时: ${elapsed}秒)`);
          break;
        }
        
        await new Promise(resolve => setTimeout(resolve, 500));
      }
      
      if (!contentChanged) {
        logger.warn(this.siteName, `  → ⚠️ 等待${waitContentTimeout/1000}秒后页面内容未变化`);
        return false;
      }
      
      return true;
      
    } catch (error) {
      logger.error(this.siteName, `  → ${actionName}失败: ${error.message}`);
      return false;
    }
  }

  /**
   * 生成账号数据（干运行模式）
   */
  generateData(options = {}) {
    logger.info(this.siteName, '生成账号数据...');
    
    const account = this.dataGen.generateAccount({
      name: options.name,
      email: options.email,
      username: options.username,
      password: {
        strategy: options.passwordStrategy || 'email',
        ...options.password
      },
      includePhone: false  // Windsurf第一步不需要手机号
    });

    return account;
  }

  /**
   * 初始化浏览器
   */
  async initBrowser() {
    const result = await this.browserManager.launch();
    this.browser = result.browser;
    this.page = result.page;
    
    logger.info(this.siteName, '等待浏览器完全准备...');
    await this.human.randomDelay(2000, 3000);
  }

  /**
   * 关闭浏览器
   */
  async closeBrowser() {
    await this.browserManager.close();
  }

  /**
   * 步骤1: 填写基本信息
   */
  async step1_fillBasicInfo() {
    logger.info(this.siteName, `[步骤 1/${this.getTotalSteps()}] 填写基本信息`);
    
    const overallStartTime = Date.now();
    const overallMaxWait = 180000; // 总共最多重试3分钟
    let stepCompleted = false;
    let retryCount = 0;
    
    while (!stepCompleted && (Date.now() - overallStartTime < overallMaxWait)) {
      try {
        if (retryCount > 0) {
          logger.info(this.siteName, `  → 第 ${retryCount + 1} 次尝试...`);
        }
        
        // 打开注册页面
        logger.info(this.siteName, `打开注册页面: ${this.siteUrl}`);
        await this.page.goto(this.siteUrl, {
          waitUntil: 'networkidle2',
          timeout: 30000
        });
        
        // 模拟阅读页面（1-3秒）
        await this.human.readPage(1, 3);

        // 填写First Name（使用人类行为）
        logger.info(this.siteName, '  → 填写First Name...');
        await this.page.waitForSelector('#firstName', { timeout: 10000 });
        await this.human.humanType(this.page, '#firstName', this.accountData.firstName);

        // 填写Last Name
        logger.info(this.siteName, '  → 填写Last Name...');
        await this.page.waitForSelector('#lastName', { timeout: 10000 });
        await this.human.humanType(this.page, '#lastName', this.accountData.lastName);

        // 填写Email
        logger.info(this.siteName, '  → 填写Email...');
        await this.page.waitForSelector('#email', { timeout: 10000 });
        await this.human.humanType(this.page, '#email', this.accountData.email);

        // 勾选同意条款（如果有）
        try {
          const checkbox = await this.page.$('input[type="checkbox"]');
          if (checkbox) {
            logger.info(this.siteName, '  → 勾选同意条款...');
            await this.human.humanCheckbox(this.page, 'input[type="checkbox"]');
          }
        } catch (error) {
          logger.warn(this.siteName, '  → 未找到同意条款checkbox，跳过');
        }

        // 点击Continue按钮并等待跳转到密码页面
        const success = await this.clickButtonAndWaitForPageChange({
          buttonText: 'Continue',
          checkContentChanged: async () => {
            // 检查是否有密码输入框（表示已进入下一步）
            return await this.page.evaluate(() => {
              return !!document.querySelector('#password');
            });
          },
          waitButtonTimeout: 30000,
          waitContentTimeout: 15000,
          actionName: '点击Continue进入密码设置页面'
        });
        
        if (!success) {
          logger.warn(this.siteName, '  → ⚠️ 未能进入密码页面，将重新尝试');
          retryCount++;
          await this.human.randomDelay(2000, 3000);
          continue;
        }
        
        // 成功完成
        stepCompleted = true;
        
      } catch (error) {
        logger.warn(this.siteName, `  → 执行出错: ${error.message}，将重新尝试`);
        retryCount++;
        await this.human.randomDelay(3000, 5000);
        continue;
      }
    }
    
    if (!stepCompleted) {
      logger.error(this.siteName, `  → ✗ 步骤1失败：${retryCount + 1}次尝试后仍未成功`);
      throw new Error(`步骤1：${retryCount + 1}次尝试后仍未能完成基本信息填写`);
    }
    
    // 额外等待确保页面稳定
    await this.human.randomDelay(1000, 2000);
    
    this.currentStep = 1;
    logger.success(this.siteName, `步骤 1 完成 (共尝试 ${retryCount + 1} 次)`);
  }

  /**
   * 步骤2: 设置密码
   */
  async step2_setPassword() {
    logger.info(this.siteName, `[步骤 2/${this.getTotalSteps()}] 设置密码`);
    
    // 等待密码页面加载
    await this.human.readPage(1, 2);
    
    // 填写密码
    logger.info(this.siteName, '  → 填写密码...');
    await this.page.waitForSelector('#password', { timeout: 10000 });
    
    // 先清空密码框
    await this.page.evaluate(() => {
      const elem = document.querySelector('#password');
      if (elem) elem.value = '';
    });
    
    await this.human.humanType(this.page, '#password', this.accountData.password);
    
    // 填写确认密码
    logger.info(this.siteName, '  → 填写确认密码...');
    await this.page.waitForSelector('#passwordConfirmation', { timeout: 10000 });
    
    // 先清空确认密码框（防止有残留）
    await this.page.evaluate(() => {
      const elem = document.querySelector('#passwordConfirmation');
      if (elem) elem.value = '';
    });
    
    await this.human.humanType(this.page, '#passwordConfirmation', this.accountData.password);
    
    // 等待密码验证
    logger.info(this.siteName, '  → 等待密码验证...');
    await this.human.randomDelay(1000, 2000);
    
    // 查找并点击Continue按钮（此时会进入 Cloudflare Turnstile 验证页面）
    logger.info(this.siteName, '  → 点击Continue按钮...');
    
    try {
      // 等待按钮可点击
      await this.page.waitForFunction(
        () => {
          const button = document.querySelector('button');
          if (!button) return false;
          const text = button.textContent.trim();
          return text === 'Continue' && !button.disabled;
        },
        { timeout: 20000 }
      );
      
      logger.info(this.siteName, '  → 按钮已激活，点击进入验证页面...');
      
      // 点击按钮
      await Promise.all([
        this.page.waitForNavigation({ waitUntil: 'load', timeout: 10000 }).catch(() => {}),
        this.human.humanClick(this.page, 'button:not([disabled])')
      ]);
      
      logger.success(this.siteName, '  → 已进入 Cloudflare Turnstile 验证页面');
      
    } catch (error) {
      logger.warn(this.siteName, '  → 按钮等待超时，尝试按Enter键');
      await this.page.keyboard.press('Enter');
    }
    
    // 等待页面稳定
    await this.human.randomDelay(1000, 2000);
    
    // 等待 Cloudflare Turnstile 验证完成（手动或其他方式）
    logger.info(this.siteName, '  → 等待 Cloudflare Turnstile 验证...');
    logger.info(this.siteName, '  → 请手动完成验证或等待自动处理...');
    
    const startTime = Date.now();
    const maxWait = 120000; // 最多等待120秒
    
    // 轮询检查按钮是否激活
    while (Date.now() - startTime < maxWait) {
      const buttonEnabled = await this.page.evaluate(() => {
        const button = document.querySelector('button');
        return button && !button.disabled && button.textContent.trim() === 'Continue';
      });
      
      if (buttonEnabled) {
        const duration = ((Date.now() - startTime) / 1000).toFixed(1);
        logger.success(this.siteName, `  → ✓ Turnstile 验证完成！耗时: ${duration}秒`);
        break;
      }
      
      // 每10秒输出一次进度
      const elapsed = Date.now() - startTime;
      if (elapsed > 0 && elapsed % 10000 === 0) {
        logger.info(this.siteName, `  → 等待验证中... 已用时 ${elapsed/1000}秒`);
      }
      
      await new Promise(resolve => setTimeout(resolve, 500));
    }
    
    if (Date.now() - startTime >= maxWait) {
      logger.error(this.siteName, '  → ⚠️ 验证超时（120秒）');
      throw new Error('Turnstile 验证超时');
    }
    
    // 点击 Continue 进入邮箱验证
    logger.info(this.siteName, '  → 点击Continue进入邮箱验证...');
    await Promise.all([
      this.page.waitForNavigation({ waitUntil: 'load', timeout: 10000 }).catch(() => {}),
      this.human.humanClick(this.page, 'button:not([disabled])')
    ]);
    
    // 额外等待确保页面稳定
    await this.human.randomDelay(1000, 2000);
    
    this.currentStep = 2;
    logger.success(this.siteName, `步骤 2 完成`);
  }

  /**
   * 步骤3: 邮箱验证
   */
  async step3_emailVerification() {
    logger.info(this.siteName, `[步骤 3/${this.getTotalSteps()}] 邮箱验证`);
    
    // Cloudflare Turnstile 验证已在步骤2中完成
    logger.info(this.siteName, '  → Turnstile 验证已通过，开始邮箱验证...');
    
    try {
      // 等待验证码页面加载
      await this.human.readPage(1, 2);
      
      // 延迟2秒后再获取验证码，让邮件有足够时间到达
      logger.info(this.siteName, '  → 延迟2秒，等待邮件到达...');
      await new Promise(resolve => setTimeout(resolve, 2000));
      
      // 获取验证码（从邮箱）
      logger.info(this.siteName, '  → 正在从邮箱获取验证码...');
      logger.info(this.siteName, `  → 接收邮箱: ${this.accountData.email}`);
      logger.info(this.siteName, '  → 注意：如果长时间无响应，请检查：');
      logger.info(this.siteName, '    1. 邮件是否已发送到邮箱');
      logger.info(this.siteName, '    2. QQ邮箱IMAP配置是否正确');
      logger.info(this.siteName, '    3. 邮件是否被标记为垃圾邮件');
      
      const code = await this.emailService.getVerificationCode(
        'windsurf',
        this.accountData.email,
        120  // 增加到120秒超时
      );
      
      logger.success(this.siteName, `  → ✓ 验证码: ${code}`);
      
      // 等待验证码输入框加载
      await this.human.randomDelay(2000, 3000);
      
      // Windsurf使用6个独立的输入框，需要逐个填写
      logger.info(this.siteName, '  → 查找验证码输入框...');
      
      // 等待输入框出现
      await this.page.waitForSelector('input[type="text"]', { timeout: 10000 });
      
      // 获取所有文本输入框
      const inputs = await this.page.$$('input[type="text"]');
      logger.info(this.siteName, `  → 找到 ${inputs.length} 个输入框`);
      
      if (inputs.length >= 6 && code.length === 6) {
        // 逐个填写每一位验证码
        logger.info(this.siteName, '  → 填写6位验证码...');
        for (let i = 0; i < 6; i++) {
          const char = code[i].toUpperCase(); // 确保大写
          
          // 点击输入框获取焦点
          await inputs[i].click();
          await this.human.randomDelay(100, 200);
          
          // 输入字符
          await inputs[i].type(char);
          await this.human.randomDelay(300, 500);
          
          logger.info(this.siteName, `  → 已输入第 ${i + 1} 位: ${char}`);
        }
        logger.success(this.siteName, '  → 验证码已填写完成');
        
        // 输入完6位验证码后，页面会自动提交
        logger.info(this.siteName, '  → 等待邮箱验证完成并跳转到问卷页面...');
        logger.info(this.siteName, '  → 将持续等待直到跳转成功（无时间限制）...');
        
        // 无限等待页面跳转到 /account/onboarding?page=source
        const startTime = Date.now();
        let registrationComplete = false;
        let hasClickedButton = false;
        
        while (!registrationComplete) {
          const currentUrl = this.page.url();
          
          // 检查1: 页面是否已经跳转成功（自动跳转成功）
          if (currentUrl.includes('/account/onboarding') && currentUrl.includes('page=source')) {
            registrationComplete = true;
            const totalTime = ((Date.now() - startTime) / 1000).toFixed(1);
            logger.success(this.siteName, `  → ✓ 邮箱验证成功！已跳转到问卷页面 (耗时: ${totalTime}秒)`);
            logger.info(this.siteName, `  → 当前页面: ${currentUrl}`);
            break;
          }
          
          // 检查2: 页面按钮是否变为激活状态（自动跳转失败，需要手动点击）
          if (!hasClickedButton) {
            const buttonEnabled = await this.page.evaluate(() => {
              const buttons = Array.from(document.querySelectorAll('button'));
              const continueButton = buttons.find(btn => 
                btn.textContent.trim() === 'Continue' && !btn.disabled
              );
              return !!continueButton;
            });
            
            if (buttonEnabled) {
              const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
              logger.warn(this.siteName, `  → ⚠️ 检测到按钮重新激活 (${elapsed}秒后)`);
              logger.info(this.siteName, '  → 自动跳转可能失败，尝试手动点击按钮...');
              
              try {
                // 点击 Continue 按钮
                await this.human.humanClick(this.page, 'button:not([disabled])');
                hasClickedButton = true;
                logger.success(this.siteName, '  → ✓ 已点击按钮，继续等待跳转...');
                await this.human.randomDelay(1000, 2000);
              } catch (e) {
                logger.warn(this.siteName, `  → 点击按钮失败: ${e.message}`);
              }
            }
          }
          
          // 每5秒输出一次进度
          const elapsed = Date.now() - startTime;
          if (elapsed > 0 && elapsed % 5000 === 0) {
            logger.info(this.siteName, `  → 等待中... 已用时 ${(elapsed/1000).toFixed(0)}秒`);
          }
          
          await new Promise(resolve => setTimeout(resolve, 500));
        }
        
        // 额外等待页面稳定
        await this.human.randomDelay(2000, 3000);
        
        this.currentStep = 3;
        logger.success(this.siteName, `步骤 3 完成 - 账号创建成功`);
        
      } else {
        logger.error(this.siteName, '  → 未找到验证码输入框！');
        logger.warn(this.siteName, '  → 请手动输入验证码: ' + code);
        
        // 等待用户手动输入
        await this.human.randomDelay(30000, 30000);
        
        this.currentStep = 3;
      }
      
    } catch (error) {
      logger.error(this.siteName, `邮箱验证失败: ${error.message}`);
      throw error;
    }
  }

  /**
   * 步骤4: 跳过问卷调查
   */
  async step4_skipSurvey() {
    logger.info(this.siteName, `[步骤 4/${this.getTotalSteps()}] 跳过问卷`);
    
    const overallStartTime = Date.now();
    const overallMaxWait = 120000; // 总共最多重试2分钟
    let stepCompleted = false;
    let retryCount = 0;
    
    while (!stepCompleted && (Date.now() - overallStartTime < overallMaxWait)) {
      try {
        if (retryCount > 0) {
          logger.info(this.siteName, `  → 第 ${retryCount + 1} 次尝试...`);
        }
        
        // 等待页面加载
        await this.human.readPage(2, 3);
        
        logger.info(this.siteName, '  → 查找"Skip this step"按钮...');
        
        const startTime = Date.now();
        const maxWait = 30000; // 单次查找最多等待30秒
        let skipButton = null;
        let buttonFound = false;
        
        // 轮询查找按钮
        while (!buttonFound && (Date.now() - startTime < maxWait)) {
          try {
            // 查找所有按钮或链接
            const buttons = await this.page.$$('button, a');
            
            for (const button of buttons) {
              const text = await this.page.evaluate(el => el.textContent?.trim(), button);
              // 匹配 "Skip this step" 或 "skip"
              if (text && (text.toLowerCase().includes('skip this step') || text.toLowerCase() === 'skip')) {
                skipButton = button;
                buttonFound = true;
                logger.success(this.siteName, `  → ✓ 找到按钮: "${text}" (耗时: ${((Date.now() - startTime) / 1000).toFixed(1)}秒)`);
                break;
              }
            }
            
            if (buttonFound) {
              break;
            }
            
            // 每5秒输出一次进度
            const elapsed = Date.now() - startTime;
            if (elapsed > 0 && elapsed % 5000 === 0) {
              logger.info(this.siteName, `  → 等待按钮出现... 已用时 ${elapsed/1000}秒`);
            }
            
            // 等待2秒后继续查找
            await new Promise(resolve => setTimeout(resolve, 2000));
            
          } catch (error) {
            logger.warn(this.siteName, `  → 查找按钮时出错: ${error.message}，继续尝试...`);
            await new Promise(resolve => setTimeout(resolve, 2000));
          }
        }
        
        if (skipButton && buttonFound) {
          logger.info(this.siteName, '  → 点击"Skip this step"按钮...');
          
          // 直接点击找到的按钮元素
          await skipButton.click();
          logger.success(this.siteName, '  → ✓ 已点击按钮');
          
          // 等待页面跳转到 /account/upgrade-prompt
          logger.info(this.siteName, '  → 等待跳转到 /account/upgrade-prompt 页面...');
          
          const jumpStartTime = Date.now();
          const jumpMaxWait = 15000; // 最多等待15秒
          let jumpSuccess = false;
          
          while (Date.now() - jumpStartTime < jumpMaxWait) {
            const newUrl = this.page.url();
            
            // 必须跳转到 upgrade-prompt 页面
            if (newUrl.includes('/account/upgrade-prompt')) {
              jumpSuccess = true;
              stepCompleted = true;
              logger.success(this.siteName, `  → ✓ 成功跳转到计划选择页面`);
              logger.info(this.siteName, `  → 当前页面: ${newUrl}`);
              break;
            }
            
            await new Promise(resolve => setTimeout(resolve, 500));
          }
          
          if (!jumpSuccess) {
            const finalUrl = this.page.url();
            logger.warn(this.siteName, `  → ⚠️ 未跳转到升级页面，将重新尝试`);
            logger.warn(this.siteName, `  → 当前页面: ${finalUrl}`);
            retryCount++;
            await this.human.randomDelay(2000, 3000);
            continue; // 重新开始循环
          }
          
        } else {
          // 未找到按钮，重试
          logger.warn(this.siteName, `  → ⚠️ 未找到Skip按钮，将重新尝试`);
          retryCount++;
          await this.human.randomDelay(2000, 3000);
          continue;
        }
        
      } catch (error) {
        logger.warn(this.siteName, `  → 执行出错: ${error.message}，将重新尝试`);
        retryCount++;
        await this.human.randomDelay(2000, 3000);
        continue;
      }
    }
    
    if (!stepCompleted) {
      const currentUrl = this.page.url();
      logger.error(this.siteName, `  → ✗ 步骤4失败：${retryCount + 1}次尝试后仍未成功`);
      logger.error(this.siteName, `  → 当前页面: ${currentUrl}`);
      throw new Error(`步骤4：${retryCount + 1}次尝试后仍未成功跳转到 /account/upgrade-prompt 页面`);
    }
    
    // 额外等待页面稳定
    await this.human.randomDelay(2000, 3000);
    
    this.currentStep = 4;
    logger.success(this.siteName, `步骤 4 完成 (共尝试 ${retryCount + 1} 次)`);
  }

  /**
   * 步骤5: 选择计划
   */
  async step5_selectPlan() {
    logger.info(this.siteName, `[步骤 5/${this.getTotalSteps()}] 选择计划`);
    
    const overallStartTime = Date.now();
    const overallMaxWait = 120000; // 总共最多重试2分钟
    let stepCompleted = false;
    let retryCount = 0;
    
    while (!stepCompleted && (Date.now() - overallStartTime < overallMaxWait)) {
      try {
        if (retryCount > 0) {
          logger.info(this.siteName, `  → 第 ${retryCount + 1} 次尝试...`);
        }
        
        // 等待页面加载
        await this.human.readPage(2, 3);
        
        logger.info(this.siteName, '  → 查找计划选择按钮...');
        
        const startTime = Date.now();
        const maxWait = 30000; // 单次查找最多等待30秒
        let selectButton = null;
        let buttonFound = false;
        
        // 轮询查找按钮
        while (!buttonFound && (Date.now() - startTime < maxWait)) {
          try {
            const buttons = await this.page.$$('button, a');
            
            for (const button of buttons) {
              const text = await this.page.evaluate(el => el.textContent?.trim(), button);
              // 匹配多种可能的按钮文本
              if (text && (
                text.toLowerCase().includes('select plan') ||
                text.toLowerCase().includes('continue') ||
                text.toLowerCase().includes('get started') ||
                text.toLowerCase() === 'select'
              )) {
                selectButton = button;
                buttonFound = true;
                logger.success(this.siteName, `  → ✓ 找到按钮: "${text}" (耗时: ${((Date.now() - startTime) / 1000).toFixed(1)}秒)`);
                break;
              }
            }
            
            if (buttonFound) {
              break;
            }
            
            // 每5秒输出一次进度
            const elapsed = Date.now() - startTime;
            if (elapsed > 0 && elapsed % 5000 === 0) {
              logger.info(this.siteName, `  → 等待按钮出现... 已用时 ${elapsed/1000}秒`);
            }
            
            await new Promise(resolve => setTimeout(resolve, 2000));
            
          } catch (error) {
            logger.warn(this.siteName, `  → 查找按钮时出错: ${error.message}，继续尝试...`);
            await new Promise(resolve => setTimeout(resolve, 2000));
          }
        }
        
        if (selectButton && buttonFound) {
          logger.info(this.siteName, '  → 点击计划选择按钮...');
          
          // 直接点击找到的按钮元素
          await selectButton.click();
          logger.success(this.siteName, '  → ✓ 已点击按钮');
          
          // 等待页面跳转到 Stripe checkout
          logger.info(this.siteName, '  → 等待跳转到 Stripe 支付页面...');
          
          const jumpStartTime = Date.now();
          const jumpMaxWait = 20000; // 最多等待20秒
          let jumpSuccess = false;
          
          while (Date.now() - jumpStartTime < jumpMaxWait) {
            const newUrl = this.page.url();
            
            // 必须跳转到 Stripe checkout
            if (newUrl.includes('checkout.stripe.com') || newUrl.includes('stripe.com')) {
              jumpSuccess = true;
              stepCompleted = true;
              logger.success(this.siteName, `  → ✓ 成功跳转到 Stripe 支付页面`);
              logger.info(this.siteName, `  → 当前页面: ${newUrl}`);
              break;
            }
            
            await new Promise(resolve => setTimeout(resolve, 500));
          }
          
          if (!jumpSuccess) {
            const finalUrl = this.page.url();
            logger.warn(this.siteName, `  → ⚠️ 未跳转到支付页面，将重新尝试`);
            logger.warn(this.siteName, `  → 当前页面: ${finalUrl}`);
            retryCount++;
            await this.human.randomDelay(2000, 3000);
            continue;
          }
          
        } else {
          // 未找到按钮，重试
          logger.warn(this.siteName, `  → ⚠️ 未找到计划选择按钮，将重新尝试`);
          retryCount++;
          await this.human.randomDelay(2000, 3000);
          continue;
        }
        
      } catch (error) {
        logger.warn(this.siteName, `  → 执行出错: ${error.message}，将重新尝试`);
        retryCount++;
        await this.human.randomDelay(2000, 3000);
        continue;
      }
    }
    
    if (!stepCompleted) {
      const currentUrl = this.page.url();
      logger.error(this.siteName, `  → ✗ 步骤5失败：${retryCount + 1}次尝试后仍未成功`);
      logger.error(this.siteName, `  → 当前页面: ${currentUrl}`);
      throw new Error(`步骤5：${retryCount + 1}次尝试后仍未成功跳转到 Stripe 支付页面`);
    }
    
    // 额外等待页面稳定
    await this.human.randomDelay(2000, 3000);
    
    this.currentStep = 5;
    logger.success(this.siteName, `步骤 5 完成 (共尝试 ${retryCount + 1} 次)`);
  }

  /**
   * 彻底清空输入框（通过DOM直接操作）
   */
  async clearInputField(selector) {
    await this.page.evaluate((sel) => {
      const field = document.querySelector(sel);
      if (field) {
        field.value = '';
        field.dispatchEvent(new Event('input', { bubbles: true }));
        field.dispatchEvent(new Event('change', { bubbles: true }));
      }
    }, selector);
  }
  
  /**
   * 填写银行卡表单（每次都彻底清空后重新填写）
   */
  async fillCardForm(card, isRetry = false) {
    if (!isRetry) {
      // 首次填写：选择支付方式
      logger.info(this.siteName, '  → 选择银行卡支付方式...');
      const cardRadio = await this.page.$('input[type="radio"][value="card"]');
      if (cardRadio) {
        await cardRadio.click();
        logger.success(this.siteName, '  → ✓ 已点击银行卡选项');
        await this.human.randomDelay(3000, 5000);
        
        try {
          await this.page.waitForFunction(
            () => {
              const cardNumber = document.querySelector('#cardNumber');
              const cardExpiry = document.querySelector('#cardExpiry');
              const cardCvc = document.querySelector('#cardCvc');
              const billingName = document.querySelector('#billingName');
              return cardNumber && cardExpiry && cardCvc && billingName;
            },
            { timeout: 30000 }
          );
          logger.success(this.siteName, '  → ✓ 支付表单加载完成');
        } catch (e) {
          logger.warn(this.siteName, `  → 等待表单超时: ${e.message}`);
        }
      }
    }
    
    // ===== 填写卡号 =====
    logger.info(this.siteName, `  → 填写卡号: ${card.number}...`);
    
    // 1. 彻底清空卡号
    await this.clearInputField('#cardNumber');
    await this.human.randomDelay(300, 500);
    
    // 2. 点击并聚焦
    await this.page.click('#cardNumber');
    await this.human.randomDelay(300, 500);
    
    // 3. 再次确保清空（按多次 Backspace）
    for (let i = 0; i < 25; i++) {
      await this.page.keyboard.press('Backspace');
    }
    await this.human.randomDelay(300, 500);
    
    // 4. 填写新卡号
    await this.page.type('#cardNumber', card.number, { delay: 100 });
    await this.human.randomDelay(500, 800);
    logger.success(this.siteName, '  → ✓ 卡号已填写');
    
    // ===== 填写有效期 =====
    const expiry = `${card.month}${card.year}`;
    logger.info(this.siteName, `  → 填写有效期: ${card.month}/${card.year}...`);
    
    // 1. 彻底清空
    await this.clearInputField('#cardExpiry');
    await this.human.randomDelay(200, 300);
    
    // 2. 点击并聚焦
    await this.page.click('#cardExpiry');
    await this.human.randomDelay(200, 300);
    
    // 3. 再次确保清空
    for (let i = 0; i < 10; i++) {
      await this.page.keyboard.press('Backspace');
    }
    await this.human.randomDelay(300, 500);
    
    // 4. 填写新有效期
    await this.page.type('#cardExpiry', expiry, { delay: 100 });
    await this.human.randomDelay(500, 800);
    logger.success(this.siteName, '  → ✓ 有效期已填写');
    
    // ===== 填写CVC =====
    logger.info(this.siteName, `  → 填写CVC: ${card.cvv}...`);
    
    // 1. 彻底清空
    await this.clearInputField('#cardCvc');
    await this.human.randomDelay(200, 300);
    
    // 2. 点击并聚焦
    await this.page.click('#cardCvc');
    await this.human.randomDelay(200, 300);
    
    // 3. 再次确保清空
    for (let i = 0; i < 10; i++) {
      await this.page.keyboard.press('Backspace');
    }
    await this.human.randomDelay(300, 500);
    
    // 4. 填写新CVC
    await this.page.type('#cardCvc', card.cvv, { delay: 100 });
    await this.human.randomDelay(500, 800);
    logger.success(this.siteName, '  → ✓ CVC已填写');
    
    // ===== 首次填写：持卡人姓名和地址 =====
    if (!isRetry) {
      logger.info(this.siteName, '  → 填写持卡人姓名...');
      await this.clearInputField('#billingName');
      await this.page.click('#billingName');
      await this.human.randomDelay(300, 500);
      const fullName = `${this.accountData.firstName} ${this.accountData.lastName}`;
      await this.page.type('#billingName', fullName, { delay: 100 });
      
      logger.info(this.siteName, '  → 选择地址：中国澳门特别行政区...');
      await this.page.select('#billingCountry', 'MO');
      await this.human.randomDelay(1000, 2000);
      
      const addressFields = await this.page.$$('input[placeholder*="地址"]');
      if (addressFields.length > 0) {
        logger.info(this.siteName, '  → 填写地址信息...');
        await addressFields[0].type('Macau', { delay: 100 });
        if (addressFields[1]) {
          await this.human.randomDelay(300, 500);
          await addressFields[1].type('Macao', { delay: 100 });
        }
      }
    }
    
    logger.success(this.siteName, '  → ✓ 银行卡信息填写完成');
  }
  
  /**
   * 处理 hCaptcha 验证码（使用 CapSolver API 自动识别）
   */
  async handleHCaptcha() {
    // 获取 captcha 信息（支持 Stripe iframe 和标准 hCaptcha）
    const captchaInfo = await this.page.evaluate(() => {
      // 方式1: Stripe 的 hCaptcha iframe
      const stripeFrame = document.querySelector('iframe[src*="hcaptcha-inner"]');
      if (stripeFrame) {
        try {
          const url = new URL(stripeFrame.src);
          const hash = url.hash.substring(1);
          const params = new URLSearchParams(hash);
          const sitekey = params.get('sitekey');
          
          if (sitekey) {
            return {
              type: 'stripe-iframe',
              siteKey: sitekey,
              callback: null,
              containerId: null
            };
          }
        } catch (e) {
          // 继续尝试其他方式
        }
      }
      
      // 方式2: 标准的 hCaptcha
      const hcaptchaDiv = document.querySelector('.h-captcha');
      if (hcaptchaDiv) {
        return {
          type: 'standard',
          siteKey: hcaptchaDiv.getAttribute('data-sitekey'),
          callback: hcaptchaDiv.getAttribute('data-callback'),
          containerId: hcaptchaDiv.id || hcaptchaDiv.getAttribute('data-hcaptcha-widget-id')
        };
      }
      
      // 方式3: hcaptcha.com iframe
      const hcaptchaFrame = document.querySelector('iframe[src*="hcaptcha.com"]');
      if (hcaptchaFrame) {
        return {
          type: 'iframe',
          siteKey: null,
          callback: null,
          containerId: null
        };
      }
      
      return null;
    });
    
    if (!captchaInfo) {
      logger.info(this.siteName, '  → 未检测到 hCaptcha，跳过');
      return true;
    }
    
    logger.info(this.siteName, `  → 检测到 hCaptcha（类型: ${captchaInfo.type}）`);
    
    if (!captchaInfo.siteKey) {
      logger.warn(this.siteName, '  → 无法获取 siteKey，跳过自动识别');
      return true;
    }
    
    // 尝试使用 CapSolver API 自动识别
    if (this.capsolver.apiKey) {
      try {
        logger.info(this.siteName, '  → 使用 CapSolver API 自动识别...');
        
        logger.info(this.siteName, `  → SiteKey: ${captchaInfo.siteKey.substring(0, 20)}...`);
        if (captchaInfo.callback) {
          logger.info(this.siteName, `  → Callback: ${captchaInfo.callback}`);
        }
        
        // 2. 调用 CapSolver API 获取 token
        // 简化 URL，移除 hash 和查询参数（CapSolver 不需要完整 URL）
        const currentUrl = this.page.url();
        const simplifiedUrl = new URL(currentUrl);
        const cleanUrl = `${simplifiedUrl.protocol}//${simplifiedUrl.host}${simplifiedUrl.pathname}`;
        
        logger.info(this.siteName, `  → 原始 URL: ${currentUrl.substring(0, 80)}...`);
        logger.info(this.siteName, `  → 简化 URL: ${cleanUrl}`);
        
        const token = await this.capsolver.solveHCaptcha(captchaInfo.siteKey, cleanUrl);
        
        logger.info(this.siteName, `  → 获取到 token: ${token.substring(0, 30)}...`);
        
        // 3. 注入 token 并触发回调
        const injected = await this.page.evaluate((token, callbackName) => {
          try {
            // 方法1: 设置到隐藏的 textarea
            const textarea = document.querySelector('[name="h-captcha-response"]');
            const textareaG = document.querySelector('[name="g-recaptcha-response"]');
            if (textarea) {
              textarea.value = token;
              textarea.innerHTML = token;
            }
            if (textareaG) {
              textareaG.value = token;
              textareaG.innerHTML = token;
            }
            
            // 方法2: 使用 hCaptcha API
            if (window.hcaptcha && window.hcaptcha.setResponse) {
              window.hcaptcha.setResponse(token);
            }
            
            // 方法3: 触发自定义回调（如果有）
            if (callbackName && typeof window[callbackName] === 'function') {
              window[callbackName](token);
              return { success: true, method: 'callback', callback: callbackName };
            }
            
            // 方法4: 触发 hCaptcha 回调事件
            if (window.hcaptcha && window.hcaptcha.callback) {
              window.hcaptcha.callback(token);
              return { success: true, method: 'hcaptcha.callback' };
            }
            
            return { success: true, method: 'textarea' };
          } catch (e) {
            return { success: false, error: e.message };
          }
        }, token, captchaInfo.callback);
        
        if (!injected.success) {
          throw new Error(`Token 注入失败: ${injected.error}`);
        }
        
        logger.success(this.siteName, `  → ✓ hCaptcha 自动识别成功 (方式: ${injected.method})`);
        await this.human.randomDelay(1000, 2000);
        return true;
        
      } catch (error) {
        logger.error(this.siteName, `  → ✗ CapSolver 自动识别失败: ${error.message}`);
        logger.warn(this.siteName, '  → 将回退到手动模式');
      }
    } else {
      logger.warn(this.siteName, '  → 未配置 CapSolver API Key');
    }
    
    // 手动等待模式
    logger.warn(this.siteName, '  → 请手动完成验证码（等待120秒）...');
    const startWait = Date.now();
    
    while (Date.now() - startWait < 120000) {
      const captchaSolved = await this.page.evaluate(() => {
        const response = document.querySelector('[name="h-captcha-response"]') || 
                        document.querySelector('[name="g-recaptcha-response"]');
        return response && response.value && response.value.length > 0;
      });
      
      if (captchaSolved) {
        logger.success(this.siteName, '  → ✓ 验证码已完成');
        return true;
      }
      
      // 每10秒输出一次进度
      const elapsed = Date.now() - startWait;
      if (elapsed > 0 && elapsed % 10000 === 0) {
        logger.info(this.siteName, `  → 等待验证码... (${(elapsed/1000).toFixed(0)}秒)`);
      }
      
      await new Promise(resolve => setTimeout(resolve, 1000));
    }
    
    logger.error(this.siteName, '  → ✗ 验证码超时（120秒）');
    return false;
  }
  
  /**
   * 检查银行卡是否被拒绝
   */
  async checkCardRejected() {
    return await this.page.evaluate(() => {
      const errorContainers = [
        '.FieldError-container',
        '[class*="Error"]',
        '[class*="error"]',
        '.error-message'
      ];
      for (const selector of errorContainers) {
        const elements = document.querySelectorAll(selector);
        for (const el of elements) {
          const text = el.textContent || '';
          if (text.includes('银行卡') && text.includes('拒绝') ||
              text.includes('您的银行卡被拒绝了') ||
              text.includes('card was declined') ||
              text.includes('被拒绝') ||
              text.includes('declined')) {
            return true;
          }
        }
      }
      return false;
    });
  }
  
  /**
   * 等待支付成功
   */
  async waitForPaymentSuccess() {
    const paymentStartTime = Date.now();
    logger.info(this.siteName, '  → 等待支付处理...');
    
    while (true) {
      const currentUrl = this.page.url();
      if (!currentUrl.includes('stripe.com') && !currentUrl.includes('checkout.stripe.com')) {
        const totalTime = ((Date.now() - paymentStartTime) / 1000).toFixed(1);
        this.registrationTime = new Date();
        logger.success(this.siteName, `  → ✓ 支付成功！(耗时: ${totalTime}秒)`);
        logger.info(this.siteName, `  → 当前页面: ${currentUrl}`);
        return true;
      }
      const elapsed = Date.now() - paymentStartTime;
      if (elapsed > 0 && elapsed % 5000 === 0) {
        logger.info(this.siteName, `  → 支付处理中... (${(elapsed/1000).toFixed(0)}秒)`);
      }
      await new Promise(resolve => setTimeout(resolve, 500));
    }
  }
  
  /**
   * 提交支付（递归重试，轮询检测）
   */
  async submitPayment(retryCount = 0, maxRetries = 5) {
    if (retryCount >= maxRetries) {
      throw new Error(`银行卡被拒绝，已重试 ${maxRetries} 次`);
    }
    
    if (retryCount > 0) {
      logger.info(this.siteName, `  → 第 ${retryCount + 1} 次尝试提交...`);
    }
    
    // 点击订阅按钮
    const submitButton = await this.page.$('button[type="submit"][data-testid="hosted-payment-submit-button"]');
    if (!submitButton) {
      logger.warn(this.siteName, '  → 未找到订阅按钮');
      return false;
    }
    
    await submitButton.click();
    logger.success(this.siteName, '  → ✓ 已点击订阅按钮');
    
    // 等待一下让 Stripe 开始处理
    await this.human.randomDelay(2000, 3000);
    
    // 检查是否有验证码（只在第一次提交时检查）
    if (retryCount === 0) {
      // 等待可能的验证码弹窗/iframe 加载（最多等5秒）
      let captchaDetected = false;
      const checkStartTime = Date.now();
      const maxCheckTime = 5000; // 最多检查5秒
      let captchaCheckCount = 0;
      
      while (Date.now() - checkStartTime < maxCheckTime && !captchaDetected) {
        captchaCheckCount++;
        
        const captchaCheck = await this.page.evaluate(() => {
          // 检查多种可能的验证码 iframe 和对话框
          const stripeHCaptchaFrame = document.querySelector('iframe[src*="hcaptcha-inner"]');
          const hcaptchaFrame = document.querySelector('iframe[src*="hcaptcha.com"]');
          const hcaptchaDiv = document.querySelector('.h-captcha');
          
          // 检查是否有"还需一步即可完成"的对话框
          const modalTexts = Array.from(document.querySelectorAll('*')).map(el => el.textContent);
          const hasCaptchaModal = modalTexts.some(text => 
            text && (text.includes('还需一步') || text.includes('我是真实访问者') || text.includes('hCaptcha'))
          );
          
          return {
            hasStripeFrame: !!stripeHCaptchaFrame,
            hasHCaptchaFrame: !!hcaptchaFrame,
            hasDiv: !!hcaptchaDiv,
            hasModal: hasCaptchaModal,
            stripeFrameUrl: stripeHCaptchaFrame ? stripeHCaptchaFrame.src.substring(0, 100) : null
          };
        });
        
        // 只要检测到任一验证码元素就退出循环
        if (captchaCheck.hasStripeFrame || captchaCheck.hasHCaptchaFrame || 
            captchaCheck.hasDiv || captchaCheck.hasModal) {
          captchaDetected = true;
          logger.info(this.siteName, `  → 检测到验证码（第${captchaCheckCount}次检查，${((Date.now() - checkStartTime) / 1000).toFixed(1)}秒）`);
          if (captchaCheck.hasModal) {
            logger.info(this.siteName, `  → 检测到验证码对话框`);
          }
          if (captchaCheck.stripeFrameUrl) {
            logger.info(this.siteName, `  → Stripe hCaptcha URL: ${captchaCheck.stripeFrameUrl}...`);
          }
        } else {
          // 每500ms检查一次
          await new Promise(resolve => setTimeout(resolve, 500));
        }
      }
      
      if (captchaDetected) {
        logger.warn(this.siteName, '  → ⚠️  检测到验证码，请手动完成（等待60秒）...');
        
        // 等待用户手动完成验证码
        const waitStart = Date.now();
        const maxWait = 60000; // 等待60秒
        
        while (Date.now() - waitStart < maxWait) {
          // 检查验证码是否已完成
          const captchaCompleted = await this.page.evaluate(() => {
            // 检查验证码对话框是否消失
            const modal = document.querySelector('[role="dialog"]');
            const modalVisible = modal && window.getComputedStyle(modal).display !== 'none';
            return !modalVisible;
          });
          
          if (captchaCompleted) {
            const elapsed = ((Date.now() - waitStart) / 1000).toFixed(1);
            logger.success(this.siteName, `  → ✓ 验证码已完成（耗时${elapsed}秒）`);
            break;
          }
          
          // 每秒检查一次
          await new Promise(resolve => setTimeout(resolve, 1000));
        }
        
        if (Date.now() - waitStart >= maxWait) {
          logger.warn(this.siteName, '  → ⚠️  验证码等待超时，继续尝试...');
        }
      } else {
        logger.info(this.siteName, `  → ✓ 无验证码（检查${captchaCheckCount}次，耗时${((Date.now() - checkStartTime) / 1000).toFixed(1)}秒）`);
      }
    } else {
      logger.info(this.siteName, `  → 跳过验证码检查（重试 ${retryCount + 1}）`);
    }
    
    // 开始轮询检测：同时等待成功或失败
    logger.info(this.siteName, '  → 轮询检测支付结果...');
    const startTime = Date.now();
    const maxWait = 30000; // 最多等待30秒
    let checkCount = 0;
    
    while (Date.now() - startTime < maxWait) {
      checkCount++;
      
      // 1. 优先检查是否有错误（卡被拒绝）
      const cardRejected = await this.checkCardRejected();
      if (cardRejected) {
        logger.warn(this.siteName, `  → ⚠️ 银行卡被拒绝！(第 ${retryCount + 1}/${maxRetries} 次，检测了 ${checkCount} 次)`);
        
        // 等待错误信息完全显示（1-2秒）
        await this.human.randomDelay(1000, 2000);
        
        // 生成新卡
        logger.info(this.siteName, '  → 生成新的银行卡信息...');
        const cardGen = new CardGenerator();
        const newCard = cardGen.generate('unionpay');
        logger.info(this.siteName, `  → 新卡号: ${newCard.number}`);
        
        this.cardInfo = {
          number: newCard.number,
          month: newCard.month,
          year: newCard.year,
          cvv: newCard.cvv,
          country: 'MO'
        };
        
        // 检查页面状态，确保表单仍然可用
        try {
          await this.page.waitForFunction(
            () => {
              const cardNumber = document.querySelector('#cardNumber');
              const cardExpiry = document.querySelector('#cardExpiry');
              const cardCvc = document.querySelector('#cardCvc');
              return cardNumber && cardExpiry && cardCvc;
            },
            { timeout: 5000 }
          );
        } catch (e) {
          logger.warn(this.siteName, `  → 表单可能已刷新，等待恢复...`);
          await this.human.randomDelay(2000, 3000);
        }
        
        // 模拟人工思考（1-2秒）
        await this.human.randomDelay(1000, 2000);
        
        // 重新填写卡信息
        await this.fillCardForm(newCard, true);
        logger.success(this.siteName, '  → ✓ 已更新银行卡信息');
        
        // 填写后等待页面响应（2-3秒）
        await this.human.randomDelay(2000, 3000);
        
        // 递归重试
        return await this.submitPayment(retryCount + 1, maxRetries);
      }
      
      // 2. 检查是否支付成功（跳转离开 Stripe）
      const currentUrl = this.page.url();
      if (!currentUrl.includes('stripe.com') && !currentUrl.includes('checkout.stripe.com')) {
        const totalTime = ((Date.now() - startTime) / 1000).toFixed(1);
        this.registrationTime = new Date();
        logger.success(this.siteName, `  → ✓ 支付成功！(耗时: ${totalTime}秒，检测了 ${checkCount} 次)`);
        logger.info(this.siteName, `  → 当前页面: ${currentUrl}`);
        return true;
      }
      
      // 3. 每5秒输出一次进度
      const elapsed = Date.now() - startTime;
      if (elapsed > 0 && elapsed % 5000 === 0) {
        logger.info(this.siteName, `  → 支付处理中... (${(elapsed/1000).toFixed(0)}秒，已检测 ${checkCount} 次)`);
      }
      
      // 4. 等待500ms后继续检测
      await new Promise(resolve => setTimeout(resolve, 500));
    }
    
    // 超时：视为可能失败，生成新卡重试
    logger.warn(this.siteName, `  → ⚠️ 支付超时（${maxWait/1000}秒），共检测 ${checkCount} 次`);
    logger.info(this.siteName, `  → 将生成新卡重试 (第 ${retryCount + 1}/${maxRetries} 次)`);
    
    // 等待页面稳定（1-2秒）
    await this.human.randomDelay(1000, 2000);
    
    // 生成新卡
    const cardGen = new CardGenerator();
    const newCard = cardGen.generate('unionpay');
    logger.info(this.siteName, `  → 新卡号: ${newCard.number}`);
    
    this.cardInfo = {
      number: newCard.number,
      month: newCard.month,
      year: newCard.year,
      cvv: newCard.cvv,
      country: 'MO'
    };
    
    // 检查页面状态
    try {
      await this.page.waitForFunction(
        () => {
          const cardNumber = document.querySelector('#cardNumber');
          const cardExpiry = document.querySelector('#cardExpiry');
          const cardCvc = document.querySelector('#cardCvc');
          return cardNumber && cardExpiry && cardCvc;
        },
        { timeout: 5000 }
      );
    } catch (e) {
      logger.warn(this.siteName, `  → 表单可能已刷新，等待恢复...`);
      await this.human.randomDelay(2000, 3000);
    }
    
    // 模拟人工思考（1-2秒）
    await this.human.randomDelay(1000, 2000);
    
    // 重新填写卡信息
    await this.fillCardForm(newCard, true);
    logger.success(this.siteName, '  → ✓ 已更新银行卡信息');
    
    // 填写后等待（2-3秒）
    await this.human.randomDelay(2000, 3000);
    
    // 递归重试
    return await this.submitPayment(retryCount + 1, maxRetries);
  }
  
  /**
   * 步骤6: 填写支付信息
   */
  async step6_fillPayment() {
    logger.info(this.siteName, `[步骤 6/${this.getTotalSteps()}] 填写支付信息`);
    
    try {
      await this.human.readPage(3, 5);
      
      // 生成银行卡
      logger.info(this.siteName, '  → 生成银联卡信息...');
      const cardGen = new CardGenerator();
      const card = cardGen.generate('unionpay');
      logger.info(this.siteName, `  → 卡号: ${card.number}`);
      logger.info(this.siteName, `  → 有效期: ${card.month}/${card.year}`);
      logger.info(this.siteName, `  → CVV: ${card.cvv}`);
      
      this.cardInfo = {
        number: card.number,
        month: card.month,
        year: card.year,
        cvv: card.cvv,
        country: 'MO'
      };
      
      // 填写卡表单
      await this.fillCardForm(card);
      await this.human.randomDelay(2000, 3000);
      
      // 提交支付（递归重试）
      await this.submitPayment();
      
      this.currentStep = 6;
      logger.success(this.siteName, `步骤 6 完成`);
      
    } catch (error) {
      logger.error(this.siteName, `填写支付信息失败: ${error.message}`);
      throw error;
    }
  }

  /**
   * 步骤7: 获取订阅信息
   */
  async step7_getSubscriptionInfo() {
    logger.info(this.siteName, `[步骤 7/${this.getTotalSteps()}] 获取订阅信息`);
    
    try {
      // 0. 先关闭多余的窗口/标签页
      logger.info(this.siteName, '  → 检查并关闭多余窗口...');
      try {
        const pages = await this.browser.pages();
        logger.info(this.siteName, `  → 当前共有 ${pages.length} 个页面`);
        
        if (pages.length > 1) {
          // 保留一个 windsurf.com 的页面，关闭其他
          let validPage = null;
          const pagesToClose = [];
          
          for (const page of pages) {
            try {
              const url = page.url();
              if (url.includes('windsurf.com') && !validPage) {
                validPage = page;
                logger.info(this.siteName, `  → ✓ 保留: ${url}`);
              } else {
                pagesToClose.push(page);
                logger.info(this.siteName, `  → ✗ 关闭: ${url}`);
              }
            } catch (e) {
              pagesToClose.push(page);
            }
          }
          
          // 如果没找到 windsurf 页面，保留第一个
          if (!validPage && pages.length > 0) {
            validPage = pages[0];
            pagesToClose.shift();
          }
          
          // 关闭多余页面
          for (const page of pagesToClose) {
            try {
              await page.close();
            } catch (e) {
              // 忽略
            }
          }
          
          this.page = validPage;
          logger.success(this.siteName, `  → ✓ 已关闭 ${pagesToClose.length} 个多余页面`);
        }
      } catch (e) {
        logger.warn(this.siteName, `  → 关闭窗口失败: ${e.message}`);
      }
      
      await this.human.randomDelay(1000, 2000);
      
      // 1. 持续按ESC关闭弹窗（循环5次，确保关闭）
      logger.info(this.siteName, '  → 关闭可能存在的对话框...');
      for (let i = 0; i < 5; i++) {
        try {
          await this.page.keyboard.press('Escape');
          await new Promise(resolve => setTimeout(resolve, 300));
        } catch (e) {
          // 忽略
        }
      }
      logger.success(this.siteName, '  → ✓ 已按5次ESC键');
      
      await this.human.randomDelay(500, 1000);
      
      // 2. 跳转到订阅使用页面
      logger.info(this.siteName, '  → 跳转到订阅使用页面...');
      const currentUrl = this.page.url();
      logger.info(this.siteName, `  → 当前页面: ${currentUrl}`);
      
      await this.page.goto('https://windsurf.com/subscription/usage', { 
        waitUntil: 'networkidle2',
        timeout: 30000 
      });
      
      // 等待页面加载
      await this.human.randomDelay(3000, 5000);
      
      // 2. 获取配额信息
      logger.info(this.siteName, '  → 获取配额信息...');
      const quotaInfo = await this.page.evaluate(() => {
        // 查找包含配额的 p 标签
        const quotaElement = document.querySelector('p.caption1.font-medium.text-sk-black\\/80');
        if (!quotaElement) return null;
        
        const spans = quotaElement.querySelectorAll('span.caption3 span');
        if (spans.length >= 2) {
          const used = spans[0].textContent.trim();
          const total = spans[1].textContent.trim().replace('/', '').trim();
          return { used, total };
        }
        return null;
      });
      
      if (quotaInfo) {
        logger.success(this.siteName, `  → ✓ 配额: ${quotaInfo.used} / ${quotaInfo.total} used`);
      } else {
        logger.warn(this.siteName, '  → ⚠️ 未找到配额信息');
      }
      
      // 3. 获取下次账单日期信息
      logger.info(this.siteName, '  → 获取账单周期信息...');
      const billingInfo = await this.page.evaluate(() => {
        // 查找包含 "Next billing cycle" 的 p 标签
        const billingElement = Array.from(document.querySelectorAll('p.caption1'))
          .find(p => p.textContent.includes('Next billing cycle'));
        
        if (!billingElement) return null;
        
        // 提取天数
        const daysMatch = billingElement.textContent.match(/(\d+)\s+days?/);
        const dateMatch = billingElement.textContent.match(/on\s+([A-Za-z]+\s+\d+,\s+\d{4})/);
        
        return {
          days: daysMatch ? daysMatch[1] : null,
          date: dateMatch ? dateMatch[1] : null,
          fullText: billingElement.textContent.trim()
        };
      });
      
      if (billingInfo && billingInfo.days) {
        logger.success(this.siteName, `  → ✓ 下次账单: ${billingInfo.days} 天后 (${billingInfo.date})`);
      } else {
        logger.warn(this.siteName, '  → ⚠️ 未找到账单周期信息');
      }
      
      // 4. 简要打印关键信息
      logger.success(this.siteName, `✓ 配额: ${quotaInfo ? `${quotaInfo.used}/${quotaInfo.total}` : 'N/A'} | 下次账单: ${billingInfo?.days || 'N/A'}天后`);
      
      // 保存订阅信息供后续使用
      this.quotaInfo = quotaInfo;
      this.billingInfo = billingInfo;
      
      this.currentStep = 7;
      logger.success(this.siteName, `步骤 7 完成`);
      
    } catch (error) {
      logger.error(this.siteName, `获取订阅信息失败: ${error.message}`);
      throw error;
    }
  }

  /**
   * 步骤8: 保存到数据库
   */
  async step8_saveToDatabase() {
    logger.info(this.siteName, `[步骤 8/${this.getTotalSteps()}] 保存到数据库`);
    
    try {
      // 初始化数据库连接
      logger.info(this.siteName, '  → 连接数据库...');
      await database.initialize();
      
      // 准备账号数据
      const accountData = {
        email: this.accountData.email,
        password: this.accountData.password,
        firstName: this.accountData.firstName,
        lastName: this.accountData.lastName,
        registrationTime: this.registrationTime,
        quotaUsed: this.quotaInfo ? parseFloat(this.quotaInfo.used) : 0,
        quotaTotal: this.quotaInfo ? parseFloat(this.quotaInfo.total) : 0,
        billingDays: this.billingInfo ? parseInt(this.billingInfo.days) : null,
        billingDate: this.billingInfo ? this.billingInfo.date : null,
        paymentCardNumber: this.cardInfo ? this.cardInfo.number : null,
        paymentCountry: this.cardInfo ? this.cardInfo.country : 'MO',
        status: 'active'
      };
      
      // 保存到数据库
      logger.info(this.siteName, '  → 保存账号信息...');
      const accountRepo = database.getRepository('account');
      const accountId = await accountRepo.create(accountData);
      
      logger.success(this.siteName, `  → ✓ 账号信息已保存到数据库 (ID: ${accountId})`);
      logger.info(this.siteName, `  → 邮箱: ${accountData.email}`);
      logger.info(this.siteName, `  → 配额: ${accountData.quotaUsed} / ${accountData.quotaTotal}`);
      logger.info(this.siteName, `  → 卡号: ${accountData.paymentCardNumber}`);
      
      this.currentStep = 8;
      logger.success(this.siteName, `步骤 8 完成`);
      
    } catch (error) {
      logger.error(this.siteName, `保存到数据库失败: ${error.message}`);
      throw error;
    }
  }

  /**
   * 步骤9: 清理并关闭浏览器
   */
  async step9_clearAndCloseBrowser() {
    logger.info(this.siteName, `[步骤 9/${this.getTotalSteps()}] 清理并关闭浏览器`);
    
    try {
      await this.browserManager.clearAndClose();
      
      this.currentStep = 9;
      logger.success(this.siteName, `步骤 9 完成`);
      
    } catch (error) {
      logger.error(this.siteName, `清理并关闭浏览器失败: ${error.message}`);
      throw error;
    }
  }

  /**
   * 执行注册流程
   * @param {Object} options - 选项
   * @param {number} options.fromStep - 从第几步开始（默认1）
   * @param {number} options.toStep - 执行到第几步（默认全部）
   */
  async register(options = {}) {
    const fromStep = options.fromStep || 1;
    const toStep = options.toStep || this.getTotalSteps();
    
    try {
      // 1. 生成数据
      this.accountData = this.generateData(options);
      logger.success(this.siteName, '账号数据生成完成');
      logger.info(this.siteName, `First Name: ${this.accountData.firstName}`);
      logger.info(this.siteName, `Last Name: ${this.accountData.lastName}`);
      logger.info(this.siteName, `Email: ${this.accountData.email}`);
      logger.info(this.siteName, `Password: ${this.accountData.password}`);

      // 2. 初始化浏览器
      await this.initBrowser();

      // 3. 执行指定范围的步骤
      logger.info(this.siteName, `\n开始执行步骤 ${fromStep} 到 ${toStep} (共 ${this.getTotalSteps()} 步)\n`);
      
      for (let i = fromStep; i <= toStep && i <= this.getTotalSteps(); i++) {
        const step = this.steps[i - 1];
        
        if (typeof this[step.method] === 'function') {
          try {
            await this[step.method]();
          } catch (error) {
            logger.error(this.siteName, `步骤 ${i} 执行失败: ${error.message}`);
            throw error;
          }
        } else {
          logger.warn(this.siteName, `步骤 ${i} (${step.name}) 未实现`);
          break;
        }
      }

      const stepInfo = this.getCurrentStepInfo();
      logger.success(this.siteName, `\n✅ 所有步骤已完成 (${fromStep} 到 ${this.currentStep})`);

      return {
        success: true,
        account: this.accountData,
        completedSteps: this.currentStep,
        totalSteps: this.getTotalSteps(),
        message: `完成 ${this.currentStep}/${this.getTotalSteps()} 步`
      };

    } catch (error) {
      logger.error(this.siteName, `注册失败: ${error.message}`);
      
      // 截图保存错误状态
      if (this.page) {
        try {
          const screenshotPath = `/tmp/windsurf-error-${Date.now()}.png`;
          await this.page.screenshot({ path: screenshotPath });
          logger.info(this.siteName, `错误截图已保存: ${screenshotPath}`);
        } catch (e) {
          // 忽略截图错误
        }
      }

      // 清理浏览器缓存并关闭
      if (this.page) {
        try {
          logger.info(this.siteName, '  → 清除浏览器缓存...');
          const client = await this.page.target().createCDPSession();
          await client.send('Network.clearBrowserCookies');
          await client.send('Network.clearBrowserCache');
          await client.send('Storage.clearDataForOrigin', {
            origin: '*',
            storageTypes: 'all'
          });
          await this.page.goto('https://windsurf.com', { waitUntil: 'domcontentloaded' });
          await this.page.evaluate(() => {
            try {
              localStorage.clear();
              sessionStorage.clear();
            } catch (e) {}
          });
          await client.detach();
          logger.success(this.siteName, '  → ✓ 浏览器缓存已清除');
        } catch (e) {
          logger.warn(this.siteName, `  → 清除缓存失败: ${e.message}`);
        }
      }

      await this.closeBrowser();
      
      throw error;
    }
  }
}

module.exports = WindsurfRegister;
