const SiteAdapter = require('../core/site-adapter');
const AccountDataGenerator = require('../../../shared/libs/account-generator');
const CardGenerator = require('../../../shared/libs/card-generator');

/**
 * Windsurf 站点适配器
 */
class WindsurfAdapter extends SiteAdapter {
  constructor(context) {
    super(context, 'windsurf');
    
    // 数据生成器
    this.dataGen = new AccountDataGenerator();
    this.cardGen = new CardGenerator();
  }
  
  /**
   * 工作流执行前 - 清理状态 + 生成账户数据
   */
  async beforeWorkflow() {
    // 先调用父类清理浏览器状态
    await super.beforeWorkflow();
    
    this.log('info', '生成账户数据...');
    
    // 生成账户数据
    const accountData = this.dataGen.generateAccount();
    const cardInfo = this.cardGen.generate();
    
    // 存储到上下文
    this.context.data = {
      site: this.config.site,
      account: accountData,
      card: cardInfo
    };
    
    this.log('info', `账户邮箱: ${accountData.email}`);
    const bin = cardInfo.number.substring(0, 9);
    this.log('info', `卡号: ${cardInfo.number} (BIN: ${bin})`);
  }
  
  /**
   * 工作流执行后 - 保存结果
   */
  async afterWorkflow() {
    await super.afterWorkflow();
    
    this.log('info', '注册流程完成');
    
    // 这里可以保存到数据库
    // await this.saveToDatabase();
  }
  
  /**
   * 步骤 2.5: Cloudflare Turnstile 验证（带智能重试）
   */
  async handleTurnstile(params) {
    const { 
      timeout = 30000, 
      maxRetries = 3,
      retryStrategy = 'refresh'  // 'refresh' | 'wait' | 'restart'
    } = params;
    
    for (let retryCount = 0; retryCount <= maxRetries; retryCount++) {
      try {
        if (retryCount > 0) {
          this.log('warn', `Turnstile 超时，执行重试策略: ${retryStrategy} (${retryCount}/${maxRetries})...`);
          
          // 根据策略执行不同的重试行为
          await this.executeRetryStrategy(retryStrategy, retryCount);
        }
        
        this.log('info', 'Cloudflare Turnstile 人机验证');
        
        // 等待 Turnstile 验证框出现
        await new Promise(resolve => setTimeout(resolve, 2000));
        
        // 检查是否有 Turnstile
        const hasTurnstile = await this.page.evaluate(() => {
          return !!document.querySelector('iframe[src*="challenges.cloudflare.com"]') ||
                 !!document.querySelector('.cf-turnstile') ||
                 document.body.textContent.includes('Please verify that you are human');
        });
        
        if (hasTurnstile) {
          this.log('info', '检测到 Turnstile 验证，等待自动完成...');
          
          // 等待验证通过（检查按钮是否启用或页面是否变化）
          const startTime = Date.now();
          
          while (Date.now() - startTime < timeout) {
            const isPassed = await this.page.evaluate(() => {
              // 检查是否有成功标记
              const successMark = document.querySelector('svg[data-status="success"]') ||
                                document.querySelector('[aria-label*="success"]') ||
                                document.querySelector('.cf-turnstile-success');
              
              // 或者检查 Continue 按钮是否启用
              const continueBtn = Array.from(document.querySelectorAll('button')).find(btn => 
                btn.textContent.trim() === 'Continue'
              );
              const btnEnabled = continueBtn && !continueBtn.disabled;
              
              return !!successMark || btnEnabled;
            });
            
            if (isPassed) {
              this.log('success', '✓ Turnstile 验证通过');
              
              // 点击 Continue 按钮
              const continueBtn = await this.page.evaluateHandle(() => {
                return Array.from(document.querySelectorAll('button')).find(btn => 
                  btn.textContent.trim() === 'Continue'
                );
              });
              
              if (continueBtn) {
                await continueBtn.asElement().click();
                this.log('info', '已点击 Continue 按钮');
                await new Promise(resolve => setTimeout(resolve, 2000));
              }
              
              return { success: true };
            }
            
            await new Promise(resolve => setTimeout(resolve, 500));
          }
          
          // 超时了，如果还有重试次数就继续循环
          if (retryCount < maxRetries) {
            this.log('warn', `Turnstile 验证超时（${timeout}ms）`);
            continue; // 进入下一次重试
          } else {
            throw new Error('Turnstile 验证超时，已达最大重试次数');
          }
          
        } else {
          this.log('info', '未检测到 Turnstile，跳过');
          return { success: true, skipped: true };
        }
        
      } catch (error) {
        if (retryCount >= maxRetries) {
          this.log('error', `Turnstile 处理最终失败: ${error.message}`);
          // Turnstile 是可选的，失败也继续（但记录错误）
          return { success: true, error: error.message, failed: true };
        }
        // 否则继续重试
      }
    }
  }
  
