import { AppDataSource, Work, PlatformAccount, Comment } from '../models/index.js';
import { AppError } from '../middleware/error.js';
import { ERROR_CODES, HTTP_STATUS } from '@media-manager/shared';
import type { PlatformType, Work as WorkType, WorkStats, WorksQueryParams } from '@media-manager/shared';
import { logger } from '../utils/logger.js';
import { headlessBrowserService } from './HeadlessBrowserService.js';
import { CookieManager } from '../automation/cookie.js';
import { WorkDayStatisticsService } from './WorkDayStatisticsService.js';

export class WorkService {
  private workRepository = AppDataSource.getRepository(Work);
  private accountRepository = AppDataSource.getRepository(PlatformAccount);

  /**
   * 获取作品列表
   */
  async getWorks(userId: number, params: WorksQueryParams): Promise<{ items: WorkType[]; total: number }> {
    const queryBuilder = this.workRepository
      .createQueryBuilder('work')
      .where('work.userId = :userId', { userId });

    if (params.accountId) {
      queryBuilder.andWhere('work.accountId = :accountId', { accountId: params.accountId });
    }
    if (params.platform) {
      queryBuilder.andWhere('work.platform = :platform', { platform: params.platform });
    }
    if (params.status) {
      queryBuilder.andWhere('work.status = :status', { status: params.status });
    }
    if (params.keyword) {
      queryBuilder.andWhere('work.title LIKE :keyword', { keyword: `%${params.keyword}%` });
    }

    const page = params.page || 1;
    const pageSize = params.pageSize || 12;

    const [items, total] = await queryBuilder
      .orderBy('work.publishTime', 'DESC')
      .skip((page - 1) * pageSize)
      .take(pageSize)
      .getManyAndCount();

    return {
      items: items.map(this.formatWork),
      total,
    };
  }

  /**
   * 获取作品统计
   */
  async getStats(userId: number): Promise<WorkStats> {
    const result = await this.workRepository
      .createQueryBuilder('work')
      .select([
        'COUNT(*) as totalCount',
        'SUM(CASE WHEN status = "published" THEN 1 ELSE 0 END) as publishedCount',
        'SUM(play_count) as totalPlayCount',
        'SUM(like_count) as totalLikeCount',
        'SUM(comment_count) as totalCommentCount',
      ])
      .where('work.userId = :userId', { userId })
      .getRawOne();

    return {
      totalCount: parseInt(result.totalCount) || 0,
      publishedCount: parseInt(result.publishedCount) || 0,
      totalPlayCount: parseInt(result.totalPlayCount) || 0,
      totalLikeCount: parseInt(result.totalLikeCount) || 0,
      totalCommentCount: parseInt(result.totalCommentCount) || 0,
    };
  }

  /**
   * 获取单个作品
   */
  async getWorkById(userId: number, workId: number): Promise<WorkType> {
    const work = await this.workRepository.findOne({
      where: { id: workId, userId },
    });
    if (!work) {
      throw new AppError('作品不存在', HTTP_STATUS.NOT_FOUND, ERROR_CODES.NOT_FOUND);
    }
    return this.formatWork(work);
  }

  /**
   * 同步账号的作品
   */
  async syncWorks(userId: number, accountId?: number): Promise<{ synced: number; accounts: number }> {
    logger.info(`[SyncWorks] Starting sync for userId: ${userId}, accountId: ${accountId || 'all'}`);
    
    // 先查看所有账号（调试用）
    const allAccounts = await this.accountRepository.find({ where: { userId } });
    logger.info(`[SyncWorks] All accounts for user ${userId}: ${allAccounts.map(a => `id=${a.id},status=${a.status},platform=${a.platform}`).join('; ')}`);
    
    // 同时查询 active 和 expired 状态的账号（expired 的账号 cookie 可能实际上还有效）
    const queryBuilder = this.accountRepository
      .createQueryBuilder('account')
      .where('account.userId = :userId', { userId })
      .andWhere('account.status IN (:...statuses)', { statuses: ['active', 'expired'] });

    if (accountId) {
      queryBuilder.andWhere('account.id = :accountId', { accountId });
    }

    const accounts = await queryBuilder.getMany();
    logger.info(`[SyncWorks] Found ${accounts.length} accounts (active + expired)`);
    
    let totalSynced = 0;
    let accountCount = 0;

    for (const account of accounts) {
      try {
        logger.info(`[SyncWorks] Syncing account ${account.id} (${account.platform}, status: ${account.status})`);
        const synced = await this.syncAccountWorks(userId, account);
        totalSynced += synced;
        accountCount++;
        logger.info(`[SyncWorks] Account ${account.id} synced ${synced} works`);
        
        // 如果同步成功且账号状态是 expired，则恢复为 active
        if (synced > 0 && account.status === 'expired') {
          await this.accountRepository.update(account.id, { status: 'active' });
          logger.info(`[SyncWorks] Account ${account.id} status restored to active`);
        }
      } catch (error) {
        logger.error(`Failed to sync works for account ${account.id}:`, error);
      }
    }

    logger.info(`[SyncWorks] Complete: ${totalSynced} works synced from ${accountCount} accounts`);
    return { synced: totalSynced, accounts: accountCount };
  }

