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

/**
 * [BIZ_FIN_187] 基于历史数据的售后损耗准备金建议 (Provision)
 * @description 根据历史售后损耗，建议计提售后准备金。
 */
export class WarrantyService {
  private static readonly PROVISION_TABLE = 'cf_warranty_provisions';

  /**
   * 生成售后准备金计提建议
   */
  static async recommendWarrantyProvision(tenantId: string) {
    logger.info(`[Warranty] Recommending warranty provision for tenant: ${tenantId}`);

    // 1. 获取过去 180 天的总销售额和售后损耗 (退款 + 赔偿)
    const stats = await db('cf_consumer_orders')
      .where({ tenant_id: tenantId })
      .andWhere('created_at', '>=', new Date(Date.now() - 180 * 24 * 60 * 60 * 1000))
      .select(db.raw('SUM(total_amount) as totalRevenue'));

    const totalRevenue = Number(stats[0].totalRevenue || 0);

    const losses = await db('cf_transactions')
      .where({ tenant_id: tenantId, transaction_type: 'REFUND' })
      .andWhere('created_at', '>=', new Date(Date.now() - 180 * 24 * 60 * 60 * 1000))
      .select(db.raw('SUM(amount) as totalRefundLoss'));

    const totalRefundLoss = Math.abs(Number(losses[0].totalRefundLoss || 0));

    // 2. 估计售后损耗率
    const lossRatio = totalRevenue > 0 ? totalRefundLoss / totalRevenue : 0.02; // 默认 2%

    // 建议计提未来 30 天预期销售额的相应比例作为准备金
    const futureRevenueEstimate = totalRevenue / 6; // 假设下月销售额与过去半年均值一致
    const recommendedProvision = futureRevenueEstimate * lossRatio;

    const provisionRecord = {
      id: `WP-${tenantId}-${new Date().toISOString().split('T')[0]}`,
      tenantId,
      totalRevenue,
      totalRefundLoss,
      lossRatio: Number(lossRatio.toFixed(4)),
      recommendedProvision: Number(recommendedProvision.toFixed(2)),
      created_at: new Date()
    };

    // 3. 存储建议
    await db(this.PROVISION_TABLE)
      .insert(provisionRecord)
      .onConflict(['id'])
      .merge();

    return provisionRecord;
  }

  /**
   * 初始化数据库表
   */
  static async initTable() {
    const hasTable = await db.schema.hasTable(this.PROVISION_TABLE);
    if (!hasTable) {
      logger.info(`📦 Creating ${this.PROVISION_TABLE} table...`);
      await db.schema.createTable(this.PROVISION_TABLE, (table) => {
        table.string('id', 128).primary();
        table.string('tenantId', 64).notNullable();
        table.decimal('totalRevenue', 15, 2);
        table.decimal('totalRefundLoss', 15, 2);
        table.decimal('lossRatio', 5, 4);
        table.decimal('recommendedProvision', 15, 2);
        table.timestamp('created_at').defaultTo(db.fn.now());
        table.index(['tenantId']);
      });
    }
  }
}
