/// <reference lib="dom" />
import path from 'path';
import { BasePlatformAdapter } from './base.js';
import type {
  AccountProfile,
  PublishParams,
  PublishResult,
  DateRange,
  AnalyticsData,
  CommentData,
  WorkItem,
} from './base.js';
import type { PlatformType, QRCodeInfo, LoginStatusResult } from '@media-manager/shared';
import { logger } from '../../utils/logger.js';
import { aiService } from '../../ai/index.js';

// 小红书 Python API 服务配置
const XHS_PYTHON_SERVICE_URL = process.env.XHS_SERVICE_URL || 'http://localhost:5005';

// 服务器根目录（用于构造绝对路径）
const SERVER_ROOT = path.resolve(process.cwd());

/**
 * 小红书平台适配器
 */
export class XiaohongshuAdapter extends BasePlatformAdapter {
  readonly platform: PlatformType = 'xiaohongshu';
  readonly loginUrl = 'https://creator.xiaohongshu.com/';
  readonly publishUrl = 'https://creator.xiaohongshu.com/publish/publish?from=menu&target=video';
  readonly creatorHomeUrl = 'https://creator.xiaohongshu.com/creator/home';
  readonly contentManageUrl = 'https://creator.xiaohongshu.com/creator/content';

  protected getCookieDomain(): string {
    return '.xiaohongshu.com';
  }

  /**
   * 获取扫码登录二维码
   */
  async getQRCode(): Promise<QRCodeInfo> {
    try {
      await this.initBrowser();

      if (!this.page) throw new Error('Page not initialized');

      // 访问创作者中心
      await this.page.goto(this.loginUrl);

      // 等待二维码出现
      await this.waitForSelector('[class*="qrcode"] img, .qrcode-image img', 30000);

      // 获取二维码图片
      const qrcodeImg = await this.page.$('[class*="qrcode"] img, .qrcode-image img');
      const qrcodeUrl = await qrcodeImg?.getAttribute('src');

      if (!qrcodeUrl) {
        throw new Error('Failed to get QR code');
      }

      const qrcodeKey = `xiaohongshu_${Date.now()}`;

      return {
        qrcodeUrl,
        qrcodeKey,
        expireTime: Date.now() + 300000, // 5分钟过期
      };
    } catch (error) {
      logger.error('Xiaohongshu getQRCode error:', error);
      throw error;
    }
  }

  /**
   * 检查扫码状态
   */
  async checkQRCodeStatus(qrcodeKey: string): Promise<LoginStatusResult> {
    try {
      if (!this.page) {
        return { status: 'expired', message: '二维码已过期' };
      }

      // 检查是否登录成功（URL 变化）
      const currentUrl = this.page.url();

      if (currentUrl.includes('/creator/home') || currentUrl.includes('/publish')) {
        // 登录成功，获取 cookie
        const cookies = await this.getCookies();
        await this.closeBrowser();

        return {
          status: 'success',
          message: '登录成功',
          cookies,
        };
      }

      // 检查是否扫码
      const scanTip = await this.page.$('[class*="scan-success"], [class*="scanned"]');
      if (scanTip) {
        return { status: 'scanned', message: '已扫码，请确认登录' };
      }

      return { status: 'waiting', message: '等待扫码' };
    } catch (error) {
      logger.error('Xiaohongshu checkQRCodeStatus error:', error);
      return { status: 'error', message: '检查状态失败' };
    }
  }

  /**
   * 检查登录状态
   */
  async checkLoginStatus(cookies: string): Promise<boolean> {
    try {
      await this.initBrowser({ headless: true });
      await this.setCookies(cookies);

      if (!this.page) throw new Error('Page not initialized');

      // 访问创作者中心
      await this.page.goto(this.creatorHomeUrl, {
        waitUntil: 'domcontentloaded',
        timeout: 30000,
      });

      await this.page.waitForTimeout(3000);

      const url = this.page.url();
      logger.info(`Xiaohongshu checkLoginStatus URL: ${url}`);

      // 如果被重定向到登录页面，说明未登录
      const isLoginPage = url.includes('login') || url.includes('passport');

      await this.closeBrowser();

      return !isLoginPage;
    } catch (error) {
      logger.error('Xiaohongshu checkLoginStatus error:', error);
      await this.closeBrowser();
      return false;
    }
  }

  /**
   * 关闭页面上可能存在的弹窗对话框
   */
  private async closeModalDialogs(): Promise<boolean> {
    if (!this.page) return false;
    
    let closedAny = false;
    
    try {
      // 检查并关闭 Element UI / Vue 弹窗
      const modalSelectors = [
        // Element UI 弹窗关闭按钮
        '.el-dialog__close',
        '.el-dialog__headerbtn',
        '.el-message-box__close',
        '.el-overlay-dialog .el-icon-close',
        // 通用关闭按钮
        '[class*="modal"] [class*="close"]',
        '[class*="dialog"] [class*="close"]',
        '[role="dialog"] button[aria-label="close"]',
        '[role="dialog"] [class*="close"]',
        // 取消/关闭按钮
        '.el-dialog__footer button:has-text("取消")',
        '.el-dialog__footer button:has-text("关闭")',
        '[role="dialog"] button:has-text("取消")',
        '[role="dialog"] button:has-text("关闭")',
        // 遮罩层（点击遮罩关闭）
        '.el-overlay[style*="display: none"]',
      ];
      
      for (const selector of modalSelectors) {
        try {
          const closeBtn = this.page.locator(selector).first();
          if (await closeBtn.count() > 0 && await closeBtn.isVisible()) {
            logger.info(`[Xiaohongshu] Found modal close button: ${selector}`);
            await closeBtn.click({ timeout: 2000 });
            closedAny = true;
            await this.page.waitForTimeout(500);
          }
        } catch (e) {
          // 忽略错误，继续尝试下一个选择器
        }
      }
      
      // 尝试按 ESC 键关闭弹窗
      if (!closedAny) {
        const hasModal = await this.page.locator('.el-overlay-dialog, [role="dialog"]').count();
        if (hasModal > 0) {
          logger.info('[Xiaohongshu] Trying ESC key to close modal...');
          await this.page.keyboard.press('Escape');
          await this.page.waitForTimeout(500);
          
          // 检查是否关闭成功
          const stillHasModal = await this.page.locator('.el-overlay-dialog, [role="dialog"]').count();
          closedAny = stillHasModal < hasModal;
        }
      }
      
      if (closedAny) {
        logger.info('[Xiaohongshu] Successfully closed modal dialog');
      }
      
    } catch (error) {
      logger.warn('[Xiaohongshu] Error closing modal:', error);
    }
    
    return closedAny;
  }