  /**
   * 重启后的恢复钩子（Windsurf 特定实现）
   * Windsurf 刷新后回到第一步，返回需要重新执行的 YAML 步骤
   * @returns {Array} 需要重新执行的步骤名称
   */
  async onRestart(options) {
    this.log('info', 'Windsurf 刷新后回到第一步，重新执行前面的步骤...');
    
    // 返回步骤名称，框架会自动从 YAML 查找并执行
    return [
      '填写基本信息',
      '勾选同意条款',
      '点击 Continue (基本信息)',
      '等待密码页面',
      '设置密码',
      '提交密码'
    ];
  }
  
  /**
   * 步骤 3: 邮箱验证
   */
  async handleEmailVerification(params) {
    const { timeout = 120000 } = params;
    
    this.log('info', '开始邮箱验证');
    
    // 导入邮箱服务
    const EmailVerificationService = require('../../account-register/email-verification');
    if (!this.emailService) {
      this.emailService = new EmailVerificationService();
    }
    
    try {
      // 等待2秒让邮件到达
      await new Promise(resolve => setTimeout(resolve, 2000));
      
      // 获取验证码
      this.log('info', `从邮箱获取验证码: ${this.context.data.account.email}`);
      const code = await this.emailService.getVerificationCode(
        'windsurf',
        this.context.data.account.email,
        timeout / 1000
      );
      
      this.log('success', `✓ 验证码: ${code}`);
      
      // 等待输入框出现
      await this.page.waitForSelector('input[type="text"]', { timeout: 10000 });
      
      // 获取所有输入框
      const inputs = await this.page.$$('input[type="text"]');
      this.log('info', `找到 ${inputs.length} 个输入框`);
      
      if (inputs.length >= 6 && code.length === 6) {
        // 填写6位验证码
        this.log('info', '填写6位验证码...');
        for (let i = 0; i < 6; i++) {
          await inputs[i].click();
          await new Promise(resolve => setTimeout(resolve, 100));
          await inputs[i].type(code[i].toUpperCase());
          await new Promise(resolve => setTimeout(resolve, 300));
        }
        
        this.log('success', '✓ 验证码已填写');
        
        // 等待跳转到问卷页面
        this.log('info', '等待页面跳转...');
        const startTime = Date.now();
        
        while (Date.now() - startTime < 60000) {
          const currentUrl = this.page.url();
          
          if (currentUrl.includes('/account/onboarding') && currentUrl.includes('page=source')) {
            this.log('success', '✓ 邮箱验证成功');
            return { success: true };
          }
          
          await new Promise(resolve => setTimeout(resolve, 500));
        }
        
        throw new Error('等待页面跳转超时');
      } else {
        throw new Error('输入框数量不正确');
      }
      
    } catch (error) {
      this.log('error', `邮箱验证失败: ${error.message}`);
      throw error;
    }
  }
  
  /**
   * 重新生成银行卡（用于重试）
   */
  regenerateCard() {
    const newCard = this.cardGen.generate();
    this.context.data.card = newCard;
    const bin = newCard.number.substring(0, 9);
    this.log('info', `重新生成卡号: ${newCard.number} (BIN: ${bin})`);
    return newCard;
  }
  