  /**
   * 同步单个账号的作品
   */
  private async syncAccountWorks(userId: number, account: PlatformAccount): Promise<number> {
    logger.info(`[SyncAccountWorks] Starting for account ${account.id} (${account.platform})`);
    
    if (!account.cookieData) {
      logger.warn(`Account ${account.id} has no cookie data`);
      return 0;
    }

    // 解密 Cookie
    let decryptedCookies: string;
    try {
      decryptedCookies = CookieManager.decrypt(account.cookieData);
      logger.info(`[SyncAccountWorks] Cookie decrypted successfully`);
    } catch {
      decryptedCookies = account.cookieData;
      logger.info(`[SyncAccountWorks] Using raw cookie data`);
    }

    // 解析 Cookie - 支持两种格式
    const platform = account.platform as PlatformType;
    let cookieList: { name: string; value: string; domain: string; path: string }[];
    try {
      // 先尝试 JSON 格式
      cookieList = JSON.parse(decryptedCookies);
      logger.info(`[SyncAccountWorks] Parsed ${cookieList.length} cookies from JSON format`);
    } catch {
      // 如果 JSON 解析失败，尝试解析 "name=value; name2=value2" 格式
      cookieList = this.parseCookieString(decryptedCookies, platform);
      logger.info(`[SyncAccountWorks] Parsed ${cookieList.length} cookies from string format`);
      if (cookieList.length === 0) {
        logger.error(`Invalid cookie format for account ${account.id}`);
        return 0;
      }
    }

    // 获取作品列表
    logger.info(`[SyncAccountWorks] Fetching account info from ${platform}...`);
    const accountInfo = await headlessBrowserService.fetchAccountInfo(platform, cookieList);
    logger.info(`[SyncAccountWorks] Got ${accountInfo.worksList?.length || 0} works from API`);

    let syncedCount = 0;
    
    // 收集远程作品的 platformVideoId
    const remotePlatformVideoIds = new Set<string>();

    if (accountInfo.worksList && accountInfo.worksList.length > 0) {
      for (const workItem of accountInfo.worksList) {
        // 生成一个唯一的视频ID
        const platformVideoId = workItem.videoId || `${platform}_${workItem.title}_${workItem.publishTime}`.substring(0, 100);
        remotePlatformVideoIds.add(platformVideoId);

        // 查找是否已存在
        const existingWork = await this.workRepository.findOne({
          where: { accountId: account.id, platformVideoId },
        });

        if (existingWork) {
          // 更新现有作品
          await this.workRepository.update(existingWork.id, {
            title: workItem.title || existingWork.title,
            coverUrl: workItem.coverUrl || existingWork.coverUrl,
            duration: workItem.duration || existingWork.duration,
            status: workItem.status || existingWork.status,
            playCount: workItem.playCount ?? existingWork.playCount,
            likeCount: workItem.likeCount ?? existingWork.likeCount,
            commentCount: workItem.commentCount ?? existingWork.commentCount,
            shareCount: workItem.shareCount ?? existingWork.shareCount,
          });
        } else {
          // 创建新作品
          const work = this.workRepository.create({
            userId,
            accountId: account.id,
            platform,
            platformVideoId,
            title: workItem.title || '',
            coverUrl: workItem.coverUrl || '',
            duration: workItem.duration || '00:00',
            status: this.normalizeStatus(workItem.status),
            publishTime: this.parsePublishTime(workItem.publishTime),
            playCount: workItem.playCount || 0,
            likeCount: workItem.likeCount || 0,
            commentCount: workItem.commentCount || 0,
            shareCount: workItem.shareCount || 0,
          });

          await this.workRepository.save(work);
        }
        syncedCount++;
      }

      logger.info(`Synced ${syncedCount} works for account ${account.id}`);
    }

    // 删除本地存在但远程已删除的作品
    const localWorks = await this.workRepository.find({
      where: { accountId: account.id },
    });
    
    let deletedCount = 0;
    for (const localWork of localWorks) {
      if (!remotePlatformVideoIds.has(localWork.platformVideoId)) {
        // 先删除关联的评论
        await AppDataSource.getRepository(Comment).delete({ workId: localWork.id });
        // 再删除作品
        await this.workRepository.delete(localWork.id);
        deletedCount++;
        logger.info(`Deleted work ${localWork.id} (${localWork.title}) - no longer exists on platform`);
      }
    }
    
    if (deletedCount > 0) {
      logger.info(`Deleted ${deletedCount} works that no longer exist on platform for account ${account.id}`);
    }

    // 保存每日统计数据
    try {
      await this.saveWorkDayStatistics(account);
    } catch (error) {
      logger.error(`[SyncAccountWorks] Failed to save day statistics for account ${account.id}:`, error);
    }

    return syncedCount;
  }