  /**
   * 获取账号信息
   * 通过拦截 API 响应获取准确数据
   */
  async getAccountInfo(cookies: string): Promise<AccountProfile> {
    try {
      await this.initBrowser({ headless: true });
      await this.setCookies(cookies);

      if (!this.page) throw new Error('Page not initialized');

      let accountId = `xiaohongshu_${Date.now()}`;
      let accountName = '小红书账号';
      let avatarUrl = '';
      let fansCount = 0;
      let worksCount = 0;
      let worksList: WorkItem[] = [];

      // 用于捕获 API 响应
      const capturedData: {
        userInfo?: {
          nickname?: string;
          avatar?: string;
          userId?: string;
          redId?: string;
          fans?: number;
          notes?: number;
        };
        homeData?: {
          fans?: number;
          notes?: number;
        };
      } = {};

      // 用于等待 API 响应的 Promise
      let resolvePersonalInfo: () => void;
      let resolveNotesCount: () => void;
      const personalInfoPromise = new Promise<void>((resolve) => { resolvePersonalInfo = resolve; });
      const notesCountPromise = new Promise<void>((resolve) => { resolveNotesCount = resolve; });

      // 设置超时自动 resolve
      setTimeout(() => resolvePersonalInfo(), 10000);
      setTimeout(() => resolveNotesCount(), 10000);

      // 设置 API 响应监听器
      this.page.on('response', async (response) => {
        const url = response.url();
        try {
          // 监听用户信息 API - personal_info 接口
          // URL: https://creator.xiaohongshu.com/api/galaxy/creator/home/personal_info
          // 返回结构: { data: { name, avatar, fans_count, red_num, follow_count, faved_count } }
          if (url.includes('/api/galaxy/creator/home/personal_info')) {
            const data = await response.json();
            logger.info(`[Xiaohongshu API] Personal info:`, JSON.stringify(data).slice(0, 1000));

            if (data?.data) {
              const info = data.data;
              capturedData.userInfo = {
                nickname: info.name,
                avatar: info.avatar,
                userId: info.red_num,  // 小红书号
                redId: info.red_num,
                fans: info.fans_count,
              };
              logger.info(`[Xiaohongshu API] Captured personal info:`, capturedData.userInfo);
            }
            resolvePersonalInfo();
          }

          // 监听笔记列表 API (获取作品数) - 新版 edith API
          // URL: https://edith.xiaohongshu.com/web_api/sns/v5/creator/note/user/posted
          // 返回结构: { data: { tags: [{ name: "所有笔记", notes_count: 1 }] } }
          if (url.includes('edith.xiaohongshu.com') && url.includes('/creator/note/user/posted')) {
            const data = await response.json();
            logger.info(`[Xiaohongshu API] Posted notes (edith):`, JSON.stringify(data).slice(0, 800));
            
            if (data?.data?.tags && Array.isArray(data.data.tags)) {
              // 从 tags 数组中找到 "所有笔记" 的 notes_count
              const allNotesTag = data.data.tags.find((tag: { id?: string; name?: string; notes_count?: number }) => 
                tag.id?.includes('note_time') || tag.name === '所有笔记'
              );
              if (allNotesTag?.notes_count !== undefined) {
                capturedData.homeData = capturedData.homeData || {};
                capturedData.homeData.notes = allNotesTag.notes_count;
                logger.info(`[Xiaohongshu API] Total notes from edith API: ${allNotesTag.notes_count}`);
              }
            }
            resolveNotesCount();
          }
        } catch (e) {
          // 忽略非 JSON 响应
          logger.debug(`[Xiaohongshu API] Failed to parse response: ${url}`);
        }
      });

      // 1. 先访问创作者首页获取用户信息
      // URL: https://creator.xiaohongshu.com/new/home
      // API: /api/galaxy/creator/home/personal_info
      logger.info('[Xiaohongshu] Navigating to creator home...');
      await this.page.goto('https://creator.xiaohongshu.com/new/home', {
        waitUntil: 'networkidle',
        timeout: 30000,
      });

      // 等待 personal_info API 响应
      await Promise.race([personalInfoPromise, this.page.waitForTimeout(5000)]);
      logger.info(`[Xiaohongshu] After home page, capturedData.userInfo:`, capturedData.userInfo);

      // 2. 再访问笔记管理页面获取作品数
      // URL: https://creator.xiaohongshu.com/new/note-manager
      // API: https://edith.xiaohongshu.com/web_api/sns/v5/creator/note/user/posted
      logger.info('[Xiaohongshu] Navigating to note manager...');
      await this.page.goto('https://creator.xiaohongshu.com/new/note-manager', {
        waitUntil: 'networkidle',
        timeout: 30000,
      });

      // 等待 notes API 响应
      await Promise.race([notesCountPromise, this.page.waitForTimeout(5000)]);
      logger.info(`[Xiaohongshu] After note manager, capturedData.homeData:`, capturedData.homeData);

      // 检查是否需要登录
      const currentUrl = this.page.url();
      if (currentUrl.includes('login') || currentUrl.includes('passport')) {
        logger.warn('[Xiaohongshu] Cookie expired, needs login');
        await this.closeBrowser();
        return {
          accountId,
          accountName,
          avatarUrl,
          fansCount,
          worksCount,
        };
      }

      // 使用捕获的数据
      if (capturedData.userInfo) {
        if (capturedData.userInfo.nickname) accountName = capturedData.userInfo.nickname;
        if (capturedData.userInfo.avatar) avatarUrl = capturedData.userInfo.avatar;
        if (capturedData.userInfo.userId) accountId = `xiaohongshu_${capturedData.userInfo.userId}`;
        else if (capturedData.userInfo.redId) accountId = `xiaohongshu_${capturedData.userInfo.redId}`;
        if (capturedData.userInfo.fans !== undefined) fansCount = capturedData.userInfo.fans;
      }

      // homeData.notes 来自笔记列表 API，直接使用（优先级最高）
      if (capturedData.homeData) {
        if (capturedData.homeData.notes !== undefined) {
          worksCount = capturedData.homeData.notes;
          logger.info(`[Xiaohongshu] Using notes count from API: ${worksCount}`);
        }
      }

      // 如果 API 没捕获到，尝试从页面 DOM 获取
      if (fansCount === 0 || worksCount === 0) {
        const statsData = await this.page.evaluate(() => {
          const result = { fans: 0, notes: 0, name: '', avatar: '' };
          
          // 获取页面文本
          const allText = document.body.innerText;
          
          // 尝试匹配粉丝数
          const fansMatch = allText.match(/粉丝[：:\s]*(\d+(?:\.\d+)?[万亿]?)|(\d+(?:\.\d+)?[万亿]?)\s*粉丝/);
          if (fansMatch) {
            const numStr = fansMatch[1] || fansMatch[2];
            result.fans = Math.floor(parseFloat(numStr) * (numStr.includes('万') ? 10000 : numStr.includes('亿') ? 100000000 : 1));
          }
          
          // 尝试匹配笔记数
          const notesMatch = allText.match(/笔记[：:\s]*(\d+)|(\d+)\s*篇?笔记|共\s*(\d+)\s*篇/);
          if (notesMatch) {
            result.notes = parseInt(notesMatch[1] || notesMatch[2] || notesMatch[3]);
          }
          
          // 获取用户名
          const nameEl = document.querySelector('[class*="nickname"], [class*="user-name"], [class*="creator-name"]');
          if (nameEl) result.name = nameEl.textContent?.trim() || '';
          
          // 获取头像
          const avatarEl = document.querySelector('[class*="avatar"] img, [class*="user-avatar"] img');
          if (avatarEl) result.avatar = (avatarEl as HTMLImageElement).src || '';
          
          return result;
        });
        
        if (fansCount === 0 && statsData.fans > 0) fansCount = statsData.fans;
        if (worksCount === 0 && statsData.notes > 0) worksCount = statsData.notes;
        if ((!accountName || accountName === '小红书账号') && statsData.name) accountName = statsData.name;
        if (!avatarUrl && statsData.avatar) avatarUrl = statsData.avatar;
      }

      await this.closeBrowser();

      logger.info(`[Xiaohongshu] Account info: ${accountName}, ID: ${accountId}, Fans: ${fansCount}, Works: ${worksCount}`);

      return {
        accountId,
        accountName,
        avatarUrl,
        fansCount,
        worksCount,
        worksList,
      };
    } catch (error) {
      logger.error('Xiaohongshu getAccountInfo error:', error);
      await this.closeBrowser();
      return {
        accountId: `xiaohongshu_${Date.now()}`,
        accountName: '小红书账号',
        avatarUrl: '',
        fansCount: 0,
        worksCount: 0,
      };
    }
  }

