/**
 * Cloudflare Turnstile 验证处理器
 * 通用的Cloudflare人机验证处理，支持全自动和半自动模式
 */

const logger = require('../../logger');

class CloudflareHandler {
  /**
   * @param {Page} page - Puppeteer page对象
   * @param {HumanBehavior} human - 人类行为模拟对象
   * @param {string} siteName - 网站名称（用于日志）
   * @param {string} mode - 验证模式: 'auto' 或 'manual' (默认 'manual')
   * @param {Function} customCheck - 自定义检测函数，返回Promise<boolean>，检测验证是否完成
   */
  constructor(page, human, siteName, mode = 'manual', customCheck = null) {
    this.page = page;
    this.human = human;
    this.siteName = siteName;
    this.mode = mode; // 'auto' 或 'manual'
    this.customCheck = customCheck; // 自定义检测函数
  }

  /**
   * 处理Cloudflare Turnstile验证
   * @returns {Promise<string>} 'passed' | 'failed' | 'manual'
   */
  async handle() {
    logger.info(this.siteName, '[Cloudflare] 检查人机验证...');
    
    await this.human.randomDelay(2000, 3000);
    
    // 检查页面内容，判断是否有验证
    const pageText = await this.page.evaluate(() => document.body.textContent || '');
    
    if (!pageText.includes('verify') && !pageText.includes('human')) {
      logger.success(this.siteName, '[Cloudflare] 无验证，自动通过');
      return 'passed';
    }
    
    logger.info(this.siteName, '[Cloudflare] 发现验证页面');
    
    // 情况1：等待自动验证（某些情况下会自动通过）
    logger.info(this.siteName, '[Cloudflare] 等待自动验证（5秒）...');
    await this.human.randomDelay(5000, 6000);
    
    const afterWait = await this.page.evaluate(() => document.body.textContent || '');
    if (!afterWait.includes('verify') && !afterWait.includes('human')) {
      logger.success(this.siteName, '[Cloudflare] 自动验证通过');
      return 'passed';
    }
    
    // 情况2：需要点击验证框
    if (this.mode === 'auto') {
      return await this.autoHandle();
    } else {
      return await this.manualHandle();
    }
  }

  /**
   * 自动处理模式（实验性）
   */
  async autoHandle() {
    logger.info(this.siteName, '[Cloudflare] 自动模式：尝试点击验证框...');
    
    try {
      // 查找Turnstile iframe
      const frames = await this.page.frames();
      let turnstileFrame = null;
      
      for (const frame of frames) {
        const url = frame.url();
        if (url.includes('challenges.cloudflare.com') || url.includes('turnstile')) {
          turnstileFrame = frame;
          logger.success(this.siteName, `[Cloudflare] 找到iframe: ${url.substring(0, 80)}...`);
          break;
        }
      }
      
      if (!turnstileFrame) {
        logger.warn(this.siteName, '[Cloudflare] 未找到Turnstile iframe');
        return 'failed';
      }
      
      // 等待iframe加载
      await turnstileFrame.waitForSelector('body', { timeout: 5000 });
      await this.human.randomDelay(8000, 8000);
      
      // 查找并点击checkbox
      const checkboxElement = await turnstileFrame.$('label.cb-lb');
      if (!checkboxElement) {
        logger.error(this.siteName, '[Cloudflare] 未找到验证框');
        return 'failed';
      }
      
      // 使用真实鼠标点击
      const box = await checkboxElement.boundingBox();
      if (box) {
        const clickX = box.x + box.width / 2;
        const clickY = box.y + box.height / 2;
        
        await this.page.mouse.move(clickX - 50, clickY - 50);
        await this.human.randomDelay(100, 300);
        await this.page.mouse.move(clickX, clickY, { steps: 10 });
        await this.human.randomDelay(200, 400);
        await this.page.mouse.click(clickX, clickY);
        
        logger.success(this.siteName, '[Cloudflare] 已点击验证框');
      }
      
      // 等待验证处理
      await this.human.randomDelay(8000, 12000);
      
      // 检查是否通过
      const finalCheck = await this.page.evaluate(() => document.body.textContent || '');
      if (!finalCheck.includes('verify') && !finalCheck.includes('human')) {
        logger.success(this.siteName, '[Cloudflare] ✓ 验证通过');
        return 'passed';
      }
      
      return 'failed';
    } catch (error) {
      logger.error(this.siteName, `[Cloudflare] 自动处理失败: ${error.message}`);
      return 'failed';
    }
  }

