/**
 * AdsPower Provider的BaseAction
 * 扩展了核心BaseAction，添加人类行为模拟和变量替换
 */

import { Page } from 'puppeteer';

export interface ActionContext {
  page: Page;
  logger?: any;
  data?: any;
  siteConfig?: any;
  config?: any;
  siteName?: string;
  adapter?: any; // 自定义适配器，用于CustomAction和WaitAction
}

export abstract class BaseAction {
  protected context: ActionContext;
  protected config: any;
  protected page: Page;
  protected logger: any;

  constructor(context: ActionContext, config: any) {
    this.context = context;
    this.config = config;
    this.page = context.page;
    this.logger = context.logger;
  }

  /**
   * 执行动作（子类必须实现）
   */
  abstract execute(): Promise<any>;

  /**
   * 替换配置中的变量（增强版）
   * 
   * 支持特性：
   * - 多数据源：{{account.email}}, {{site.url}}, {{config.timeout}}
   * - 默认值：{{var|default}}, {{user.name|Guest}}
   * - 变量不存在时警告
   */
  replaceVariables(value: any): any {
    if (typeof value !== 'string') return value;

    return value.replace(/\{\{(.+?)\}\}/g, (match, expression) => {
      // 解析默认值：{{var|default}}
      const [path, defaultValue] = expression.split('|').map((s: string) => s.trim());

      // 获取变量值
      const result = this.resolveVariablePath(path);

      // 如果找到值，返回
      if (result !== undefined && result !== null) {
        return result;
      }

      // 如果有默认值，使用默认值
      if (defaultValue !== undefined) {
        this.log('debug', `变量 "${path}" 不存在，使用默认值: "${defaultValue}"`);
        return defaultValue;
      }

      // 变量不存在且无默认值，发出警告
      this.log('warn', `⚠️ 变量 "${path}" 不存在，返回原始值: ${match}`);
      return match;
    });
  }

  /**
   * 解析变量路径，支持多个数据源
   */
  resolveVariablePath(path: string): any {
    const keys = path.split('.');
    const rootKey = keys[0];

    // 确定数据源
    let dataSource: any;
    let startIndex = 1; // 从第二个key开始

    switch (rootKey) {
      case 'site':
        // {{site.url}} -> context.siteConfig.url
        dataSource = this.context.siteConfig;
        break;

      case 'config':
        // {{config.timeout}} -> context.config
        dataSource = this.context.config;
        break;

      case 'env':
        // {{env.API_KEY}} -> process.env
        dataSource = process.env;
        break;

      default:
        // 默认从 context.data 读取
        // {{account.email}} -> context.data.account.email
        dataSource = this.context.data;
        startIndex = 0; // 从第一个key开始
    }

    if (!dataSource) {
      return undefined;
    }

    // 遍历路径获取值
    let result = dataSource;
    for (let i = startIndex; i < keys.length; i++) {
      if (result && typeof result === 'object') {
        result = result[keys[i]];
      } else {
        return undefined;
      }
    }

    return result;
  }

  /**
   * 记录日志
   */
  log(level: string, message: string): void {
    if (this.logger && this.logger[level]) {
      this.logger[level](this.context.siteName || 'Automation', message);
    } else {
      console.log(`[${level.toUpperCase()}] ${message}`);
    }
  }

  /**
   * 人类行为延迟工具方法（模拟真实用户操作节奏）
   */

  // 随机延迟
  async randomDelay(min: number, max: number): Promise<void> {
    const delay = min + Math.random() * (max - min);
    await new Promise(resolve => setTimeout(resolve, delay));
  }

  // 阅读页面延迟（2-5秒）- 模拟用户查看页面内容
  async readPageDelay(): Promise<void> {
    await this.randomDelay(2000, 5000);
  }

  // 思考延迟（1-2.5秒）- 模拟填写表单后的思考
  async thinkDelay(): Promise<void> {
    await this.randomDelay(1000, 2500);
  }

  // 短暂停顿（300-800ms）- 模拟操作间的自然停顿
  async pauseDelay(): Promise<void> {
    await this.randomDelay(300, 800);
  }

  // 步骤间延迟（1.5-3秒）- 模拟步骤之间的过渡
  async stepDelay(): Promise<void> {
    await this.randomDelay(1500, 3000);
  }

  /**
   * 获取Action类（用于动态加载）
   */
  getActionClass(actionType: string): any {
    const actionMap: any = {
      navigate: require('./NavigateAction').default,
      fillForm: require('./FillFormAction').default,
      click: require('./ClickAction').default,
      wait: require('./WaitAction').default,
      custom: require('./CustomAction').default,
      scroll: require('./ScrollAction').default,
      verify: require('./VerifyAction').default,
      extract: require('./ExtractAction').default,
      retryBlock: require('./RetryBlockAction').default
    };

    const ActionClass = actionMap[actionType];

    if (!ActionClass) {
      throw new Error(`未知的 action 类型: ${actionType}`);
    }

    return ActionClass;
  }
}

export default BaseAction;
