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

export interface ReconRecord {
  id: string;
  tenantId: string;
  orderId: string;
  platformAmount: number;
  actualReceived: number;
  logisticsFee: number;
  tax: number;
  netProfit: number;
  status: 'MATCHED' | 'DISCREPANCY' | 'PENDING';
  discrepancyReason?: string;
}

/**
 * [BIZ_FIN_06] 全自动化财务利润对账 (Auto-Profit Recon)
 * @description 核心逻辑：自动对比平台订单流、支付回款流、物流账单流，计算真实净利并标记差异。
 */
export class ReconciliationService {
  private static readonly RECON_TABLE = 'cf_recon_records';

  /**
   * 执行对账分析
   */
  static async reconcileOrder(tenantId: string, orderId: string): Promise<ReconRecord> {
    logger.info(`[Reconciliation] Reconciling Order ${orderId} for Tenant ${tenantId}`);

    try {
      // 1. 获取平台订单数据 (收入)
      const order = await db('cf_consumer_orders').where({ id: orderId, tenant_id: tenantId }).first();
      if (!order) throw new Error(`Order ${orderId} not found`);

      // 2. 获取采购成本 (成本)
      const purchaseOrder = await db('cf_purchase_orders').where({ order_id: orderId, tenant_id: tenantId }).first();
      const purchaseCost = purchaseOrder ? purchaseOrder.total_amount : 0;

      // 3. 获取物流费用 (费用)
      const fulfillment = await db('cf_global_fulfillment').where({ order_id: orderId, tenant_id: tenantId }).first();
      const logisticsFee = fulfillment ? fulfillment.estimated_cost : 0;

      // 4. 获取实际回款 (资产流)
      const transaction = await db('cf_transactions')
        .where({ order_id: orderId, tenant_id: tenantId, transaction_type: 'PAYOUT' })
        .first();
      const actualReceived = transaction ? transaction.amount : 0;

      // 5. 汇率处理 [BIZ_FIN_12]
      const orderCurrency = order.currency || 'USD';
      const settlementCurrency = 'CNY'; 
      
      let rate = 7.25;
      const rateInfo = await db('cf_fx_rates').where({ pair: `${orderCurrency}/${settlementCurrency}` }).first();
      if (rateInfo) rate = rateInfo.rate;

      // 6. 计算税费 (简化的 5% 预估，实际应联动 TaxPlanningService)
      const tax = order.total_amount * 0.05 * rate;

      // 7. 计算真实净利 (CNY)
      // 公式：回款 - 采购成本(CNY) - 物流费(CNY) - 税费(CNY)
      // 注意：这里假设 purchaseCost 和 logisticsFee 已经是本币或已转换
      const netProfit = actualReceived - (purchaseCost * rate) - (logisticsFee * rate) - tax;

      // 8. 差异识别 (Discrepancy Identification)
      let status: ReconRecord['status'] = 'MATCHED';
      let discrepancyReason = '';

      if (!transaction) {
        status = 'PENDING';
        discrepancyReason = 'Waiting for payout transaction';
      } else if (netProfit < 0) {
        status = 'DISCREPANCY';
        discrepancyReason = `Negative profit detected: ${netProfit.toFixed(2)} ${settlementCurrency}`;
      } else if (Math.abs(actualReceived - (order.total_amount * 0.85 * rate)) > 10) {
        // 假设平台扣费约 15%，如果偏差过大标记异常
        status = 'DISCREPANCY';
        discrepancyReason = 'Payout amount significantly deviates from platform expectation (15% fee)';
      }

      const recon: ReconRecord = {
        id: `REC-${orderId}`,
        tenantId,
        orderId,
        platformAmount: order.total_amount,
        actualReceived,
        logisticsFee,
        tax,
        netProfit: Number(netProfit.toFixed(2)),
        status,
        discrepancyReason
      };

      // 9. 保存或更新对账记录
      await db(this.RECON_TABLE)
        .insert({
          id: recon.id,
          tenantId: recon.tenantId,
          orderId: recon.orderId,
          platformAmount: recon.platformAmount,
          actualReceived: recon.actualReceived,
          logisticsFee: recon.logisticsFee,
          tax: recon.tax,
          netProfit: recon.netProfit,
          status: recon.status,
          discrepancyReason: recon.discrepancyReason,
          created_at: new Date(),
          updated_at: new Date()
        })
        .onConflict(['id'])
        .merge();

      return recon;
    } catch (err: any) {
      logger.error(`[Reconciliation] Failed for Order ${orderId}: ${err.message}`);
      throw err;
    }
  }

  /**
   * 初始化数据库表
   */
  static async initTable() {
    const hasTable = await db.schema.hasTable(this.RECON_TABLE);
    if (!hasTable) {
      logger.info(`📦 Creating ${this.RECON_TABLE} table...`);
      await db.schema.createTable(this.RECON_TABLE, (table) => {
        table.string('id', 64).primary();
        table.string('tenantId', 64).notNullable();
        table.string('orderId', 64).notNullable();
        table.decimal('platformAmount', 15, 2);
        table.decimal('actualReceived', 15, 2);
        table.decimal('logisticsFee', 15, 2);
        table.decimal('tax', 15, 2);
        table.decimal('netProfit', 15, 2);
        table.string('status', 20).notNullable();
        table.text('discrepancyReason');
        table.index(['tenantId', 'orderId']);
        table.timestamps(true, true);
      });
    }
  }
}