  /**
   * 检查 Python API 服务是否可用
   */
  private async checkPythonServiceAvailable(): Promise<boolean> {
    try {
      const response = await fetch(`${XHS_PYTHON_SERVICE_URL}/health`, {
        method: 'GET',
        signal: AbortSignal.timeout(3000),
      });
      if (response.ok) {
        const data = await response.json();
        return data.status === 'ok' && data.xhs_sdk === true;
      }
      return false;
    } catch {
      return false;
    }
  }

  /**
   * 通过 Python API 服务发布视频（推荐方式，更稳定）
   * 参考: matrix 项目的小红书发布逻辑
   */
  private async publishVideoViaApi(
    cookies: string,
    params: PublishParams,
    onProgress?: (progress: number, message: string) => void
  ): Promise<PublishResult> {
    logger.info('[Xiaohongshu API] Starting publish via Python API service...');
    onProgress?.(5, '正在通过 API 发布...');

    try {
      // 准备 cookie 字符串
      let cookieStr = cookies;
      
      // 如果 cookies 是 JSON 数组格式，转换为字符串格式
      try {
        const cookieArray = JSON.parse(cookies);
        if (Array.isArray(cookieArray)) {
          cookieStr = cookieArray.map((c: { name: string; value: string }) => `${c.name}=${c.value}`).join('; ');
        }
      } catch {
        // 已经是字符串格式
      }

      onProgress?.(10, '正在上传视频...');

      // 将相对路径转换为绝对路径
      const absoluteVideoPath = path.isAbsolute(params.videoPath) 
        ? params.videoPath 
        : path.resolve(SERVER_ROOT, params.videoPath);
      
      const absoluteCoverPath = params.coverPath 
        ? (path.isAbsolute(params.coverPath) ? params.coverPath : path.resolve(SERVER_ROOT, params.coverPath))
        : undefined;

      const requestBody = {
        platform: 'xiaohongshu',
        cookie: cookieStr,
        title: params.title,
        description: params.description || params.title,
        video_path: absoluteVideoPath,
        cover_path: absoluteCoverPath,
        tags: params.tags || [],
        post_time: params.scheduledTime ? new Date(params.scheduledTime).toISOString().replace('T', ' ').slice(0, 19) : null,
      };

      logger.info('[Xiaohongshu API] Request body:', {
        platform: requestBody.platform,
        title: requestBody.title,
        video_path: requestBody.video_path,
        has_cookie: !!requestBody.cookie,
        cookie_length: requestBody.cookie?.length || 0,
      });

      // 使用 AI 辅助发布接口
      const response = await fetch(`${XHS_PYTHON_SERVICE_URL}/publish/ai-assisted`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          ...requestBody,
          return_screenshot: true,
        }),
        signal: AbortSignal.timeout(300000), // 5分钟超时
      });

      const result = await response.json();
      logger.info('[Xiaohongshu API] Response:', { ...result, screenshot_base64: result.screenshot_base64 ? '[截图已省略]' : undefined });

      // 使用通用的 AI 辅助处理方法
      return await this.aiProcessPythonPublishResult(result, undefined, onProgress);
    } catch (error) {
      logger.error('[Xiaohongshu API] Publish failed:', error);
      throw error;
    }
  }

  /**
   * 发布视频/笔记
   * 只使用 Python API 服务发布
   */
  async publishVideo(
    cookies: string,
    params: PublishParams,
    onProgress?: (progress: number, message: string) => void,
    onCaptchaRequired?: (captchaInfo: { taskId: string; phone?: string }) => Promise<string>,
    options?: { headless?: boolean }
  ): Promise<PublishResult> {
    // 只使用 Python API 服务
    const apiAvailable = await this.checkPythonServiceAvailable();
    if (!apiAvailable) {
      logger.error('[Xiaohongshu] Python API service not available');
      return {
        success: false,
        errorMessage: 'Python 发布服务不可用，请确保 Python 服务已启动',
      };
    }

    logger.info('[Xiaohongshu] Using Python API service for publishing');
    try {
      const result = await this.publishVideoViaApi(cookies, params, onProgress);
      
      // 检查是否需要验证码
      if (!result.success && result.errorMessage?.includes('验证码')) {
        logger.info('[Xiaohongshu] Python detected captcha, need headful browser');
        return {
          success: false,
          errorMessage: `CAPTCHA_REQUIRED:${result.errorMessage}`,
        };
      }
      
      return result;
    } catch (apiError) {
      logger.error('[Xiaohongshu] Python API publish failed:', apiError);
      return {
        success: false,
        errorMessage: apiError instanceof Error ? apiError.message : '发布失败',
      };
    }

    /* ========== Playwright 方式已注释，只使用 Python API ==========
    const useHeadless = options?.headless ?? true;

    try {
      logger.info('[Xiaohongshu Publish] Initializing browser...');
      await this.initBrowser({ headless: useHeadless });
      
      if (!this.page) {
        throw new Error('浏览器初始化失败，page 为 null');
      }
      
      logger.info('[Xiaohongshu Publish] Setting cookies...');
      await this.setCookies(cookies);

      if (!useHeadless) {
        logger.info('[Xiaohongshu Publish] Running in HEADFUL mode');
        onProgress?.(1, '已打开浏览器窗口，请注意查看...');
      }

      // 再次检查 page 状态
      if (!this.page) throw new Error('Page not initialized after setCookies');

      // 检查视频文件是否存在
      const fs = await import('fs');
      if (!fs.existsSync(params.videoPath)) {
        throw new Error(`视频文件不存在: ${params.videoPath}`);
      }

      onProgress?.(5, '正在打开发布页面...');
      logger.info(`[Xiaohongshu Publish] Starting upload for: ${params.videoPath}`);

      // 访问发布页面
      await this.page.goto(this.publishUrl, {
        waitUntil: 'domcontentloaded',
        timeout: 60000,
      });

      await this.page.waitForTimeout(3000);

      // 检查是否需要登录
      const currentUrl = this.page.url();
      if (currentUrl.includes('login') || currentUrl.includes('passport')) {
        throw new Error('登录已过期，请重新登录');
      }

      logger.info(`[Xiaohongshu Publish] Page loaded: ${currentUrl}`);

      onProgress?.(10, '正在选择视频文件...');

      // 确保在"上传视频"标签页
      try {
        const videoTab = this.page.locator('div.tab:has-text("上传视频"), span:has-text("上传视频")').first();
        if (await videoTab.count() > 0) {
          await videoTab.click();
          await this.page.waitForTimeout(1000);
          logger.info('[Xiaohongshu Publish] Clicked video tab');
        }
      } catch {}

      // 上传视频 - 优先使用 AI 截图分析找到上传入口
      let uploadTriggered = false;

      // 方法1: AI 截图分析找到上传入口
      logger.info('[Xiaohongshu Publish] Using AI to find upload entry...');
      try {
        const screenshot = await this.screenshotBase64();
        const guide = await aiService.getPageOperationGuide(screenshot, 'xiaohongshu', '找到视频上传入口并点击上传按钮');
        logger.info(`[Xiaohongshu Publish] AI analysis result:`, guide);

        if (guide.hasAction && guide.targetSelector) {
          logger.info(`[Xiaohongshu Publish] AI suggested selector: ${guide.targetSelector}`);
          try {
            const [fileChooser] = await Promise.all([
              this.page.waitForEvent('filechooser', { timeout: 15000 }),
              this.page.click(guide.targetSelector),
            ]);
            await fileChooser.setFiles(params.videoPath);
            uploadTriggered = true;
            logger.info('[Xiaohongshu Publish] Upload triggered via AI selector');
          } catch (e) {
            logger.warn(`[Xiaohongshu Publish] AI selector click failed: ${e}`);
          }
        }
      } catch (e) {
        logger.warn(`[Xiaohongshu Publish] AI analysis failed: ${e}`);
      }

      // 方法2: 尝试点击常见的上传区域触发 file chooser
      if (!uploadTriggered) {
        logger.info('[Xiaohongshu Publish] Trying common upload selectors...');
        const uploadSelectors = [
          // 小红书常见上传区域选择器
          '[class*="upload-area"]',
          '[class*="upload-btn"]',
          '[class*="upload-trigger"]',
          '[class*="upload-container"]',
          '[class*="drag-area"]',
          'div[class*="upload"] div',
          '.upload-wrapper',
          '.video-upload',
          'button:has-text("上传")',
          'div:has-text("上传视频"):not(:has(div))',
          'span:has-text("上传视频")',
          '[class*="add-video"]',
        ];
        
        for (const selector of uploadSelectors) {
          if (uploadTriggered) break;
          try {
            const element = this.page.locator(selector).first();
            if (await element.count() > 0 && await element.isVisible()) {
              logger.info(`[Xiaohongshu Publish] Trying selector: ${selector}`);
              const [fileChooser] = await Promise.all([
                this.page.waitForEvent('filechooser', { timeout: 5000 }),
                element.click(),
              ]);
              await fileChooser.setFiles(params.videoPath);
              uploadTriggered = true;
              logger.info(`[Xiaohongshu Publish] Upload triggered via selector: ${selector}`);
            }
          } catch (e) {
            // 继续尝试下一个选择器
          }
        }
      }

      // 方法3: 直接设置 file input
      if (!uploadTriggered) {
        logger.info('[Xiaohongshu Publish] Trying direct file input...');
        const fileInputs = await this.page.$$('input[type="file"]');
        logger.info(`[Xiaohongshu Publish] Found ${fileInputs.length} file inputs`);
        
        for (const fileInput of fileInputs) {
          try {
            const accept = await fileInput.getAttribute('accept');
            if (!accept || accept.includes('video') || accept.includes('*')) {
              await fileInput.setInputFiles(params.videoPath);
              uploadTriggered = true;
              logger.info('[Xiaohongshu Publish] Upload triggered via file input');
              
              // 直接设置后需要等待一下，让页面响应
              await this.page.waitForTimeout(2000);
              
              // 检查页面是否有变化
              const hasChange = await this.page.locator('[class*="video-preview"], video, [class*="progress"], [class*="upload-success"]').count() > 0;
              if (hasChange) {
                logger.info('[Xiaohongshu Publish] Page responded to file input');
                break;
              }
            }
          } catch (e) {
            logger.warn(`[Xiaohongshu Publish] File input method failed: ${e}`);
          }
        }
      }

      if (!uploadTriggered) {
        // 截图调试
        try {
          if (this.page) {
            const screenshotPath = `uploads/debug/xhs_no_upload_${Date.now()}.png`;
            await this.page.screenshot({ path: screenshotPath, fullPage: true });
            logger.info(`[Xiaohongshu Publish] Screenshot saved: ${screenshotPath}`);
          }
        } catch {}
        throw new Error('无法上传视频文件');
      }

      onProgress?.(15, '视频上传中...');

      // 等待视频上传完成
      const maxWaitTime = 300000; // 5分钟
      const startTime = Date.now();
      let lastAiCheckTime = 0;
      const aiCheckInterval = 10000; // 每10秒使用AI检测一次
      let uploadComplete = false;

      while (Date.now() - startTime < maxWaitTime && !uploadComplete) {
        await this.page.waitForTimeout(3000);

        // 检查当前URL是否变化（上传成功后可能跳转）
        const newUrl = this.page.url();
        if (newUrl !== currentUrl && !newUrl.includes('upload')) {
          logger.info(`[Xiaohongshu Publish] URL changed to: ${newUrl}`);
        }

        // 检查上传进度（通过DOM）
        let progressDetected = false;
        const progressText = await this.page.locator('[class*="progress"]').first().textContent().catch(() => '');
        if (progressText) {
          const match = progressText.match(/(\d+)%/);
          if (match) {
            const progress = parseInt(match[1]);
            onProgress?.(15 + Math.floor(progress * 0.4), `视频上传中: ${progress}%`);
            logger.info(`[Xiaohongshu Publish] Upload progress: ${progress}%`);
            progressDetected = true;
            if (progress >= 100) {
              logger.info('[Xiaohongshu Publish] Upload progress reached 100%');
              uploadComplete = true;
              break;
            }
          }
        }

        // 检查是否上传完成 - 扩展检测范围
        const uploadCompleteSelectors = [
          '[class*="upload-success"]',
          '[class*="video-preview"]',
          'video',
          '[class*="cover"]', // 封面设置区域
          'input[placeholder*="标题"]', // 标题输入框出现
          '[class*="title"] input',
          '[class*="editor"]', // 编辑器区域
        ];
        
        for (const selector of uploadCompleteSelectors) {
          const count = await this.page.locator(selector).count();
          if (count > 0) {
            logger.info(`[Xiaohongshu Publish] Video upload completed, found: ${selector}`);
            uploadComplete = true;
            break;
          }
        }
        
        if (uploadComplete) break;
        
        // 如果标题输入框出现，说明可以开始填写了
        const titleInput = await this.page.locator('input[placeholder*="标题"]').count();
        if (titleInput > 0) {
          logger.info('[Xiaohongshu Publish] Title input found, upload must be complete');
          uploadComplete = true;
          break;
        }

        // 使用AI检测上传进度（每隔一段时间检测一次）
        if (!progressDetected && !uploadComplete && Date.now() - lastAiCheckTime > aiCheckInterval) {
          lastAiCheckTime = Date.now();
          try {
            const screenshot = await this.screenshotBase64();
            const uploadStatus = await aiService.analyzeUploadProgress(screenshot, 'xiaohongshu');
            logger.info(`[Xiaohongshu Publish] AI upload status:`, uploadStatus);
            
            if (uploadStatus.isComplete) {
              logger.info('[Xiaohongshu Publish] AI detected upload complete');
              uploadComplete = true;
              break;
            }
            
            if (uploadStatus.isFailed) {
              throw new Error(`视频上传失败: ${uploadStatus.statusDescription}`);
            }
            
            if (uploadStatus.progress !== null) {
              onProgress?.(15 + Math.floor(uploadStatus.progress * 0.4), `视频上传中: ${uploadStatus.progress}%`);
              if (uploadStatus.progress >= 100) {
                logger.info('[Xiaohongshu Publish] AI detected progress 100%');
                uploadComplete = true;
                break;
              }
            }
          } catch (aiError) {
            logger.warn('[Xiaohongshu Publish] AI progress check failed:', aiError);
          }
        }

        // 检查是否上传失败
        const failText = await this.page.locator('[class*="error"], [class*="fail"]').first().textContent().catch(() => '');
        if (failText && failText.includes('失败')) {
          throw new Error(`视频上传失败: ${failText}`);
        }
        
        // 检查是否还在初始上传页面
        const stillOnUploadPage = await this.page.locator('div:has-text("拖拽视频到此")').count();
        if (stillOnUploadPage > 0 && Date.now() - startTime > 10000) {
          logger.warn('[Xiaohongshu Publish] Still on upload page after 10s, retrying upload...');
          // 可能需要重新触发上传
          break;
        }
      }

      onProgress?.(55, '正在填写笔记信息...');

      // 填写标题
      logger.info('[Xiaohongshu Publish] Filling title...');
      const titleSelectors = [
        'input[placeholder*="标题"]',
        '[class*="title"] input',
        'textarea[placeholder*="标题"]',
      ];

      for (const selector of titleSelectors) {
        const titleInput = this.page.locator(selector).first();
        if (await titleInput.count() > 0) {
          await titleInput.fill(params.title.slice(0, 20)); // 小红书标题限制20字
          logger.info(`[Xiaohongshu Publish] Title filled via: ${selector}`);
          break;
        }
      }

      // 填写描述/正文
      if (params.description) {
        logger.info('[Xiaohongshu Publish] Filling description...');
        const descSelectors = [
          '[class*="content-input"] [contenteditable="true"]',
          'textarea[placeholder*="正文"]',
          '[class*="editor"] [contenteditable="true"]',
          '#post-textarea',
        ];

        for (const selector of descSelectors) {
          const descInput = this.page.locator(selector).first();
          if (await descInput.count() > 0) {
            await descInput.click();
            await this.page.keyboard.type(params.description, { delay: 30 });
            logger.info(`[Xiaohongshu Publish] Description filled via: ${selector}`);
            break;
          }
        }
      }

      onProgress?.(65, '正在添加话题标签...');

      // 添加话题标签 - 注意不要触发话题选择器弹窗
      // 小红书会自动识别 # 开头的话题，不需要从弹窗选择
      if (params.tags && params.tags.length > 0) {
        // 找到正文输入框
        const descSelectors = [
          '[class*="content-input"] [contenteditable="true"]',
          '[class*="editor"] [contenteditable="true"]',
          '#post-textarea',
        ];
        
        for (const selector of descSelectors) {
          const descInput = this.page.locator(selector).first();
          if (await descInput.count() > 0) {
            await descInput.click();
            // 添加空行后再添加标签
            await this.page.keyboard.press('Enter');
            for (const tag of params.tags) {
              await this.page.keyboard.type(`#${tag} `, { delay: 30 });
            }
            logger.info(`[Xiaohongshu Publish] Tags added: ${params.tags.join(', ')}`);
            break;
          }
        }
        
        await this.page.waitForTimeout(500);
      }

      onProgress?.(75, '等待处理完成...');
      
      // 等待视频处理完成，检查是否有"上传成功"标识
      await this.page.waitForTimeout(2000);
      
      // 检查当前页面是否还在编辑状态
      const stillInEditMode = await this.page.locator('input[placeholder*="标题"], [class*="video-preview"]').count() > 0;
      if (!stillInEditMode) {
        logger.error('[Xiaohongshu Publish] Page is no longer in edit mode!');
        try {
          if (this.page) {
            const screenshotPath = `uploads/debug/xhs_not_in_edit_${Date.now()}.png`;
            await this.page.screenshot({ path: screenshotPath, fullPage: true });
          }
        } catch {}
        throw new Error('页面状态异常，请重试');
      }

      onProgress?.(85, '正在发布...');

      // 先关闭可能存在的弹窗
      await this.closeModalDialogs();

      // 滚动到页面底部，确保发布按钮可见
      logger.info('[Xiaohongshu Publish] Scrolling to bottom...');
      await this.page.evaluate(() => {
        window.scrollTo(0, document.body.scrollHeight);
      });
      await this.page.waitForTimeout(1000);

      // 点击发布按钮
      logger.info('[Xiaohongshu Publish] Looking for publish button...');
      
      // 先截图看当前页面状态
      try {
        if (this.page) {
          const beforeClickPath = `uploads/debug/xhs_before_publish_${Date.now()}.png`;
          await this.page.screenshot({ path: beforeClickPath, fullPage: true });
          logger.info(`[Xiaohongshu Publish] Screenshot before publish: ${beforeClickPath}`);
        }
      } catch {}
      
      let publishClicked = false;
      
      // 方法1: 使用 Playwright locator 点击（模拟真实鼠标点击）
      const publishBtnSelectors = [
        'button.publishBtn',
        '.publishBtn',
        'button.d-button.red',
      ];

      for (const selector of publishBtnSelectors) {
        try {
          const btn = this.page.locator(selector).first();
          const count = await btn.count();
          logger.info(`[Xiaohongshu Publish] Checking selector ${selector}: count=${count}`);
          if (count > 0 && await btn.isVisible()) {
            // 确保按钮在视口内
            await btn.scrollIntoViewIfNeeded();
            await this.page.waitForTimeout(500);
            
            // 获取按钮位置并使用鼠标点击
            const box = await btn.boundingBox();
            if (box) {
              // 使用 page.mouse.click 模拟真实鼠标点击
              const x = box.x + box.width / 2;
              const y = box.y + box.height / 2;
              logger.info(`[Xiaohongshu Publish] Clicking at position: (${x}, ${y})`);
              await this.page.mouse.click(x, y);
              publishClicked = true;
              logger.info(`[Xiaohongshu Publish] Publish button clicked via mouse.click: ${selector}`);
              break;
            }
          }
        } catch (e) {
          logger.warn(`[Xiaohongshu Publish] Failed with selector ${selector}:`, e);
        }
      }
      
      // 方法2: 使用 Playwright locator.click() 配合 force 选项
      if (!publishClicked) {
        try {
          const btn = this.page.locator('button.publishBtn').first();
          if (await btn.count() > 0) {
            logger.info('[Xiaohongshu Publish] Trying locator.click with force...');
            await btn.click({ force: true, timeout: 5000 });
            publishClicked = true;
            logger.info('[Xiaohongshu Publish] Publish button clicked via locator.click(force)');
          }
        } catch (e) {
          logger.warn('[Xiaohongshu Publish] locator.click(force) failed:', e);
        }
      }
      
      // 方法3: 使用 getByRole
      if (!publishClicked) {
        try {
          const publishBtn = this.page.getByRole('button', { name: '发布', exact: true });
          if (await publishBtn.count() > 0) {
            const buttons = await publishBtn.all();
            for (const btn of buttons) {
              if (await btn.isVisible() && await btn.isEnabled()) {
                // 使用鼠标点击
                const box = await btn.boundingBox();
                if (box) {
                  const x = box.x + box.width / 2;
                  const y = box.y + box.height / 2;
                  await this.page.mouse.click(x, y);
                  publishClicked = true;
                  logger.info('[Xiaohongshu Publish] Publish button clicked via getByRole');
                  break;
                }
              }
            }
          }
        } catch (e) {
          logger.warn('[Xiaohongshu Publish] getByRole failed:', e);
        }
      }

      // 如果还是没找到，尝试用 evaluate 直接查找和点击
      if (!publishClicked) {
        logger.info('[Xiaohongshu Publish] Trying evaluate method...');
        try {
          publishClicked = await this.page.evaluate(() => {
            // 查找所有包含"发布"文字的按钮
            const buttons = Array.from(document.querySelectorAll('button, div[role="button"]'));
            for (const btn of buttons) {
              const text = btn.textContent?.trim();
              // 找到只包含"发布"两个字的按钮（排除"发布笔记"等）
              if (text === '发布' && (btn as HTMLElement).offsetParent !== null) {
                (btn as HTMLElement).click();
                return true;
              }
            }
            return false;
          });
          if (publishClicked) {
            logger.info('[Xiaohongshu Publish] Publish button clicked via evaluate');
          }
        } catch (e) {
          logger.warn('[Xiaohongshu Publish] evaluate failed:', e);
        }
      }

      if (!publishClicked) {
        // 截图调试
        try {
          if (this.page) {
            const screenshotPath = `uploads/debug/xhs_no_publish_btn_${Date.now()}.png`;
            await this.page.screenshot({ path: screenshotPath, fullPage: true });
            logger.info(`[Xiaohongshu Publish] Screenshot saved: ${screenshotPath}`);
          }
        } catch {}
        throw new Error('未找到发布按钮');
      }

      onProgress?.(90, '等待发布完成...');

      // 等待发布结果
      const publishMaxWait = 120000; // 2分钟
      const publishStartTime = Date.now();
      let aiCheckCounter = 0;
      let lastProgressCheckTime = 0;
      const progressCheckInterval = 5000; // 每5秒检测一次发布进度

      while (Date.now() - publishStartTime < publishMaxWait) {
        await this.page.waitForTimeout(3000);
        const currentUrl = this.page.url();

        // 检查是否跳转到内容管理页面
        if (currentUrl.includes('/content') || currentUrl.includes('/creator/home')) {
          logger.info('[Xiaohongshu Publish] Publish success! Redirected to content page');
          onProgress?.(100, '发布成功！');
          await this.closeBrowser();
          return {
            success: true,
            videoUrl: currentUrl,
          };
        }

        // 检查成功提示
        const successToast = await this.page.locator('[class*="success"]:has-text("成功"), [class*="toast"]:has-text("发布成功")').count();
        if (successToast > 0) {
          logger.info('[Xiaohongshu Publish] Found success toast');
          await this.page.waitForTimeout(2000);
          onProgress?.(100, '发布成功！');
          await this.closeBrowser();
          return {
            success: true,
            videoUrl: this.page.url(),
          };
        }

        // 检查发布进度条（DOM方式）
        const publishProgressText = await this.page.locator('[class*="progress"], [class*="loading"]').first().textContent().catch(() => '');
        if (publishProgressText) {
          const match = publishProgressText.match(/(\d+)%/);
          if (match) {
            const progress = parseInt(match[1]);
            onProgress?.(90 + Math.floor(progress * 0.1), `发布中: ${progress}%`);
            logger.info(`[Xiaohongshu Publish] Publish progress: ${progress}%`);
          }
        }

        // AI检测发布进度（定期检测）
        if (Date.now() - lastProgressCheckTime > progressCheckInterval) {
          lastProgressCheckTime = Date.now();
          try {
            const screenshot = await this.screenshotBase64();
            const publishStatus = await aiService.analyzePublishProgress(screenshot, 'xiaohongshu');
            logger.info(`[Xiaohongshu Publish] AI publish progress status:`, publishStatus);
            
            if (publishStatus.isComplete) {
              logger.info('[Xiaohongshu Publish] AI detected publish complete');
              onProgress?.(100, '发布成功！');
              await this.closeBrowser();
              return { success: true, videoUrl: this.page.url() };
            }
            
            if (publishStatus.isFailed) {
              throw new Error(`发布失败: ${publishStatus.statusDescription}`);
            }
            
            if (publishStatus.progress !== null) {
              onProgress?.(90 + Math.floor(publishStatus.progress * 0.1), `发布中: ${publishStatus.progress}%`);
            }
            
            if (publishStatus.isPublishing) {
              logger.info(`[Xiaohongshu Publish] Still publishing: ${publishStatus.statusDescription}`);
            }
          } catch (aiError) {
            logger.warn('[Xiaohongshu Publish] AI publish progress check failed:', aiError);
          }
        }

        // 检查错误提示
        const errorToast = await this.page.locator('[class*="error"], [class*="fail"]').first().textContent().catch(() => '');
        if (errorToast && (errorToast.includes('失败') || errorToast.includes('错误'))) {
          throw new Error(`发布失败: ${errorToast}`);
        }

        // AI 辅助检测发布状态（每隔几次循环）
        aiCheckCounter++;
        if (aiCheckCounter >= 3) {
          aiCheckCounter = 0;
          const aiStatus = await this.aiAnalyzePublishStatus();
          if (aiStatus) {
            logger.info(`[Xiaohongshu Publish] AI status: ${aiStatus.status}, confidence: ${aiStatus.confidence}%`);

            if (aiStatus.status === 'success' && aiStatus.confidence >= 70) {
              logger.info('[Xiaohongshu Publish] AI detected publish success');
              onProgress?.(100, '发布成功！');
              await this.closeBrowser();
              return {
                success: true,
                videoUrl: currentUrl,
              };
            }

            if (aiStatus.status === 'failed' && aiStatus.confidence >= 70) {
              logger.error(`[Xiaohongshu Publish] AI detected failure: ${aiStatus.errorMessage}`);
              throw new Error(aiStatus.errorMessage || 'AI 检测到发布失败');
            }

            // AI 检测到需要验证码
            if (aiStatus.status === 'need_captcha') {
              logger.warn('[Xiaohongshu Publish] AI detected captcha required');
              if (onCaptchaRequired) {
                const imageBase64 = await this.screenshotBase64();
                try {
                  const captchaCode = await onCaptchaRequired({
                    taskId: `xhs_captcha_${Date.now()}`,
                    type: aiStatus.captchaType === 'sms' ? 'sms' : 'image',
                    imageBase64,
                  });

                  if (captchaCode) {
                    const guide = await this.aiGetPublishOperationGuide('需要输入验证码');
                    if (guide?.hasAction && guide.targetSelector) {
                      await this.page.fill(guide.targetSelector, captchaCode);
                      await this.page.waitForTimeout(500);

                      const confirmGuide = await this.aiGetPublishOperationGuide('已输入验证码，需要点击确认');
                      if (confirmGuide?.hasAction && confirmGuide.targetSelector) {
                        await this.page.click(confirmGuide.targetSelector);
                      }
                    }
                  }
                } catch (captchaError) {
                  logger.error('[Xiaohongshu Publish] Captcha handling failed:', captchaError);
                }
              }
            }

            // AI 建议需要操作
            if (aiStatus.status === 'need_action' && aiStatus.nextAction) {
              logger.info(`[Xiaohongshu Publish] AI suggests action: ${aiStatus.nextAction.targetDescription}`);
              
              // 先尝试关闭可能存在的弹窗
              await this.closeModalDialogs();
              
              const guide = await this.aiGetPublishOperationGuide(aiStatus.pageDescription);
              if (guide?.hasAction) {
                await this.aiExecuteOperation(guide);
              }
            }
          }
        }

        const elapsed = Math.floor((Date.now() - publishStartTime) / 1000);
        onProgress?.(90 + Math.min(9, Math.floor(elapsed / 15)), `等待发布完成 (${elapsed}s)...`);
      }

      // 超时，使用 AI 做最后一次状态检查
      const finalAiStatus = await this.aiAnalyzePublishStatus();
      if (finalAiStatus) {
        logger.info(`[Xiaohongshu Publish] Final AI status: ${finalAiStatus.status}`);

        if (finalAiStatus.status === 'success') {
          onProgress?.(100, '发布成功！');
          await this.closeBrowser();
          return {
            success: true,
            videoUrl: this.page.url(),
          };
        }

        if (finalAiStatus.status === 'failed') {
          throw new Error(finalAiStatus.errorMessage || 'AI 检测到发布失败');
        }
      }

      // 截图调试
      try {
        if (this.page) {
          const screenshotPath = `uploads/debug/xhs_publish_timeout_${Date.now()}.png`;
          await this.page.screenshot({ path: screenshotPath, fullPage: true });
          logger.info(`[Xiaohongshu Publish] Timeout screenshot saved: ${screenshotPath}`);
        }
      } catch {}

      throw new Error('发布超时，请手动检查是否发布成功');

    } catch (error) {
      logger.error('[Xiaohongshu Publish] Error:', error);
      await this.closeBrowser();
      return {
        success: false,
        errorMessage: error instanceof Error ? error.message : '发布失败',
      };
    }
    ========== Playwright 方式已注释结束 ========== */
  }

  /**
   * 通过 Python API 获取评论
   */
  private async getCommentsViaPython(cookies: string, videoId: string): Promise<CommentData[]> {
    logger.info('[Xiaohongshu] Getting comments via Python API...');
    
    const response = await fetch(`${XHS_PYTHON_SERVICE_URL}/comments`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        platform: 'xiaohongshu',
        cookie: cookies,
        work_id: videoId,
      }),
    });
    
    if (!response.ok) {
      throw new Error(`Python API returned ${response.status}`);
    }
    
    const result = await response.json();
    
    if (!result.success) {
      throw new Error(result.error || 'Failed to get comments');
    }
    
    // 转换数据格式
    return (result.comments || []).map((comment: {
      comment_id: string;
      author_id: string;
      author_name: string;
      author_avatar: string;
      content: string;
      like_count: number;
      create_time: string;
      reply_count: number;
      replies?: Array<{
        comment_id: string;
        author_id: string;
        author_name: string;
        author_avatar: string;
        content: string;
        like_count: number;
        create_time: string;
      }>;
    }) => ({
      commentId: comment.comment_id,
      authorId: comment.author_id,
      authorName: comment.author_name,
      authorAvatar: comment.author_avatar,
      content: comment.content,
      likeCount: comment.like_count,
      commentTime: comment.create_time,
      replyCount: comment.reply_count,
      replies: comment.replies?.map((reply: {
        comment_id: string;
        author_id: string;
        author_name: string;
        author_avatar: string;
        content: string;
        like_count: number;
        create_time: string;
      }) => ({
        commentId: reply.comment_id,
        authorId: reply.author_id,
        authorName: reply.author_name,
        authorAvatar: reply.author_avatar,
        content: reply.content,
        likeCount: reply.like_count,
        commentTime: reply.create_time,
      })),
    }));
  }

  /**
   * 获取评论列表
   */
  async getComments(cookies: string, videoId: string): Promise<CommentData[]> {
    // 优先尝试使用 Python API
    const pythonAvailable = await this.checkPythonServiceAvailable();
    if (pythonAvailable) {
      logger.info('[Xiaohongshu] Python service available, using Python API for comments');
      try {
        return await this.getCommentsViaPython(cookies, videoId);
      } catch (pythonError) {
        logger.warn('[Xiaohongshu] Python API getComments failed, falling back to Playwright:', pythonError);
      }
    }
    
    // 回退到 Playwright 方式
    try {
      await this.initBrowser({ headless: true });
      await this.setCookies(cookies);

      if (!this.page) throw new Error('Page not initialized');

      const comments: CommentData[] = [];

      // 设置 API 响应监听器
      this.page.on('response', async (response) => {
        const url = response.url();
        try {
          // 监听评论列表 API
          if (url.includes('/api/sns/web/v2/comment/page') ||
            url.includes('/api/galaxy/creator/comment')) {
            const data = await response.json();
            logger.info(`[Xiaohongshu API] Comments response:`, JSON.stringify(data).slice(0, 500));

            const commentList = data?.data?.comments || data?.comments || [];
            for (const comment of commentList) {
              comments.push({
                commentId: comment.id || comment.comment_id || '',
                authorId: comment.user_info?.user_id || comment.user_id || '',
                authorName: comment.user_info?.nickname || comment.nickname || '',
                authorAvatar: comment.user_info?.image || comment.avatar || '',
                content: comment.content || '',
                likeCount: comment.like_count || 0,
                commentTime: comment.create_time || comment.time || '',
                parentCommentId: comment.target_comment_id || undefined,
              });
            }
          }
        } catch {}
      });

      // 访问评论管理页面
      await this.page.goto(`${this.contentManageUrl}?tab=comment`, {
        waitUntil: 'domcontentloaded',
        timeout: 30000,
      });

      await this.page.waitForTimeout(5000);

      await this.closeBrowser();
      return comments;

    } catch (error) {
      logger.error('Xiaohongshu getComments error:', error);
      await this.closeBrowser();
      return [];
    }
  }

  /**
   * 回复评论
   */
  async replyComment(cookies: string, commentId: string, content: string): Promise<boolean> {
    try {
      await this.initBrowser({ headless: true });
      await this.setCookies(cookies);

      if (!this.page) throw new Error('Page not initialized');

      // 访问评论管理页面
      await this.page.goto(`${this.contentManageUrl}?tab=comment`, {
        waitUntil: 'networkidle',
        timeout: 30000,
      });

      await this.page.waitForTimeout(2000);

      // 找到对应评论并点击回复
      const commentItem = this.page.locator(`[data-comment-id="${commentId}"], [data-id="${commentId}"]`).first();
      if (await commentItem.count() > 0) {
        const replyBtn = commentItem.locator('[class*="reply"], button:has-text("回复")').first();
        if (await replyBtn.count() > 0) {
          await replyBtn.click();
          await this.page.waitForTimeout(500);
        }
      }

      // 输入回复内容
      const replyInput = this.page.locator('[class*="reply-input"] textarea, [class*="comment-input"] textarea').first();
      if (await replyInput.count() > 0) {
        await replyInput.fill(content);
        await this.page.waitForTimeout(500);

        // 点击发送
        const sendBtn = this.page.locator('button:has-text("发送"), button:has-text("回复")').first();
        if (await sendBtn.count() > 0) {
          await sendBtn.click();
          await this.page.waitForTimeout(2000);
        }
      }

      await this.closeBrowser();
      return true;

    } catch (error) {
      logger.error('Xiaohongshu replyComment error:', error);
      await this.closeBrowser();
      return false;
    }
  }

  /**
   * 删除已发布的作品
   * 使用小红书笔记管理页面: https://creator.xiaohongshu.com/new/note-manager
   */
  async deleteWork(
    cookies: string,
    noteId: string,
    onCaptchaRequired?: (captchaInfo: { taskId: string; imageUrl?: string }) => Promise<string>
  ): Promise<{ success: boolean; errorMessage?: string }> {
    try {
      // 使用无头浏览器后台运行
      await this.initBrowser({ headless: true });
      await this.setCookies(cookies);

      if (!this.page) throw new Error('Page not initialized');

      logger.info(`[Xiaohongshu Delete] Starting delete for note: ${noteId}`);

      // 访问笔记管理页面（新版）
      const noteManagerUrl = 'https://creator.xiaohongshu.com/new/note-manager';
      await this.page.goto(noteManagerUrl, {
        waitUntil: 'networkidle',
        timeout: 60000,
      });

      await this.page.waitForTimeout(3000);

      // 检查是否需要登录
      const currentUrl = this.page.url();
      if (currentUrl.includes('login') || currentUrl.includes('passport')) {
        throw new Error('登录已过期，请重新登录');
      }

      logger.info(`[Xiaohongshu Delete] Current URL: ${currentUrl}`);

      // 截图用于调试
      try {
        if (this.page) {
          const screenshotPath = `uploads/debug/xhs_delete_page_${Date.now()}.png`;
          await this.page.screenshot({ path: screenshotPath, fullPage: true });
          logger.info(`[Xiaohongshu Delete] Page screenshot: ${screenshotPath}`);
        }
      } catch {}

      // 在笔记管理页面找到对应的笔记行
      // 页面结构：
      // - 每条笔记是 div.note 元素
      // - 笔记ID在 data-impression 属性的 JSON 中: noteId: "xxx"
      // - 删除按钮是 span.control.data-del 内的 <span>删除</span>
      let deleteClicked = false;
      
      // 方式1: 通过 data-impression 属性找到对应笔记，然后点击其删除按钮
      logger.info(`[Xiaohongshu Delete] Looking for note with ID: ${noteId}`);
      
      // 查找所有笔记卡片
      const noteCards = this.page.locator('div.note');
      const noteCount = await noteCards.count();
      logger.info(`[Xiaohongshu Delete] Found ${noteCount} note cards`);
      
      for (let i = 0; i < noteCount; i++) {
        const card = noteCards.nth(i);
        const impression = await card.getAttribute('data-impression').catch(() => '');
        
        // 检查 data-impression 中是否包含目标 noteId
        if (impression && impression.includes(noteId)) {
          logger.info(`[Xiaohongshu Delete] Found target note at index ${i}`);
          
          // 在该笔记卡片内查找删除按钮 (span.data-del)
          const deleteBtn = card.locator('span.data-del, span.control.data-del').first();
          if (await deleteBtn.count() > 0) {
            await deleteBtn.click();
            deleteClicked = true;
            logger.info(`[Xiaohongshu Delete] Clicked delete button for note ${noteId}`);
            break;
          }
        }
      }

      // 方式2: 如果方式1没找到，尝试直接用 evaluate 在 DOM 中查找
      if (!deleteClicked) {
        logger.info('[Xiaohongshu Delete] Trying evaluate method to find note by data-impression...');
        deleteClicked = await this.page.evaluate((nid: string) => {
          // 查找所有 div.note 元素
          const notes = document.querySelectorAll('div.note');
          console.log(`[XHS Delete] Found ${notes.length} note elements`);
          
          for (const note of notes) {
            const impression = note.getAttribute('data-impression') || '';
            if (impression.includes(nid)) {
              console.log(`[XHS Delete] Found note with ID ${nid}`);
              
              // 查找删除按钮
              const deleteBtn = note.querySelector('span.data-del') || 
                               note.querySelector('.control.data-del');
              if (deleteBtn) {
                console.log(`[XHS Delete] Clicking delete button`);
                (deleteBtn as HTMLElement).click();
                return true;
              }
            }
          }
          
          return false;
        }, noteId);
        
        if (deleteClicked) {
          logger.info('[Xiaohongshu Delete] Delete button clicked via evaluate');
        }
      }
      
      // 方式3: 如果还没找到，尝试点击第一个可见的删除按钮
      if (!deleteClicked) {
        logger.info('[Xiaohongshu Delete] Trying to click first visible delete button...');
        
        const allDeleteBtns = this.page.locator('span.data-del');
        const btnCount = await allDeleteBtns.count();
        logger.info(`[Xiaohongshu Delete] Found ${btnCount} delete buttons on page`);
        
        for (let i = 0; i < btnCount; i++) {
          const btn = allDeleteBtns.nth(i);
          if (await btn.isVisible().catch(() => false)) {
            await btn.click();
            deleteClicked = true;
            logger.info(`[Xiaohongshu Delete] Clicked delete button ${i}`);
            break;
          }
        }
      }

      if (!deleteClicked) {
        // 截图调试
        try {
          if (this.page) {
            const screenshotPath = `uploads/debug/xhs_delete_no_btn_${Date.now()}.png`;
            await this.page.screenshot({ path: screenshotPath, fullPage: true });
            logger.info(`[Xiaohongshu Delete] No delete button found, screenshot: ${screenshotPath}`);
          }
        } catch {}
        throw new Error('未找到删除按钮');
      }

      await this.page.waitForTimeout(1000);

      // 检查是否需要验证码
      const captchaVisible = await this.page.locator('[class*="captcha"], [class*="verify"]').count() > 0;

      if (captchaVisible && onCaptchaRequired) {
        logger.info('[Xiaohongshu Delete] Captcha required');

        // 点击发送验证码
        const sendCodeBtn = this.page.locator('button:has-text("发送验证码"), button:has-text("获取验证码")').first();
        if (await sendCodeBtn.count() > 0) {
          await sendCodeBtn.click();
          logger.info('[Xiaohongshu Delete] Verification code sent');
        }

        // 通过回调获取验证码
        const taskId = `delete_xhs_${noteId}_${Date.now()}`;
        const code = await onCaptchaRequired({ taskId });

        if (code) {
          // 输入验证码
          const codeInput = this.page.locator('input[placeholder*="验证码"], input[type="text"]').first();
          if (await codeInput.count() > 0) {
            await codeInput.fill(code);
            logger.info('[Xiaohongshu Delete] Verification code entered');
          }

          // 点击确认按钮
          const confirmBtn = this.page.locator('button:has-text("确定"), button:has-text("确认")').first();
          if (await confirmBtn.count() > 0) {
            await confirmBtn.click();
            await this.page.waitForTimeout(2000);
          }
        }
      }

      // 确认删除（可能有二次确认弹窗）
      const confirmDeleteSelectors = [
        'button:has-text("确认删除")',
        'button:has-text("确定")',
        'button:has-text("确认")',
        '[class*="modal"] button[class*="primary"]',
        '[class*="dialog"] button[class*="confirm"]',
        '.d-button.red:has-text("确")',
      ];

      for (const selector of confirmDeleteSelectors) {
        const confirmBtn = this.page.locator(selector).first();
        if (await confirmBtn.count() > 0 && await confirmBtn.isVisible()) {
          await confirmBtn.click();
          logger.info(`[Xiaohongshu Delete] Confirm button clicked via: ${selector}`);
          await this.page.waitForTimeout(1000);
        }
      }

      // 等待删除完成
      await this.page.waitForTimeout(2000);

      // 检查是否删除成功（页面刷新或出现成功提示）
      const successToast = await this.page.locator('[class*="success"]:has-text("成功"), [class*="toast"]:has-text("删除成功")').count();
      if (successToast > 0) {
        logger.info('[Xiaohongshu Delete] Delete success toast found');
      }

      logger.info('[Xiaohongshu Delete] Delete completed');
      await this.closeBrowser();

      return { success: true };

    } catch (error) {
      logger.error('[Xiaohongshu Delete] Error:', error);
      await this.closeBrowser();
      return {
        success: false,
        errorMessage: error instanceof Error ? error.message : '删除失败',
      };
    }
  }

  /**
   * 获取数据统计
   */
  async getAnalytics(cookies: string, dateRange: DateRange): Promise<AnalyticsData> {
    try {
      await this.initBrowser({ headless: true });
      await this.setCookies(cookies);

      if (!this.page) throw new Error('Page not initialized');

      const analytics: AnalyticsData = {
        fansCount: 0,
        fansIncrease: 0,
        viewsCount: 0,
        likesCount: 0,
        commentsCount: 0,
        sharesCount: 0,
      };

      // 设置 API 响应监听器
      this.page.on('response', async (response) => {
        const url = response.url();
        try {
          if (url.includes('/api/galaxy/creator/data') ||
            url.includes('/api/galaxy/creator/home')) {
            const data = await response.json();
            if (data?.data) {
              const d = data.data;
              analytics.fansCount = d.fans_count || analytics.fansCount;
              analytics.fansIncrease = d.fans_increase || analytics.fansIncrease;
              analytics.viewsCount = d.view_count || d.read_count || analytics.viewsCount;
              analytics.likesCount = d.like_count || analytics.likesCount;
              analytics.commentsCount = d.comment_count || analytics.commentsCount;
              analytics.sharesCount = d.collect_count || analytics.sharesCount;
            }
          }
        } catch {}
      });

      // 访问数据中心
      await this.page.goto('https://creator.xiaohongshu.com/creator/data', {
        waitUntil: 'domcontentloaded',
        timeout: 30000,
      });

      await this.page.waitForTimeout(5000);
      await this.closeBrowser();

      return analytics;

    } catch (error) {
      logger.error('Xiaohongshu getAnalytics error:', error);
      await this.closeBrowser();
      return {
        fansCount: 0,
        fansIncrease: 0,
        viewsCount: 0,
        likesCount: 0,
        commentsCount: 0,
        sharesCount: 0,
      };
    }
  }
}
