import type { Page } from 'playwright';
import { promises as fs } from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import { logger } from '../utils/logger.js';
import { config } from '../config/index.js';
import {
  aiService,
  type LoginStatusAnalysis,
  type AccountInfoExtraction,
  type PageOperationGuide,
} from '../ai/index.js';
import type { PlatformType } from '@media-manager/shared';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const DEBUG_SCREENSHOT_DIR = path.join(__dirname, '../../uploads/debug');

/**
 * AI 登录状态监控结果
 */
export interface AILoginMonitorResult {
  status: 'pending' | 'logged_in' | 'verification_needed' | 'error';
  analysis: LoginStatusAnalysis;
  screenshotBase64?: string;
}

/**
 * AI 账号信息获取结果
 */
export interface AIAccountInfoResult {
  success: boolean;
  accountInfo?: AccountInfoExtraction;
  needNavigation: boolean;
  navigationGuide?: PageOperationGuide;
}

/**
 * AI 登录辅助服务
 * 使用千问视觉模型分析登录页面状态
 */
export class AILoginAssistant {
  private platform: PlatformType;
  private page: Page;
  private sessionId: string;
  private isMonitoring: boolean = false;
  private isAnalyzing: boolean = false; // 请求锁，防止并发请求
  private maxAnalysisAttempts: number = 30; // 最多分析30次
  private analysisCount: number = 0;
  private waitAfterResponseMs: number = 3000; // API 返回后等待时间（3秒）
  private initialDelayMs: number = 3000; // 首次分析前等待时间（3秒）
  private savedScreenshots: string[] = []; // 保存的截图文件路径列表
  private isDevelopment: boolean;

  constructor(page: Page, platform: PlatformType, sessionId?: string) {
    this.page = page;
    this.platform = platform;
    this.sessionId = sessionId || `session_${Date.now()}`;
    this.isDevelopment = config.env === 'development';
  }

  /**
   * 确保 debug 截图目录存在
   */
  private async ensureDebugDir(): Promise<void> {
    if (!this.isDevelopment) return;
    
    try {
      await fs.mkdir(DEBUG_SCREENSHOT_DIR, { recursive: true });
    } catch (error) {
      logger.warn('[AILoginAssistant] Failed to create debug directory:', error);
    }
  }

  /**
   * 保存截图到 debug 目录（仅开发模式）
   */
  private async saveScreenshotToDebug(base64Data: string, suffix: string = ''): Promise<string | null> {
    if (!this.isDevelopment) return null;

    try {
      await this.ensureDebugDir();
      
      const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
      const filename = `${this.platform}_${this.sessionId}_${timestamp}${suffix}.jpg`;
      const filepath = path.join(DEBUG_SCREENSHOT_DIR, filename);
      
      const buffer = Buffer.from(base64Data, 'base64');
      await fs.writeFile(filepath, buffer);
      
      this.savedScreenshots.push(filepath);
      logger.info(`[AILoginAssistant] Screenshot saved: ${filename}`);
      
      return filepath;
    } catch (error) {
      logger.warn('[AILoginAssistant] Failed to save screenshot:', error);
      return null;
    }
  }

  /**
   * 清理所有保存的截图（生产环境自动调用，或手动调用）
   */
  async cleanupScreenshots(): Promise<void> {
    if (this.savedScreenshots.length === 0) return;

    logger.info(`[AILoginAssistant] Cleaning up ${this.savedScreenshots.length} screenshots...`);
    
    for (const filepath of this.savedScreenshots) {
      try {
        await fs.unlink(filepath);
        logger.debug(`[AILoginAssistant] Deleted screenshot: ${filepath}`);
      } catch (error) {
        // 文件可能已经被删除，忽略错误
        logger.debug(`[AILoginAssistant] Failed to delete screenshot: ${filepath}`);
      }
    }
    
    this.savedScreenshots = [];
  }

  /**
   * 检查 AI 服务是否可用
   */
  isAIAvailable(): boolean {
    return aiService.isAvailable();
  }

  /**
   * 截取当前页面截图并转换为 Base64
   * @param saveToDebug 是否保存到 debug 目录（仅开发模式有效）
   * @param suffix 文件名后缀
   */
  async captureScreenshot(saveToDebug: boolean = true, suffix: string = ''): Promise<string> {
    try {
      const screenshot = await this.page.screenshot({
        type: 'jpeg',
        quality: 80,
        fullPage: false,
      });
      const base64Data = screenshot.toString('base64');
      
      // 开发模式下保存截图到 debug 目录
      if (saveToDebug && this.isDevelopment) {
        await this.saveScreenshotToDebug(base64Data, suffix);
      }
      
      return base64Data;
    } catch (error) {
      logger.error('[AILoginAssistant] Failed to capture screenshot:', error);
      throw error;
    }
  }

