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

/**
 * [BE-A002] 数据分析服务
 * @description 实现商户数据的收集、分析和报表生成
 * @taskId BE-A002
 * @version 1.0
 */
export class AnalyticsService {
  private static generateId(prefix: string): string {
    return `${prefix}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  }

  private static generateTraceId(): string {
    return `trace_${Date.now()}_${Math.random().toString(36).substr(2, 12)}`;
  }

  /**
   * 收集商户数据
   * @param merchantId 商户ID
   * @param dataType 数据类型
   * @param data 数据
   */
  static async collectData(
    merchantId: string,
    dataType: 'order' | 'inventory' | 'sales' | 'traffic',
    data: any
  ): Promise<{ success: boolean; dataId: string }> {
    const traceId = this.generateTraceId();

    logger.info('[AnalyticsService] Collecting data', {
      merchantId,
      dataType,
      traceId,
    });

    try {
      const dataId = this.generateId('data');

      await db('cf_analytics_data').insert({
        id: dataId,
        merchant_id: merchantId,
        data_type: dataType,
        data: JSON.stringify(data),
        trace_id: traceId,
        created_at: new Date(),
      });

      logger.info('[AnalyticsService] Data collected successfully', {
        merchantId,
        dataType,
        dataId,
        traceId,
      });

      return { success: true, dataId };
    } catch (error: any) {
      logger.error('[AnalyticsService] Data collection failed', {
        merchantId,
        dataType,
        traceId,
        error: error.message,
      });
      throw error;
    }
  }

  /**
   * 生成商户销售报表
   * @param merchantId 商户ID
   * @param startDate 开始日期
   * @param endDate 结束日期
   */
  static async generateSalesReport(
    merchantId: string,
    startDate: Date,
    endDate: Date
  ): Promise<any> {
    const traceId = this.generateTraceId();

    logger.info('[AnalyticsService] Generating sales report', {
      merchantId,
      startDate,
      endDate,
      traceId,
    });

    try {
      // 查询商户订单数据
      const orders = await db('cf_consumer_orders')
        .where('created_at', '>=', startDate)
        .where('created_at', '<=', endDate)
        .where('merchant_id', merchantId)
        .select('*');

      // 计算销售统计
      const totalOrders = orders.length;
      const totalSales = orders.reduce((sum, order) => {
        return sum + parseFloat(order.total_amount || 0);
      }, 0);

      // 按状态统计订单
      const ordersByStatus = orders.reduce((acc, order) => {
        acc[order.status] = (acc[order.status] || 0) + 1;
        return acc;
      }, {} as Record<string, number>);

      // 生成报表
      const report = {
        merchantId,
        startDate,
        endDate,
        totalOrders,
        totalSales: Math.round(totalSales * 100) / 100,
        ordersByStatus,
        averageOrderValue: totalOrders > 0 ? Math.round((totalSales / totalOrders) * 100) / 100 : 0,
        generatedAt: new Date(),
      };

      // 保存报表
      const reportId = this.generateId('report');
      await db('cf_analytics_report').insert({
        id: reportId,
        merchant_id: merchantId,
        report_type: 'sales',
        report_data: JSON.stringify(report),
        period_start: startDate,
        period_end: endDate,
        trace_id: traceId,
        created_at: new Date(),
      });

      logger.info('[AnalyticsService] Sales report generated', {
        merchantId,
        reportId,
        totalSales,
        traceId,
      });

      return {
        ...report,
        reportId,
      };
    } catch (error: any) {
      logger.error('[AnalyticsService] Sales report generation failed', {
        merchantId,
        traceId,
        error: error.message,
      });
      throw error;
    }
  }

  /**
   * 生成商户库存报表
   * @param merchantId 商户ID
   */
  static async generateInventoryReport(merchantId: string): Promise<any> {
    const traceId = this.generateTraceId();

    logger.info('[AnalyticsService] Generating inventory report', {
      merchantId,
      traceId,
    });

    try {
      // 查询商户库存数据
      const inventory = await db('cf_inventory')
        .where('merchant_id', merchantId)
        .select('*');

      // 计算库存统计
      const totalItems = inventory.length;
      const totalQuantity = inventory.reduce((sum, item) => {
        return sum + (item.total_qty || 0);
      }, 0);

      // 按仓库统计
      const inventoryByWarehouse = inventory.reduce((acc, item) => {
        const warehouse = item.warehouse_id || 'default';
        acc[warehouse] = (acc[warehouse] || 0) + (item.total_qty || 0);
        return acc;
      }, {} as Record<string, number>);

      // 生成报表
      const report = {
        merchantId,
        totalItems,
        totalQuantity,
        inventoryByWarehouse,
        generatedAt: new Date(),
      };

      // 保存报表
      const reportId = this.generateId('report');
      await db('cf_analytics_report').insert({
        id: reportId,
        merchant_id: merchantId,
        report_type: 'inventory',
        report_data: JSON.stringify(report),
        trace_id: traceId,
        created_at: new Date(),
      });

      logger.info('[AnalyticsService] Inventory report generated', {
        merchantId,
        reportId,
        totalItems,
        traceId,
      });

      return {
        ...report,
        reportId,
      };
    } catch (error: any) {
      logger.error('[AnalyticsService] Inventory report generation failed', {
        merchantId,
        traceId,
        error: error.message,
      });
      throw error;
    }
  }

  /**
   * 获取商户报表历史
   * @param merchantId 商户ID
   * @param reportType 报表类型
   * @param limit 限制数量
   */
  static async getReportHistory(
    merchantId: string,
    reportType?: 'sales' | 'inventory' | 'all',
    limit: number = 20
  ): Promise<any[]> {
    const traceId = this.generateTraceId();

    logger.info('[AnalyticsService] Getting report history', {
      merchantId,
      reportType,
      limit,
      traceId,
    });

    try {
      let query = db('cf_analytics_report')
        .where({ merchant_id: merchantId })
        .orderBy('created_at', 'desc')
        .limit(limit);

      if (reportType && reportType !== 'all') {
        query = query.where({ report_type: reportType });
      }

      const reports = await query.select('*');

      // 解析报表数据
      const parsedReports = reports.map(report => ({
        ...report,
        report_data: JSON.parse(report.report_data),
      }));

      logger.info('[AnalyticsService] Report history retrieved', {
        merchantId,
        reportCount: parsedReports.length,
        traceId,
      });

      return parsedReports;
    } catch (error: any) {
      logger.error('[AnalyticsService] Failed to get report history', {
        merchantId,
        traceId,
        error: error.message,
      });
      throw error;
    }
  }

  /**
   * 初始化数据分析相关数据库表
   */
  static async initTables(): Promise<void> {
    const dataTableExists = await db.schema.hasTable('cf_analytics_data');
    if (!dataTableExists) {
      logger.info('📦 Creating cf_analytics_data table...');
      await db.schema.createTable('cf_analytics_data', (table) => {
        table.string('id', 64).primary();
        table.string('merchant_id', 64).notNullable();
        table.enum('data_type', ['order', 'inventory', 'sales', 'traffic']).notNullable();
        table.text('data').notNullable();
        table.string('trace_id', 64);
        table.timestamp('created_at').defaultTo(db.fn.now());

        table.index(['merchant_id']);
        table.index(['data_type']);
        table.index(['created_at']);
      });
      logger.info('✅ Table cf_analytics_data created');
    }

    const reportTableExists = await db.schema.hasTable('cf_analytics_report');
    if (!reportTableExists) {
      logger.info('📦 Creating cf_analytics_report table...');
      await db.schema.createTable('cf_analytics_report', (table) => {
        table.string('id', 64).primary();
        table.string('merchant_id', 64).notNullable();
        table.enum('report_type', ['sales', 'inventory', 'profit', 'traffic']).notNullable();
        table.text('report_data').notNullable();
        table.date('period_start');
        table.date('period_end');
        table.string('trace_id', 64);
        table.timestamp('created_at').defaultTo(db.fn.now());

        table.index(['merchant_id']);
        table.index(['report_type']);
        table.index(['created_at']);
      });
      logger.info('✅ Table cf_analytics_report created');
    }
  }
}
