import db from '../../config/database';
import { logger } from '../../utils/logger';

/**
 * [BIZ_REP_05] 报表预聚合与大数据量优化服务 (Summary Aggregator)
 * @description 解决报表维度多、数据量大的性能瓶颈。采用“增量预聚合”模式，
 * 将原始订单、利润数据实时或近实时地汇总到轻量级的 Summary 表中。
 */
export class SummaryAggregationService {
  private static readonly SUMMARY_TABLE = 'cf_report_summary';

  /**
   * 初始化 Summary 表结构
   */
  static async initTable() {
    const hasTable = await db.schema.hasTable(this.SUMMARY_TABLE);
    if (!hasTable) {
      logger.info(`📊 Creating ${this.SUMMARY_TABLE} for high-performance reporting...`);
      await db.schema.createTable(this.SUMMARY_TABLE, (table) => {
        table.increments('id').primary();
        table.string('tenant_id', 64).notNullable();
        table.string('shop_id', 64);
        table.string('platform', 32);
        table.string('site', 16); // e.g., 'US', 'UK'
        table.string('dimension_type', 32).notNullable(); // e.g., 'DAILY', 'MONTHLY', 'CATEGORY'
        table.string('dimension_value', 64).notNullable(); // e.g., '2026-03-14'
        
        table.decimal('total_revenue', 15, 2).defaultTo(0);
        table.decimal('total_cost', 15, 2).defaultTo(0);
        table.decimal('net_profit', 15, 2).defaultTo(0);
        table.integer('order_count').defaultTo(0);
        table.decimal('avg_roi', 10, 4).defaultTo(0);
        
        table.json('metadata'); // 存储额外的维度信息
        table.timestamps(true, true);

        // 核心索引：租户 + 维度类型 + 维度值 + 平台 + 站点 + 店铺
        table.unique(['tenant_id', 'dimension_type', 'dimension_value', 'platform', 'site', 'shop_id'], 'idx_sum_unique');
        table.index(['tenant_id', 'dimension_type', 'dimension_value', 'site'], 'idx_sum_main');
      });
      logger.info(`✅ Table ${this.SUMMARY_TABLE} initialized`);
    }
  }

  /**
   * [Incremental Update] 增量更新摘要数据
   * @description 当订单支付、利润核算完成时调用，避免全量扫表
   */
  static async updateDailyStats(data: {
    tenantId: string;
    shopId?: string;
    platform: string;
    site: string;
    amount: number;
    cost: number;
    profit: number;
    date: string; // YYYY-MM-DD
  }) {
    const { tenantId, shopId, platform, site, amount, cost, profit, date } = data;

    logger.info(`[SummaryAggregator] Incrementing daily stats for ${tenantId} (${platform}-${site}) on ${date}`);

    // 使用 MySQL ON DUPLICATE KEY UPDATE 实现原子增量
    const rawSql = `
      INSERT INTO ${this.SUMMARY_TABLE} 
      (tenant_id, shop_id, platform, site, dimension_type, dimension_value, total_revenue, total_cost, net_profit, order_count, created_at, updated_at)
      VALUES (?, ?, ?, ?, 'DAILY', ?, ?, ?, ?, 1, NOW(), NOW())
      ON DUPLICATE KEY UPDATE 
      total_revenue = total_revenue + VALUES(total_revenue),
      total_cost = total_cost + VALUES(total_cost),
      net_profit = net_profit + VALUES(net_profit),
      order_count = order_count + 1,
      updated_at = NOW()
    `;

    await db.raw(rawSql, [tenantId, shopId || null, platform, site, date, amount, cost, profit]);
  }

  /**
   * 从 Summary 表获取聚合数据 (秒级响应)
   */
  static async getSummary(tenantId: string, dimensionType: string, startDate: string, endDate: string) {
    return db(this.SUMMARY_TABLE)
      .where({ tenant_id: tenantId, dimension_type: dimensionType })
      .whereBetween('dimension_value', [startDate, endDate])
      .orderBy('dimension_value', 'asc');
  }

  /**
   * [Self-Healing] 全量重刷摘要数据 (应对逻辑变更或数据丢失)
   * @description 仅在低峰期或手动触发时运行
   */
  static async rebuildSummary(tenantId: string, dateRange: [string, string]) {
    logger.warn(`[SummaryAggregator] Rebuilding summary for tenant ${tenantId} from ${dateRange[0]} to ${dateRange[1]}`);
    
    // 1. 清理旧数据
    await db(this.SUMMARY_TABLE)
      .where({ tenant_id: tenantId, dimension_type: 'DAILY' })
      .whereBetween('dimension_value', dateRange)
      .delete();

    // 2. 从 cf_consumer_orders 全量聚合
    const rawAgg = await db('cf_consumer_orders')
      .where({ tenant_id: tenantId })
      .whereBetween('created_at', [dateRange[0] + ' 00:00:00', dateRange[1] + ' 23:59:59'])
      .select(
        'tenant_id',
        'shop_id',
        'platform',
        'site',
        db.raw("DATE_FORMAT(created_at, '%Y-%m-%d') as date"),
        db.raw('SUM(total_amount) as revenue'),
        db.raw('COUNT(id) as count')
      )
      .groupBy('tenant_id', 'shop_id', 'platform', 'site', 'date');

    // 3. 批量插入 (TODO: 实现分批插入以防大事务)
    for (const row of rawAgg) {
      await this.updateDailyStats({
        tenantId: row.tenant_id,
        shopId: row.shop_id,
        platform: row.platform,
        site: row.platform, // Default to platform
        amount: row.revenue,
        cost: 0, // TODO: 接入真实成本
        profit: 0, // TODO: 接入真实利润
        date: row.date
      });
    }
  }
}