  /**
   * 验证订阅按钮点击是否生效
   */
  async verifySubmitClick() {
    this.log('info', '验证订阅按钮点击是否生效...');
    
    await new Promise(resolve => setTimeout(resolve, 1000));
    
    const buttonState = await this.page.evaluate(() => {
      const button = document.querySelector('button[data-testid="hosted-payment-submit-button"]') ||
                    document.querySelector('button[type="submit"]');
      
      if (!button) {
        return { found: false };
      }
      
      const text = button.textContent || button.innerText || '';
      const isDisabled = button.disabled || button.getAttribute('aria-disabled') === 'true';
      const isProcessing = text.includes('处理') || text.includes('Processing') || 
                          text.includes('正在') || text.includes('Loading');
      
      return {
        found: true,
        text: text.trim(),
        disabled: isDisabled,
        processing: isProcessing,
        changed: isDisabled || isProcessing
      };
    });
    
    if (!buttonState.found) {
      throw new Error('订阅按钮已消失（可能页面已跳转）');
    }
    
    if (buttonState.changed) {
      this.log('success', `✓ 按钮状态已变化: "${buttonState.text}" (disabled: ${buttonState.disabled})`);
      return { success: true, clicked: true };
    } else {
      this.log('error', `✗ 按钮状态未变化: "${buttonState.text}" - 点击可能未生效！`);
      throw new Error(`订阅按钮点击未生效，按钮文本: "${buttonState.text}"`);
    }
  }
  
  /**
   * 处理 hCaptcha（等待60秒让用户手动完成）
   */
  async handleHCaptcha(params = {}) {
    const waitTime = 60000; // 固定等待60秒
    
    this.log('warn', '⚠️  等待手动完成 hCaptcha 验证...');
    this.log('info', `⏱️  等待时间：${waitTime / 1000} 秒`);
    
    // 纯等待60秒，不做任何检测
    await new Promise(resolve => setTimeout(resolve, waitTime));
    
    this.log('success', '✓ 等待完成，继续执行');
    return { success: true };
  }
  
  /**
   * 提交并验证支付（供 retryBlock 使用）
   */
  async submitAndVerifyPayment(params = {}) {
    this.log('info', '提交支付...');
    
    // 查找提交按钮
    const submitButton = await this.page.evaluateHandle(() => {
      const buttons = Array.from(document.querySelectorAll('button'));
      return buttons.find(btn => {
        const text = btn.textContent?.trim();
        return text && (text.includes('订阅') || text.includes('Subscribe') || 
                       text.includes('支付') || text.includes('Pay'));
      });
    });
    
    if (!submitButton) {
      throw new Error('未找到提交按钮');
    }
    
    await submitButton.asElement().click();
    this.log('info', '已点击提交按钮');
    
    // 等待支付结果
    await new Promise(resolve => setTimeout(resolve, 3000));
    
    // 检测支付结果
    const result = await this.checkPaymentResult();
    
    if (result.success) {
      this.log('success', '✓ 支付成功');
      return { success: true };
    }
    
    if (result.cardDeclined) {
      // 抛出异常，触发 retryBlock 重试
      throw new Error(`银行卡被拒绝: ${result.message}`);
    }
    
    // 默认认为成功
    this.log('info', '支付状态未知，视为成功');
    return { success: true };
  }
  
  /**
   * 检测支付结果
   */
  async checkPaymentResult() {
    const currentUrl = this.page.url();
    
    // 检查是否跳转成功（离开 Stripe）
    if (!currentUrl.includes('stripe.com') && !currentUrl.includes('checkout.stripe.com')) {
      return { success: true, message: '页面已跳转' };
    }
    
    // 检查页面上的错误信息
    const errorInfo = await this.page.evaluate(() => {
      // 查找错误消息
      const errorTexts = [
        'card was declined',
        '卡片被拒绝',
        'Your card was declined',
        'declined',
        'insufficient funds',
        '余额不足'
      ];
      
      const bodyText = document.body.textContent || '';
      
      for (const errorText of errorTexts) {
        if (bodyText.toLowerCase().includes(errorText.toLowerCase())) {
          return {
            cardDeclined: true,
            message: errorText
          };
        }
      }
      
      return { cardDeclined: false };
    });
    
    if (errorInfo.cardDeclined) {
      return { 
        success: false, 
        cardDeclined: true, 
        message: errorInfo.message 
      };
    }
    
    // 默认认为成功
    return { success: true };
  }
  