  /**
   * 半自动处理模式（推荐）
   */
  async manualHandle() {
    logger.info(this.siteName, '[Cloudflare] 半自动模式：等待用户手动点击...');
    
    try {
      // 查找Turnstile iframe
      const frames = await this.page.frames();
      let turnstileFrame = null;
      
      for (const frame of frames) {
        const url = frame.url();
        if (url.includes('challenges.cloudflare.com') || url.includes('turnstile')) {
          turnstileFrame = frame;
          break;
        }
      }
      
      if (turnstileFrame) {
        await turnstileFrame.waitForSelector('body', { timeout: 5000 });
      }
      
      // 显示提示
      logger.warn(this.siteName, '='.repeat(60));
      logger.warn(this.siteName, '[Cloudflare] 🖱️  请手动点击验证框！');
      logger.warn(this.siteName, '[Cloudflare] 程序将自动检测验证完成（超时10分钟）...');
      logger.warn(this.siteName, '='.repeat(60));
      
      // 轮询检查验证是否完成（最多10分钟）
      let verified = false;
      let attempts = 0;
      const maxAttempts = 600; // 10分钟 = 600秒
      
      while (!verified && attempts < maxAttempts) {
        attempts++;
        await this.human.randomDelay(1000, 1000);
        
        // 方法1: 检查页面内容
        const pageText = await this.page.evaluate(() => document.body.textContent || '');
        const hasVerifyText = pageText.includes('verify') || pageText.includes('human');
        
        // 方法2: 检查URL是否改变
        const currentUrl = this.page.url();
        const urlChanged = !currentUrl.includes('register');
        
        // 方法3: 检查iframe内成功标志
        let iframeSuccess = false;
        if (turnstileFrame) {
          try {
            iframeSuccess = await turnstileFrame.evaluate(() => {
              const successDiv = document.querySelector('#success');
              return successDiv && successDiv.style.display !== 'none';
            });
          } catch (e) {
            // iframe可能已消失
          }
        }
        
        // 方法4: 自定义检测（由网站自己定义）
        let customCheckPassed = false;
        if (this.customCheck) {
          try {
            customCheckPassed = await this.customCheck();
          } catch (e) {
            // 忽略错误
          }
        }
        
        // 每15秒输出一次状态
        if (attempts % 15 === 0) {
          const minutes = Math.floor(attempts / 60);
          const seconds = attempts % 60;
          logger.info(this.siteName, `[Cloudflare] 等待中... (${minutes}分${seconds}秒/${Math.floor(maxAttempts/60)}分钟) - custom=${customCheckPassed}, iframe=${iframeSuccess}`);
        }
        
        // 判断验证完成
        if (customCheckPassed || iframeSuccess || (!hasVerifyText && attempts > 3) || urlChanged) {
          verified = true;
          logger.success(this.siteName, '[Cloudflare] ✓✓✓ 检测到验证完成！');
          break;
        }
      }
      
      if (!verified) {
        logger.error(this.siteName, '[Cloudflare] ✗ 10分钟超时');
        return 'failed';
      }
      
      // 验证完成后等待页面稳定
      await this.human.randomDelay(2000, 3000);
      return 'passed';
      
    } catch (error) {
      logger.error(this.siteName, `[Cloudflare] 半自动处理失败: ${error.message}`);
      return 'failed';
    }
  }
}

module.exports = CloudflareHandler;
