import db from '../config/database';
import { FeatureGovernanceService } from '../core/governance/FeatureGovernanceService';
import { logger } from '../utils/logger';
import { AuditService } from './AuditService';

/**
 * [BIZ_TRADE_13] 自动化物流保险按需采购 (Auto-Insurance)
 * @description 核心逻辑：根据包裹价值与路线风险自动投保，支持多级风险评估算法。
 */
export class LogisticsInsuranceService {
  private static readonly TABLE_NAME = 'cf_logistics_insurance';

  /**
   * 初始化数据库表
   */
  static async initTable() {
    const hasTable = await db.schema.hasTable(this.TABLE_NAME);
    if (!hasTable) {
      logger.info(`📦 Creating ${this.TABLE_NAME} table...`);
      await db.schema.createTable(this.TABLE_NAME, (table) => {
        table.increments('id').primary();
        table.string('tenant_id', 64).notNullable();
        table.string('order_id', 64).notNullable();
        table.decimal('insured_value', 15, 2);
        table.decimal('premium_amount', 15, 2);
        table.string('policy_number', 100);
        table.string('status', 20).defaultTo('PENDING'); // PENDING, INSURED, CLAIMED, EXPIRED
        table.float('risk_score');
        table.timestamps(true, true);
        table.index(['tenant_id', 'order_id']);
      });
    }
  }

  /**
   * 自动检查并投保
   * @description 综合考虑订单金额、目的地风险评分与商品类型进行决策
   */
  static async autoInsure(tenantId: string, orderId: string, traceId: string): Promise<boolean> {
    // Feature Flag Check
    if (!(await FeatureGovernanceService.isEnabled('BIZ_TRADE_AUTO_INSURANCE', tenantId))) {
      return false;
    }

    const order = await db('cf_orders').where({ id: orderId }).first();
    if (!order) return false;

    // 1. 风险评估算法 (Risk Assessment)
    const riskScore = this.calculateRiskScore(order);
    
    // 2. 投保阈值判断 (Threshold Decision)
    // 策略：订单金额 > 100 USD 或 风险分 > 0.7 时自动投保
    const INSURANCE_THRESHOLD = 100;
    if (order.selling_price < INSURANCE_THRESHOLD && riskScore < 0.7) {
      logger.info(`[Insurance] Order ${orderId} skipped (Value: $${order.selling_price}, Risk: ${riskScore})`);
      return false;
    }

    // 3. 检查是否已投保
    const existing = await db(this.TABLE_NAME)
      .where({ order_id: orderId, tenant_id: tenantId })
      .first();
    if (existing) return true;

    // 4. 费率估算 (基于风险分的动态费率)
    const baseRate = 0.015;
    const premiumRate = baseRate * (1 + riskScore);
    const premiumAmount = order.selling_price * premiumRate;
    const policyNumber = `INS-${Date.now()}-${orderId.slice(-4)}`;

    await db.transaction(async (trx) => {
      await trx(this.TABLE_NAME).insert({
        tenant_id: tenantId,
        order_id: orderId,
        insured_value: order.selling_price,
        premium_amount: premiumAmount,
        policy_number: policyNumber,
        risk_score: riskScore,
        status: 'INSURED',
        created_at: new Date(),
        updated_at: new Date()
      });

      await AuditService.log({
        tenantId,
        userId: 'SYSTEM',
        module: 'LOGISTICS',
        action: 'AUTO_INSURE_ORDER',
        resourceType: 'ORDER',
        resourceId: orderId,
        traceId,
        afterSnapshot: { premiumAmount, policyNumber, riskScore },
        result: 'success',
        source: 'node',
        metadata: { reason: 'High value or high risk order auto-insurance' }
      });
    });

    logger.info(`[Insurance] Order ${orderId} insured successfully. Premium: $${premiumAmount.toFixed(2)}`);
    return true;
  }

  /**
   * 简单的风险评分计算
   */
  private static calculateRiskScore(order: any): number {
    let score = 0.1; // 基础风险
    
    // 目的地风险 (模拟)
    const highRiskCountries = ['BR', 'NG', 'ID', 'IN'];
    if (highRiskCountries.includes(order.country_code)) score += 0.4;
    
    // 物流时效风险 (模拟)
    if (order.shipping_method === 'Economy') score += 0.2;
    
    return Math.min(1.0, score);
  }

  /**
   * 索赔逻辑 (如果物流轨迹异常或确认为丢失/破损)
   */
  static async initiateClaim(tenantId: string, orderId: string, reason: string, traceId: string): Promise<void> {
    await db.transaction(async (trx) => {
      const insurance = await trx('cf_logistics_insurance')
        .where({ order_id: orderId, tenant_id: tenantId })
        .forUpdate()
        .first();

      if (!insurance || insurance.status !== 'INSURED') {
        return;
      }

      await trx('cf_logistics_insurance')
        .where({ order_id: orderId, tenant_id: tenantId })
        .update({
          status: 'CLAIMED',
          updated_at: db.fn.now()
        });

      await AuditService.log({
        tenantId,
        userId: 'SYSTEM',
        module: 'LOGISTICS',
        action: 'INITIATE_INSURANCE_CLAIM',
        resourceType: 'LOGISTICS_INSURANCE',
        resourceId: insurance.id.toString(),
        traceId,
        afterSnapshot: { reason },
        result: 'success',
        source: 'node',
        metadata: { orderId }
      });
    });
  }
}