  /**
   * 分析当前页面的登录状态
   * @param analysisIndex 分析序号（用于截图文件命名）
   */
  async analyzeCurrentPage(analysisIndex?: number): Promise<AILoginMonitorResult> {
    if (!this.isAIAvailable()) {
      return {
        status: 'error',
        analysis: {
          isLoggedIn: false,
          hasVerification: false,
          pageDescription: 'AI 服务不可用',
        },
      };
    }

    try {
      // 截图文件名后缀：包含分析序号
      const suffix = analysisIndex !== undefined ? `_analysis_${String(analysisIndex).padStart(3, '0')}` : '';
      const screenshotBase64 = await this.captureScreenshot(true, suffix);
      logger.info(`[AILoginAssistant] Analyzing page for platform: ${this.platform}`);

      const analysis = await aiService.analyzeLoginStatus(screenshotBase64, this.platform);

      logger.info(`[AILoginAssistant] Analysis result:`, {
        isLoggedIn: analysis.isLoggedIn,
        hasVerification: analysis.hasVerification,
        verificationType: analysis.verificationType,
        pageDescription: analysis.pageDescription?.substring(0, 100),
      });

      let status: AILoginMonitorResult['status'] = 'pending';
      if (analysis.isLoggedIn) {
        status = 'logged_in';
      } else if (analysis.hasVerification) {
        status = 'verification_needed';
      }

      return {
        status,
        analysis,
        screenshotBase64,
      };
    } catch (error) {
      logger.error('[AILoginAssistant] Analysis error:', error);
      return {
        status: 'error',
        analysis: {
          isLoggedIn: false,
          hasVerification: false,
          pageDescription: `分析出错: ${error instanceof Error ? error.message : '未知错误'}`,
        },
      };
    }
  }

  /**
   * 开始监控登录状态
   * 使用异步循环确保等待 API 返回后再等待指定时间，防止并发请求
   * @param onStatusChange 状态变化回调
   * @param waitAfterResponseMs API 返回后等待时间（毫秒），默认3000ms
   */
  startMonitoring(
    onStatusChange: (result: AILoginMonitorResult) => void,
    waitAfterResponseMs: number = 3000
  ): void {
    if (this.isMonitoring) {
      logger.warn('[AILoginAssistant] Already monitoring');
      return;
    }

    if (!this.isAIAvailable()) {
      logger.warn('[AILoginAssistant] AI service not available, skipping AI monitoring');
      return;
    }

    this.isMonitoring = true;
    this.analysisCount = 0;
    this.waitAfterResponseMs = waitAfterResponseMs;
    logger.info(`[AILoginAssistant] Starting login status monitoring for ${this.platform}, wait after response: ${waitAfterResponseMs}ms`);

    // 使用异步循环代替 setInterval，确保顺序执行
    this.runMonitorLoop(onStatusChange);
  }

  /**
   * 监控循环（异步，确保顺序执行）
   */
  private async runMonitorLoop(onStatusChange: (result: AILoginMonitorResult) => void): Promise<void> {
    // 首次分析前等待页面加载
    logger.info(`[AILoginAssistant] Waiting ${this.initialDelayMs}ms before first analysis...`);
    await this.sleep(this.initialDelayMs);

    while (this.isMonitoring) {
      // 检查分析次数上限
      if (this.analysisCount >= this.maxAnalysisAttempts) {
        logger.warn(`[AILoginAssistant] Max analysis attempts (${this.maxAnalysisAttempts}) reached, stopping`);
        this.stopMonitoring();
        return;
      }

      // 检查是否已有请求在进行中（双重保险）
      if (this.isAnalyzing) {
        logger.warn('[AILoginAssistant] Analysis already in progress, waiting...');
        await this.sleep(1000);
        continue;
      }

      try {
        this.isAnalyzing = true;
        this.analysisCount++;
        
        logger.info(`[AILoginAssistant] Starting analysis #${this.analysisCount}...`);
        const startTime = Date.now();
        
        // 传递分析序号用于截图命名
        const result = await this.analyzeCurrentPage(this.analysisCount);
        
        const duration = Date.now() - startTime;
        logger.info(`[AILoginAssistant] Analysis #${this.analysisCount} completed in ${duration}ms`);
        
        // 调用回调
        onStatusChange(result);

        // 如果登录成功，停止监控，并清理截图（生产环境）
        if (result.status === 'logged_in') {
          logger.info('[AILoginAssistant] Login detected, stopping monitoring');
          this.stopMonitoring();
          // 生产环境下清理截图
          if (!this.isDevelopment) {
            await this.cleanupScreenshots();
          }
          return;
        }

      } catch (error) {
        logger.error(`[AILoginAssistant] Monitor iteration #${this.analysisCount} error:`, error);
      } finally {
        this.isAnalyzing = false;
      }

      // 如果仍在监控，等待指定时间后再进行下一次分析
      if (this.isMonitoring) {
        logger.info(`[AILoginAssistant] Waiting ${this.waitAfterResponseMs}ms before next analysis...`);
        await this.sleep(this.waitAfterResponseMs);
      }
    }
  }

