import BaseAction from '../core/BaseAction';
import SmartSelector from '../../../core/selectors/SmartSelector';
import { ConfigurationError, ElementNotFoundError, TimeoutError } from '../../../core/errors/CustomErrors';

/**
 * 填充表单动作
 */
class FillFormAction extends BaseAction {
  async execute(): Promise<any> {
    const fields = this.config.fields;
    const humanLike = this.config.humanLike !== false; // 默认使用人类行为
    
    if (!fields || typeof fields !== 'object') {
      throw new ConfigurationError(
        '表单字段配置无效',
        'fields',
        { provided: typeof fields, config: this.config }
      );
    }
    
    this.log('info', `填写表单，共 ${Object.keys(fields).length} 个字段`);
    
    // 填写每个字段
    const fieldEntries = Object.entries(fields);
    for (let i = 0; i < fieldEntries.length; i++) {
      const [key, fieldConfig] = fieldEntries[i];
      await this.fillField(key, fieldConfig, humanLike);
      
      // 字段间的停顿（不是最后一个字段时）
      if (i < fieldEntries.length - 1) {
        await this.pauseDelay();
      }
    }
    
    this.log('info', '✓ 表单填写完成');
    
    // 模拟人类填写后的思考时间
    await this.thinkDelay();
    
    return { success: true };
  }
  
  /**
   * 填写单个字段
   */
  async fillField(key: string, fieldConfig: any, humanLike: boolean): Promise<void> {
    let selector, value, fieldType;
    
    // 支持三种配置格式
    if (typeof fieldConfig === 'object' && fieldConfig.find) {
      // 完整配置: { find: [...], value: "...", type: "..." }
      selector = fieldConfig.find;
      value = this.replaceVariables(fieldConfig.value);
      fieldType = fieldConfig.type;
    } else if (typeof fieldConfig === 'string') {
      // 超简化配置: { fieldName: "value" }
      // 自动推断选择器
      selector = [
        { css: `#${key}` },
        { name: key },
        { css: `input[name="${key}"]` },
        { css: `select[name="${key}"]` },
        { css: `textarea[name="${key}"]` }
      ];
      value = this.replaceVariables(fieldConfig);
      fieldType = 'input';
    } else {
      // 简化配置: { selector: value }（已有的逻辑）
      selector = key;
      value = this.replaceVariables(fieldConfig);
      fieldType = 'input';
    }
    
    // 查找元素（自动等待出现）
    const smartSelector = SmartSelector.fromConfig(selector, this.page);
    const element = await smartSelector.find(10000);
    
    if (!element) {
      throw new ElementNotFoundError(selector, {
        action: 'fillForm',
        field: key,
        value
      });
    }
    
    this.log('debug', `  → 填写字段: ${key}`);
    
    // 检查字段类型（已在上面定义）
    if (!fieldType) {
      fieldType = fieldConfig.type || 'input';
    }
    
    if (fieldType === 'select') {
      // 下拉框选择（需要 CSS 选择器）
      const cssSelector = selector.css || selector[0]?.css;
      if (!cssSelector) {
        throw new ConfigurationError(
          `select 类型字段需要 css 选择器`,
          'selector',
          { field: key, selector, fieldType }
        );
      }
      await this.page.select(cssSelector, value);
      this.log('debug', `  → 已选择: ${value}`);
      return;
    }
    
    // 普通输入框
    // 清空字段（增强清空逻辑，支持 Stripe 等复杂表单）
    await element.click({ clickCount: 3 });
    await new Promise(resolve => setTimeout(resolve, 100));
    
    // 多次 Backspace 确保彻底清空
    const clearTimes = fieldConfig.clearTimes || this.config.clearTimes || 25;
    for (let i = 0; i < clearTimes; i++) {
      await this.page.keyboard.press('Backspace');
    }
    await new Promise(resolve => setTimeout(resolve, 200));
    
    if (humanLike) {
      // 人类行为模拟
      await this.typeHumanLike(element, value);
    } else {
      // 直接输入
      await element.type(value, { delay: 100 });
    }
    
    // 触发事件
    await this.page.evaluate((el: any) => {
      el.dispatchEvent(new Event('input', { bubbles: true }));
      el.dispatchEvent(new Event('change', { bubbles: true }));
    }, element);
  }
  
  /**
   * 模拟人类输入（更慢、更真实）
   */
  async typeHumanLike(element: any, text: string): Promise<void> {
    for (let i = 0; i < text.length; i++) {
      const char = text[i];
      
      // 每个字符延迟 100-250ms（更慢）
      await element.type(char, {
        delay: Math.random() * 150 + 100
      });
      
      // 每输入3-5个字符，随机停顿一下（模拟思考或调整手指）
      if (i > 0 && i % (Math.floor(Math.random() * 3) + 3) === 0) {
        await new Promise(resolve => setTimeout(resolve, Math.random() * 800 + 300));
      }
    }
    
    // 输入完成后，短暂停顿（模拟检查输入）
    await new Promise(resolve => setTimeout(resolve, Math.random() * 500 + 300));
  }
  
  /**
   * 提交表单
   */
  async submitForm(submitConfig: any): Promise<void> {
    this.log('info', '  → 提交表单');
    
    const selector = submitConfig.find || submitConfig;
    const smartSelector = SmartSelector.fromConfig(selector, this.page);
    const button = await smartSelector.find(10000);
    
    if (!button) {
      throw new ElementNotFoundError(selector, {
        action: 'fillForm',
        operation: 'submitForm'
      });
    }
    
    // 等待按钮可点击
    await this.waitForButtonEnabled(button);
    
    // 点击
    await button.click();
    
    // 等待提交后的延迟
    if (submitConfig.waitAfter) {
      await new Promise(resolve => setTimeout(resolve, submitConfig.waitAfter));
    }
  }
  
  /**
   * 等待按钮启用
   */
  async waitForButtonEnabled(button: any, timeout: number = 30000): Promise<void> {
    const startTime = Date.now();
    
    while (Date.now() - startTime < timeout) {
      const isEnabled = await this.page.evaluate((btn: any) => {
        return !btn.disabled;
      }, button);
      
      if (isEnabled) {
        return;
      }
      
      await new Promise(resolve => setTimeout(resolve, 500));
    }
    
    throw new TimeoutError('等待按钮启用', timeout, {
      action: 'fillForm'
    });
  }
}

export default FillFormAction;