  /**
   * 处理订阅数据 - 从 extract action 提取的原始数据中构造结构化对象
   */
  async processSubscriptionData(params) {
    this.log('info', '处理订阅数据...');
    
    try {
      // 处理配额信息（从多个 span 中提取）
      const quotaRaw = this.context.data.quotaRaw;
      let quotaInfo = null;
      
      if (quotaRaw && Array.isArray(quotaRaw) && quotaRaw.length >= 2) {
        quotaInfo = {
          used: quotaRaw[0].trim(),
          total: quotaRaw[1].trim().replace('/', '').trim()
        };
        this.context.data.quotaInfo = quotaInfo;
        this.log('success', `✓ 配额: ${quotaInfo.used} / ${quotaInfo.total} used`);
      } else {
        this.log('warn', '未找到配额信息');
      }
      
      // billingInfo 已由 extract action 处理好
      const billingInfo = this.context.data.billingInfo;
      if (billingInfo && billingInfo.days) {
        this.log('success', `✓ 下次账单: ${billingInfo.days} 天后 (${billingInfo.date || 'N/A'})`);
      } else {
        this.log('warn', '未找到账单周期信息');
      }
      
      // 打印汇总信息
      this.log('success', `✓ 配额: ${quotaInfo ? `${quotaInfo.used}/${quotaInfo.total}` : 'N/A'} | 下次账单: ${billingInfo?.days || 'N/A'}天后`);
      
      return { success: true };
      
    } catch (error) {
      this.log('error', `处理订阅数据失败: ${error.message}`);
      // 不抛出异常，允许流程继续
      return { success: true, error: error.message };
    }
  }
  
  /**
   * 步骤 8: 保存到数据库
   */
  async saveToDatabase(params) {
    this.log('info', '保存到数据库');
    
    try {
      // 导入数据库模块
      const database = require('../../../shared/libs/database');
      
      // 初始化数据库连接
      this.log('info', '连接数据库...');
      await database.initialize();
      
      const account = this.context.data.account;
      const card = this.context.data.card;
      const quotaInfo = this.context.data.quotaInfo;
      const billingInfo = this.context.data.billingInfo;
      
      // 准备账号数据
      const accountData = {
        email: account.email,
        password: account.password,
        firstName: account.firstName,
        lastName: account.lastName,
        registrationTime: new Date(),
        quotaUsed: quotaInfo ? parseFloat(quotaInfo.used) : 0,
        quotaTotal: quotaInfo ? parseFloat(quotaInfo.total) : 0,
        billingDays: billingInfo ? parseInt(billingInfo.days) : null,
        billingDate: billingInfo ? billingInfo.date : null,
        paymentCardNumber: card ? card.number : null,
        paymentCountry: card ? card.country : 'MO',
        status: 'active',
        isOnSale: false
      };
      
      // 保存到数据库
      this.log('info', '保存账号信息...');
      const accountRepo = database.getRepository('account');
      const accountId = await accountRepo.create(accountData);
      
      this.log('success', `✓ 账号信息已保存到数据库 (ID: ${accountId})`);
      this.log('info', `  → 邮箱: ${accountData.email}`);
      this.log('info', `  → 配额: ${accountData.quotaUsed} / ${accountData.quotaTotal}`);
      this.log('info', `  → 卡号: ${accountData.paymentCardNumber}`);
      
      return { success: true, accountId };
      
    } catch (error) {
      this.log('error', `保存到数据库失败: ${error.message}`);
      // 数据库保存失败不影响注册流程
      return { success: true, error: error.message };
    }
  }
}

module.exports = WindsurfAdapter;