  /**
   * 休眠指定时间
   */
  private sleep(ms: number): Promise<void> {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  /**
   * 停止监控
   */
  stopMonitoring(): void {
    this.isMonitoring = false;
    logger.info(`[AILoginAssistant] Monitoring stopped after ${this.analysisCount} analyses`);
  }

  /**
   * 获取账号信息（带智能导航）
   * @param maxAttempts 最大尝试次数
   */
  async getAccountInfoWithAI(maxAttempts: number = 5): Promise<AIAccountInfoResult> {
    if (!this.isAIAvailable()) {
      return {
        success: false,
        needNavigation: false,
      };
    }

    for (let attempt = 0; attempt < maxAttempts; attempt++) {
      logger.info(`[AILoginAssistant] Attempting to get account info (attempt ${attempt + 1}/${maxAttempts})`);

      try {
        // 等待页面稳定
        await this.page.waitForTimeout(1000);

        // 截图并分析
        const screenshotBase64 = await this.captureScreenshot();
        const accountInfo = await aiService.extractAccountInfo(screenshotBase64, this.platform);

        logger.info(`[AILoginAssistant] Account info extraction result:`, {
          found: accountInfo.found,
          accountName: accountInfo.accountName,
          hasNavigationSuggestion: !!accountInfo.navigationSuggestion,
        });

        if (accountInfo.found && accountInfo.accountName) {
          return {
            success: true,
            accountInfo,
            needNavigation: false,
          };
        }

        // 如果没找到账号信息，尝试获取导航指导
        if (accountInfo.navigationSuggestion) {
          logger.info(`[AILoginAssistant] Navigation suggestion: ${accountInfo.navigationSuggestion}`);

          // 获取具体的操作指导
          const guide = await aiService.getPageOperationGuide(
            screenshotBase64,
            this.platform,
            '获取账号信息（用户名、头像、粉丝数等）'
          );

          logger.info(`[AILoginAssistant] Operation guide:`, {
            hasAction: guide.hasAction,
            actionType: guide.actionType,
            targetDescription: guide.targetDescription,
            explanation: guide.explanation,
          });

          if (guide.hasAction) {
            // 尝试执行操作
            const executed = await this.executeOperation(guide);
            if (executed) {
              // 等待页面更新后继续下一次尝试
              await this.page.waitForTimeout(2000);
              continue;
            }
          }

          return {
            success: false,
            accountInfo,
            needNavigation: true,
            navigationGuide: guide,
          };
        }

        // 没有导航建议，返回失败
        return {
          success: false,
          accountInfo,
          needNavigation: false,
        };
      } catch (error) {
        logger.error(`[AILoginAssistant] Get account info error (attempt ${attempt + 1}):`, error);
      }
    }

    return {
      success: false,
      needNavigation: false,
    };
  }

  /**
   * 执行 AI 指导的页面操作
   * @param guide 操作指导
   * @returns 是否成功执行
   */
  async executeOperation(guide: PageOperationGuide): Promise<boolean> {
    if (!guide.hasAction) {
      return false;
    }

    try {
      switch (guide.actionType) {
        case 'click':
          return await this.executeClick(guide);

        case 'input':
          return await this.executeInput(guide);

        case 'scroll':
          return await this.executeScroll(guide);

        case 'wait':
          await this.page.waitForTimeout(2000);
          return true;

        case 'navigate':
          // 导航操作需要用户手动处理
          logger.info(`[AILoginAssistant] Navigation required: ${guide.explanation}`);
          return false;

        default:
          logger.warn(`[AILoginAssistant] Unknown action type: ${guide.actionType}`);
          return false;
      }
    } catch (error) {
      logger.error('[AILoginAssistant] Execute operation error:', error);
      return false;
    }
  }

  /**
   * 执行点击操作
   */
  private async executeClick(guide: PageOperationGuide): Promise<boolean> {
    // 优先使用选择器
    if (guide.targetSelector) {
      try {
        const element = this.page.locator(guide.targetSelector).first();
        if (await element.count() > 0 && await element.isVisible()) {
          await element.click();
          logger.info(`[AILoginAssistant] Clicked element with selector: ${guide.targetSelector}`);
          return true;
        }
      } catch (e) {
        logger.warn(`[AILoginAssistant] Failed to click by selector: ${guide.targetSelector}`, e);
      }
    }

    // 尝试使用文本内容定位
    if (guide.targetDescription) {
      try {
        // 尝试常见的可点击元素
        const textVariants = [
          guide.targetDescription,
          guide.targetDescription.replace(/["""]/g, ''),
        ];

        for (const text of textVariants) {
          // 尝试精确匹配
          let element = this.page.getByText(text, { exact: true }).first();
          if (await element.count() > 0 && await element.isVisible().catch(() => false)) {
            await element.click();
            logger.info(`[AILoginAssistant] Clicked element with text: ${text}`);
            return true;
          }

          // 尝试模糊匹配
          element = this.page.getByText(text, { exact: false }).first();
          if (await element.count() > 0 && await element.isVisible().catch(() => false)) {
            await element.click();
            logger.info(`[AILoginAssistant] Clicked element with fuzzy text: ${text}`);
            return true;
          }

          // 尝试作为按钮或链接
          element = this.page.getByRole('button', { name: text }).first();
          if (await element.count() > 0 && await element.isVisible().catch(() => false)) {
            await element.click();
            logger.info(`[AILoginAssistant] Clicked button with name: ${text}`);
            return true;
          }

          element = this.page.getByRole('link', { name: text }).first();
          if (await element.count() > 0 && await element.isVisible().catch(() => false)) {
            await element.click();
            logger.info(`[AILoginAssistant] Clicked link with name: ${text}`);
            return true;
          }
        }
      } catch (e) {
        logger.warn(`[AILoginAssistant] Failed to click by text: ${guide.targetDescription}`, e);
      }
    }

    // 最后尝试坐标点击
    if (guide.targetPosition) {
      try {
        await this.page.mouse.click(guide.targetPosition.x, guide.targetPosition.y);
        logger.info(`[AILoginAssistant] Clicked at position: (${guide.targetPosition.x}, ${guide.targetPosition.y})`);
        return true;
      } catch (e) {
        logger.warn(`[AILoginAssistant] Failed to click at position`, e);
      }
    }

    logger.warn('[AILoginAssistant] Could not execute click operation');
    return false;
  }

  /**
   * 执行输入操作
   */
  private async executeInput(guide: PageOperationGuide): Promise<boolean> {
    if (!guide.inputText) {
      return false;
    }

    // 尝试使用选择器
    if (guide.targetSelector) {
      try {
        const element = this.page.locator(guide.targetSelector).first();
        if (await element.count() > 0 && await element.isVisible()) {
          await element.fill(guide.inputText);
          logger.info(`[AILoginAssistant] Input text to selector: ${guide.targetSelector}`);
          return true;
        }
      } catch (e) {
        logger.warn(`[AILoginAssistant] Failed to input by selector`, e);
      }
    }

    // 尝试查找输入框
    try {
      const inputs = this.page.locator('input:visible, textarea:visible');
      const count = await inputs.count();
      if (count > 0) {
        await inputs.first().fill(guide.inputText);
        logger.info(`[AILoginAssistant] Input text to first visible input`);
        return true;
      }
    } catch (e) {
      logger.warn(`[AILoginAssistant] Failed to input to visible input`, e);
    }

    return false;
  }

  /**
   * 执行滚动操作
   */
  private async executeScroll(guide: PageOperationGuide): Promise<boolean> {
    try {
      // 默认向下滚动
      await this.page.mouse.wheel(0, 300);
      logger.info('[AILoginAssistant] Scrolled page');
      return true;
    } catch (e) {
      logger.warn('[AILoginAssistant] Failed to scroll', e);
      return false;
    }
  }

  /**
   * 销毁实例
   * @param cleanupScreenshots 是否清理截图（默认生产环境清理）
   */
  async destroy(cleanupScreenshots?: boolean): Promise<void> {
    this.stopMonitoring();
    
    // 根据参数或环境决定是否清理截图
    const shouldCleanup = cleanupScreenshots !== undefined ? cleanupScreenshots : !this.isDevelopment;
    if (shouldCleanup) {
      await this.cleanupScreenshots();
    } else if (this.savedScreenshots.length > 0) {
      logger.info(`[AILoginAssistant] Development mode: ${this.savedScreenshots.length} screenshots saved to debug directory`);
    }
  }
}
