/**
 * Human Behavior - 模拟人类行为
 * 用于使自动化操作更像真实用户
 */

const { randomInt } = require('../../utils');

class HumanBehavior {
  /**
   * 人类般的输入
   * @param {Page} page - Puppeteer page对象
   * @param {string} selector - 选择器
   * @param {string} text - 要输入的文本
   */
  async humanType(page, selector, text) {
    await page.waitForSelector(selector);
    
    // 点击输入框获得焦点
    await page.click(selector);
    await this.randomDelay(200, 400);
    
    // 清空现有内容
    await page.evaluate((sel) => {
      const element = document.querySelector(sel);
      if (element) element.value = '';
    }, selector);
    
    // 逐字符输入 - 使用page.type
    await page.type(selector, text, {
      delay: this.randomInt(100, 180)  // 每个字符的延迟
    });
    
    // 每隔几个字符停顿一下
    await this.randomDelay(300, 600);
    
    // 验证输入是否正确
    const actualValue = await page.evaluate((sel) => {
      const element = document.querySelector(sel);
      return element ? element.value : '';
    }, selector);
    
    if (actualValue !== text) {
      console.warn(`⚠️ 输入验证失败: 期望 "${text}", 实际 "${actualValue}"`);
    }
    
    // 触发blur事件（触发表单验证）
    await page.evaluate((sel) => {
      const element = document.querySelector(sel);
      if (element) {
        element.blur();
      }
    }, selector);
    
    // 等待表单验证完成
    await this.randomDelay(500, 800);
  }

  /**
   * 人类般的点击
   * @param {Page} page - Puppeteer page对象
   * @param {string} selector - 选择器
   */
  async humanClick(page, selector) {
    const element = await page.$(selector);
    if (!element) {
      throw new Error(`Element not found: ${selector}`);
    }
    
    const box = await element.boundingBox();
    if (!box) {
      // 如果元素不可见，直接点击
      await element.click();
      return;
    }
    
    // 计算随机点击位置（在元素范围内）
    const x = box.x + box.width / 2 + this.randomInt(-box.width * 0.3, box.width * 0.3);
    const y = box.y + box.height / 2 + this.randomInt(-box.height * 0.3, box.height * 0.3);
    
    // 先移动鼠标到附近（不是直接到目标）
    const steps = this.randomInt(10, 20);
    await page.mouse.move(
      x + this.randomInt(-50, 50),
      y + this.randomInt(-50, 50),
      { steps: Math.floor(steps / 2) }
    );
    
    await this.randomDelay(50, 150);
    
    // 移动到目标位置
    await page.mouse.move(x, y, { steps: Math.floor(steps / 2) });
    
    // 短暂停顿
    await this.randomDelay(50, 200);
    
    // 点击（按下和释放之间有随机延迟）
    await page.mouse.down();
    await this.randomDelay(50, 120);
    await page.mouse.up();
    
    // 点击后短暂停顿
    await this.randomDelay(100, 300);
  }

  /**
   * 随机延迟
   * @param {number} min - 最小毫秒
   * @param {number} max - 最大毫秒
   */
  async randomDelay(min, max) {
    const delay = this.randomInt(min, max);
    await new Promise(resolve => setTimeout(resolve, delay));
  }

  /**
   * 随机整数
   * @param {number} min - 最小值
   * @param {number} max - 最大值
   * @returns {number}
   */
  randomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  }

  /**
   * 人类般的滚动
   * @param {Page} page - Puppeteer page对象
   * @param {string} direction - 方向 'down' 或 'up'
   */
  async humanScroll(page, direction = 'down') {
    const distance = this.randomInt(100, 300);
    const steps = this.randomInt(3, 8);
    
    for (let i = 0; i < steps; i++) {
      await page.evaluate((dir, dist) => {
        window.scrollBy(0, dir === 'down' ? dist : -dist);
      }, direction, distance / steps);
      
      await this.randomDelay(100, 300);
    }
  }

  /**
   * 模拟鼠标随机移动（增加真实性）
   * @param {Page} page - Puppeteer page对象
   */
  async randomMouseMovement(page) {
    const viewport = await page.viewport();
    const x = this.randomInt(100, viewport.width - 100);
    const y = this.randomInt(100, viewport.height - 100);
    
    await page.mouse.move(x, y, { steps: this.randomInt(10, 30) });
  }

  /**
   * 模拟阅读页面（随机停顿）
   * @param {number} minSeconds - 最小秒数
   * @param {number} maxSeconds - 最大秒数
   */
  async readPage(minSeconds = 2, maxSeconds = 5) {
    const seconds = this.randomInt(minSeconds, maxSeconds);
    await this.randomDelay(seconds * 1000, (seconds + 1) * 1000);
  }

  /**
   * 检查并勾选checkbox（人类方式）
   * @param {Page} page - Puppeteer page对象
   * @param {string} selector - 选择器
   */
  async humanCheckbox(page, selector) {
    await page.waitForSelector(selector);
    
    // 移动到checkbox附近
    const element = await page.$(selector);
    const box = await element.boundingBox();
    
    if (box) {
      await page.mouse.move(
        box.x + box.width / 2,
        box.y + box.height / 2,
        { steps: this.randomInt(5, 15) }
      );
      await this.randomDelay(200, 500);
    }
    
    // 点击
    await element.click();
    await this.randomDelay(300, 700);
  }

  /**
   * 模拟查找元素（视觉搜索行为）
   * @param {Page} page - Puppeteer page对象
   * @param {string} selector - 目标元素选择器
   */
  async visualSearch(page, selector) {
    // 先随机移动几次鼠标（模拟眼睛在找）
    for (let i = 0; i < this.randomInt(2, 4); i++) {
      await this.randomMouseMovement(page);
      await this.randomDelay(300, 800);
    }
    
    // 找到目标元素
    await page.waitForSelector(selector);
    
    // 移动到目标
    const element = await page.$(selector);
    const box = await element.boundingBox();
    if (box) {
      await page.mouse.move(
        box.x + box.width / 2,
        box.y + box.height / 2,
        { steps: this.randomInt(15, 25) }
      );
    }
  }
}

module.exports = HumanBehavior;
