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

/**
 * 等待动作
 */
class WaitAction extends BaseAction {
  async execute() {
    const type = this.config.type || 'delay';
    
    switch (type) {
      case 'delay':
        return await this.waitDelay();
      
      case 'element':
        return await this.waitForElement();
      
      case 'navigation':
        return await this.waitForNavigation();
      
      case 'condition':
        return await this.waitForCondition();
      
      case 'url':
        return await this.waitForUrl();
      
      default:
        throw new Error(`未知的等待类型: ${type}`);
    }
  }
  
  /**
   * 固定延迟
   */
  async waitDelay() {
    const duration = this.config.duration || this.config.ms || 1000;
    this.log('debug', `等待 ${duration}ms`);
    await new Promise(resolve => setTimeout(resolve, duration));
    return { success: true };
  }
  
  /**
   * 等待元素出现
   */
  async waitForElement() {
    const selector = this.config.selector || this.config.find;
    const timeout = this.config.timeout || 10000;
    
    if (!selector) {
      throw new Error('缺少选择器配置');
    }
    
    this.log('debug', '等待元素出现');
    
    const smartSelector = SmartSelector.fromConfig(selector, this.page);
    const element = await smartSelector.find(timeout);
    
    if (!element) {
      throw new Error(`元素未出现（超时 ${timeout}ms）`);
    }
    
    this.log('debug', '✓ 元素已出现');
    return { success: true };
  }
  
  /**
   * 等待页面导航
   */
  async waitForNavigation() {
    const timeout = this.config.timeout || 30000;
    
    this.log('debug', '等待页面导航');
    
    await this.page.waitForNavigation({
      waitUntil: this.config.waitUntil || 'networkidle2',
      timeout
    });
    
    this.log('debug', '✓ 导航完成');
    return { success: true };
  }
  
  /**
   * 等待自定义条件
   */
  async waitForCondition() {
    const handler = this.config.handler;
    const timeout = this.config.timeout || 10000;
    
    if (!handler) {
      throw new Error('缺少条件处理函数');
    }
    
    this.log('debug', '等待自定义条件');
    
    const startTime = Date.now();
    
    while (Date.now() - startTime < timeout) {
      // 调用适配器中的条件判断函数
      if (typeof this.context.adapter[handler] === 'function') {
        const result = await this.context.adapter[handler]();
        if (result) {
          this.log('debug', '✓ 条件满足');
          return { success: true };
        }
      }
      
      await new Promise(resolve => setTimeout(resolve, 500));
    }
    
    throw new Error('条件未满足（超时）');
  }
  
  /**
   * 等待 URL 变化
   */
  async waitForUrl() {
    const timeout = this.config.timeout || 20000;
    const urlContains = this.config.urlContains;
    const urlNotContains = this.config.urlNotContains;
    const urlEquals = this.config.urlEquals;
    
    if (!urlContains && !urlNotContains && !urlEquals) {
      throw new Error('需要指定 urlContains、urlNotContains 或 urlEquals');
    }
    
    this.log('debug', '等待 URL 变化');
    
    const startTime = Date.now();
    
    while (Date.now() - startTime < timeout) {
      const currentUrl = this.page.url();
      
      let matched = false;
      
      if (urlContains) {
        matched = currentUrl.includes(urlContains);
        if (matched) {
          this.log('debug', `✓ URL 包含 "${urlContains}": ${currentUrl}`);
          return { success: true };
        }
      }
      
      if (urlNotContains) {
        matched = !currentUrl.includes(urlNotContains);
        if (matched) {
          this.log('debug', `✓ URL 不包含 "${urlNotContains}": ${currentUrl}`);
          return { success: true };
        }
      }
      
      if (urlEquals) {
        matched = currentUrl === urlEquals;
        if (matched) {
          this.log('debug', `✓ URL 等于 "${urlEquals}"`);
          return { success: true };
        }
      }
      
      await new Promise(resolve => setTimeout(resolve, 500));
    }
    
    const finalUrl = this.page.url();
    throw new Error(`URL 条件未满足（超时），当前 URL: ${finalUrl}`);
  }
}

module.exports = WaitAction;
