import { AppDataSource, AnalyticsData, PlatformAccount } from '../models/index.js';
import type {
  AnalyticsSummary,
  AnalyticsTrend,
  PlatformComparison,
  TrendDataPoint,
} from '@media-manager/shared';

interface QueryParams {
  startDate: string;
  endDate: string;
  accountId?: number;
  platform?: string;
}

interface ExportParams extends QueryParams {
  format?: string;
}

export class AnalyticsService {
  private analyticsRepository = AppDataSource.getRepository(AnalyticsData);
  private accountRepository = AppDataSource.getRepository(PlatformAccount);

  async getSummary(userId: number, params: QueryParams): Promise<AnalyticsSummary> {
    const { startDate, endDate, accountId, platform } = params;

    const queryBuilder = this.analyticsRepository
      .createQueryBuilder('data')
      .select('SUM(data.fansCount)', 'totalFans')
      .addSelect('SUM(data.fansIncrease)', 'totalFansIncrease')
      .addSelect('SUM(data.viewsCount)', 'totalViews')
      .addSelect('SUM(data.likesCount)', 'totalLikes')
      .addSelect('SUM(data.commentsCount)', 'totalComments')
      .addSelect('SUM(data.sharesCount)', 'totalShares')
      .addSelect('SUM(data.income)', 'totalIncome')
      .where('data.userId = :userId', { userId })
      .andWhere('data.date BETWEEN :startDate AND :endDate', { startDate, endDate });

    if (accountId) {
      queryBuilder.andWhere('data.accountId = :accountId', { accountId });
    }
    if (platform) {
      queryBuilder
        .innerJoin('data.account', 'account')
        .andWhere('account.platform = :platform', { platform });
    }

    const result = await queryBuilder.getRawOne();

    return {
      totalFans: Number(result?.totalFans) || 0,
      totalFansIncrease: Number(result?.totalFansIncrease) || 0,
      totalViews: Number(result?.totalViews) || 0,
      totalLikes: Number(result?.totalLikes) || 0,
      totalComments: Number(result?.totalComments) || 0,
      totalShares: Number(result?.totalShares) || 0,
      totalIncome: Number(result?.totalIncome) || 0,
    };
  }

  async getTrend(userId: number, params: QueryParams): Promise<AnalyticsTrend> {
    const { startDate, endDate, accountId, platform } = params;

    const queryBuilder = this.analyticsRepository
      .createQueryBuilder('data')
      .select('data.date', 'date')
      .addSelect('SUM(data.fansCount)', 'fansCount')
      .addSelect('SUM(data.viewsCount)', 'viewsCount')
      .addSelect('SUM(data.likesCount)', 'likesCount')
      .addSelect('SUM(data.commentsCount)', 'commentsCount')
      .addSelect('SUM(data.sharesCount)', 'sharesCount')
      .addSelect('SUM(data.income)', 'income')
      .where('data.userId = :userId', { userId })
      .andWhere('data.date BETWEEN :startDate AND :endDate', { startDate, endDate })
      .groupBy('data.date')
      .orderBy('data.date', 'ASC');

    if (accountId) {
      queryBuilder.andWhere('data.accountId = :accountId', { accountId });
    }
    if (platform) {
      queryBuilder
        .innerJoin('data.account', 'account')
        .andWhere('account.platform = :platform', { platform });
    }

    const results = await queryBuilder.getRawMany();

    const formatTrend = (key: string): TrendDataPoint[] =>
      results.map(r => ({ date: r.date, value: Number(r[key]) || 0 }));

    return {
      fans: formatTrend('fansCount'),
      views: formatTrend('viewsCount'),
      likes: formatTrend('likesCount'),
      comments: formatTrend('commentsCount'),
      shares: formatTrend('sharesCount'),
      income: formatTrend('income'),
    };
  }

  async getPlatformComparison(
    userId: number,
    params: { startDate: string; endDate: string }
  ): Promise<PlatformComparison[]> {
    const { startDate, endDate } = params;

    const results = await this.analyticsRepository
      .createQueryBuilder('data')
      .select('account.platform', 'platform')
      .addSelect('account.accountName', 'accountName')
      .addSelect('SUM(data.fansCount)', 'fansCount')
      .addSelect('SUM(data.fansIncrease)', 'fansIncrease')
      .addSelect('SUM(data.viewsCount)', 'viewsCount')
      .addSelect('SUM(data.likesCount)', 'likesCount')
      .addSelect('SUM(data.commentsCount)', 'commentsCount')
      .innerJoin('data.account', 'account')
      .where('data.userId = :userId', { userId })
      .andWhere('data.date BETWEEN :startDate AND :endDate', { startDate, endDate })
      .groupBy('account.platform')
      .addGroupBy('account.accountName')
      .getRawMany();

    return results.map(r => ({
      platform: r.platform,
      accountName: r.accountName,
      fansCount: Number(r.fansCount) || 0,
      fansIncrease: Number(r.fansIncrease) || 0,
      viewsCount: Number(r.viewsCount) || 0,
      likesCount: Number(r.likesCount) || 0,
      commentsCount: Number(r.commentsCount) || 0,
    }));
  }

  async exportData(userId: number, params: ExportParams): Promise<string> {
    const { startDate, endDate, accountId, format } = params;

    const queryBuilder = this.analyticsRepository
      .createQueryBuilder('data')
      .leftJoinAndSelect('data.account', 'account')
      .where('data.userId = :userId', { userId })
      .andWhere('data.date BETWEEN :startDate AND :endDate', { startDate, endDate })
      .orderBy('data.date', 'ASC');

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

    const results = await queryBuilder.getMany();

    if (format === 'csv') {
      const headers = ['日期', '平台', '账号', '粉丝数', '粉丝增量', '播放量', '点赞数', '评论数', '分享数', '收益'];
      const rows = results.map(r => [
        r.date,
        r.account?.platform || '',
        r.account?.accountName || '',
        r.fansCount,
        r.fansIncrease,
        r.viewsCount,
        r.likesCount,
        r.commentsCount,
        r.sharesCount,
        r.income,
      ]);
      return [headers.join(','), ...rows.map(r => r.join(','))].join('\n');
    }

    return JSON.stringify(results, null, 2);
  }
}