  /**
   * 保存作品每日统计数据
   */
  private async saveWorkDayStatistics(account: PlatformAccount): Promise<void> {
    // 获取该账号下所有作品
    const works = await this.workRepository.find({
      where: { accountId: account.id },
    });

    if (works.length === 0) {
      logger.info(`[SaveWorkDayStatistics] No works found for account ${account.id}`);
      return;
    }

    // 构建统计数据列表（不再包含粉丝数，粉丝数从 user_day_statistics 表获取）
    const statisticsList = works.map(work => ({
      workId: work.id,
      playCount: work.playCount || 0,
      likeCount: work.likeCount || 0,
      commentCount: work.commentCount || 0,
      shareCount: work.shareCount || 0,
      collectCount: work.collectCount || 0,
    }));

    logger.info(`[SaveWorkDayStatistics] Saving ${statisticsList.length} work statistics for account ${account.id}`);

    // 直接使用 WorkDayStatisticsService 保存统计数据
    try {
      const workDayStatisticsService = new WorkDayStatisticsService();
      const result = await workDayStatisticsService.saveStatistics(statisticsList);

      logger.info(`[SaveWorkDayStatistics] Success: inserted=${result.inserted}, updated=${result.updated}`);
    } catch (error) {
      logger.error(`[SaveWorkDayStatistics] Failed to save statistics:`, error);
      throw error;
    }
  }

  /**
   * 标准化状态
   */
  private normalizeStatus(status: string): string {
    const statusMap: Record<string, string> = {
      '已发布': 'published',
      '审核中': 'reviewing',
      '未通过': 'rejected',
      '草稿': 'draft',
      'published': 'published',
      'reviewing': 'reviewing',
      'rejected': 'rejected',
      'draft': 'draft',
    };
    return statusMap[status] || 'published';
  }

  /**
   * 解析发布时间
   */
  private parsePublishTime(timeStr: string): Date | null {
    if (!timeStr) return null;
    
    // 尝试解析各种格式
    // 格式: "2025年12月19日 06:33"
    const match = timeStr.match(/(\d{4})年(\d{1,2})月(\d{1,2})日\s*(\d{1,2}):(\d{2})/);
    if (match) {
      const [, year, month, day, hour, minute] = match;
      return new Date(parseInt(year), parseInt(month) - 1, parseInt(day), parseInt(hour), parseInt(minute));
    }
    
    // 尝试直接解析
    const date = new Date(timeStr);
    if (!isNaN(date.getTime())) {
      return date;
    }
    
    return null;
  }

  /**
   * 删除本地作品记录
   */
  async deleteWork(userId: number, workId: number): Promise<void> {
    const work = await this.workRepository.findOne({
      where: { id: workId, userId },
    });
    
    if (!work) {
      throw new AppError('作品不存在', HTTP_STATUS.NOT_FOUND, ERROR_CODES.NOT_FOUND);
    }
    
    // 先删除关联的评论
    await AppDataSource.getRepository(Comment).delete({ workId });
    
    // 删除作品
    await this.workRepository.delete(workId);
    
    logger.info(`Deleted work ${workId} for user ${userId}`);
  }

  /**
   * 删除平台上的作品
   * @returns 包含 accountId 用于后续刷新作品列表
   */
  async deletePlatformWork(
    userId: number, 
    workId: number,
    onCaptchaRequired?: (captchaInfo: { taskId: string }) => Promise<string>
  ): Promise<{ success: boolean; errorMessage?: string; accountId?: number }> {
    const work = await this.workRepository.findOne({
      where: { id: workId, userId },
      relations: ['account'],
    });
    
    if (!work) {
      throw new AppError('作品不存在', HTTP_STATUS.NOT_FOUND, ERROR_CODES.NOT_FOUND);
    }
    
    const account = await this.accountRepository.findOne({
      where: { id: work.accountId },
    });
    
    if (!account || !account.cookieData) {
      throw new AppError('账号不存在或未登录', HTTP_STATUS.BAD_REQUEST, ERROR_CODES.ACCOUNT_NOT_FOUND);
    }
    
    // 解密 Cookie
    let decryptedCookies: string;
    try {
      decryptedCookies = CookieManager.decrypt(account.cookieData);
    } catch {
      decryptedCookies = account.cookieData;
    }
    
    // 根据平台调用对应的删除方法
    if (account.platform === 'douyin') {
      const { DouyinAdapter } = await import('../automation/platforms/douyin.js');
      const adapter = new DouyinAdapter();
      
      const result = await adapter.deleteWork(decryptedCookies, work.platformVideoId, onCaptchaRequired);
      
      if (result.success) {
        // 更新作品状态为已删除
        await this.workRepository.update(workId, { status: 'deleted' });
        logger.info(`Platform work ${workId} deleted successfully`);
      }
      
      return { ...result, accountId: account.id };
    }
    
    if (account.platform === 'xiaohongshu') {
      const { XiaohongshuAdapter } = await import('../automation/platforms/xiaohongshu.js');
      const adapter = new XiaohongshuAdapter();
      
      const result = await adapter.deleteWork(decryptedCookies, work.platformVideoId, onCaptchaRequired);
      
      if (result.success) {
        // 更新作品状态为已删除
        await this.workRepository.update(workId, { status: 'deleted' });
        logger.info(`Platform work ${workId} (xiaohongshu) deleted successfully`);
      }
      
      return { ...result, accountId: account.id };
    }
    
    return { success: false, errorMessage: '暂不支持该平台删除功能' };
  }

  /**
   * 将 cookie 字符串解析为 cookie 列表
   */
  private parseCookieString(cookieString: string, platform: PlatformType): { 
    name: string; 
    value: string; 
    domain: string; 
    path: string;
  }[] {
    // 获取平台对应的域名
    const domainMap: Record<string, string> = {
      douyin: '.douyin.com',
      kuaishou: '.kuaishou.com',
      xiaohongshu: '.xiaohongshu.com',
      weixin_video: '.qq.com',
      bilibili: '.bilibili.com',
      toutiao: '.toutiao.com',
      baijiahao: '.baidu.com',
      qie: '.qq.com',
      dayuhao: '.alibaba.com',
    };
    
    const domain = domainMap[platform] || `.${platform}.com`;
    
    // 解析 "name=value; name2=value2" 格式的 cookie 字符串
    const cookies: { name: string; value: string; domain: string; path: string }[] = [];
    
    const pairs = cookieString.split(';');
    for (const pair of pairs) {
      const trimmed = pair.trim();
      if (!trimmed) continue;
      
      const eqIndex = trimmed.indexOf('=');
      if (eqIndex === -1) continue;
      
      const name = trimmed.substring(0, eqIndex).trim();
      const value = trimmed.substring(eqIndex + 1).trim();
      
      if (name && value) {
        cookies.push({
          name,
          value,
          domain,
          path: '/',
        });
      }
    }
    
    return cookies;
  }

  /**
   * 格式化作品
   */
  private formatWork(work: Work): WorkType {
    return {
      id: work.id,
      accountId: work.accountId,
      platform: work.platform as PlatformType,
      platformVideoId: work.platformVideoId,
      title: work.title,
      description: work.description || undefined,
      coverUrl: work.coverUrl,
      videoUrl: work.videoUrl || undefined,
      duration: work.duration,
      status: work.status as 'published' | 'reviewing' | 'rejected' | 'draft' | 'deleted',
      publishTime: work.publishTime?.toISOString() || '',
      playCount: work.playCount,
      likeCount: work.likeCount,
      commentCount: work.commentCount,
      shareCount: work.shareCount,
      collectCount: work.collectCount,
      createdAt: work.createdAt.toISOString(),
      updatedAt: work.updatedAt.toISOString(),
    };
  }
}

export const workService = new WorkService();
