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

export interface SettlementParty {
  did: string;
  role: 'BRAND' | 'OPERATOR' | 'KOL' | 'LOGISTICS';
  shareRatio: number; // 分成比例 (0-1)
  walletAddress?: string;
}

/**
 * [BIZ_FIN_40] 基于 DID 的自治清算协议 (DID-based Sovereign Settlement)
 * @description 核心逻辑：利用分布式身份 (DID) 实现品牌方、代运营与达人的自动化、隐私化清算。
 */
export class DIDSettlementService {
  private static readonly SETTLEMENT_TABLE = 'cf_did_settlements';
  private static readonly CONTRACT_TABLE = 'cf_did_contracts';

  /**
   * 执行跨主体自动化清算
   */
  static async settleOrder(tenantId: string, orderId: string) {
    logger.info(`[DIDSettlement] Initiating DID-based settlement for order: ${orderId}`);

    // 1. 获取订单净利润 (联动 OrderProfitService)
    const order = await db('cf_consumer_orders').where({ tenant_id: tenantId, order_id: orderId }).first();
    if (!order) return null;
    
    // 假设利润已预先计算好，此处简化获取
    const netProfit = Number(order.total_amount) * 0.25; // 假设 25% 利润

    // 2. 获取该租户的清算合约
    const contracts = await db(this.CONTRACT_TABLE).where({ tenant_id: tenantId, is_active: true });
    
    if (contracts.length === 0) {
      logger.warn(`[DIDSettlement] No active DID contracts found for tenant ${tenantId}`);
      return null;
    }

    const results = [];
    for (const contract of contracts) {
      const parties: SettlementParty[] = JSON.parse(contract.parties_json);
      
      // 3. 按比例分润并存证
      for (const party of parties) {
        const amount = netProfit * party.shareRatio;
        
        // 生成隐私存证证明 (ZKP)
        const proofHash = await PrivateAuditService.generateProof(tenantId, 'SETTLEMENT', {
          orderId,
          did: party.did,
          amount
        });

        const settlement = {
          id: `SETTLE-${orderId}-${party.did}`,
          tenant_id: tenantId,
          order_id: orderId,
          party_did: party.did,
          party_role: party.role,
          amount: Number(amount.toFixed(2)),
          proof_hash: proofHash,
          status: 'SETTLED',
          created_at: new Date()
        };

        await db(this.SETTLEMENT_TABLE).insert(settlement);
        results.push(settlement);
      }
    }

    return results;
  }

  /**
   * 创建清算合约
   */
  static async createContract(tenantId: string, parties: SettlementParty[]) {
    // 验证总比例是否为 1
    const totalRatio = parties.reduce((sum, p) => sum + p.shareRatio, 0);
    if (Math.abs(totalRatio - 1.0) > 0.001) {
      throw new Error(`[DIDSettlement] Total share ratio must be 1.0, current: ${totalRatio}`);
    }

    const [id] = await db(this.CONTRACT_TABLE).insert({
      tenant_id: tenantId,
      parties_json: JSON.stringify(parties),
      is_active: true,
      created_at: new Date()
    });

    return id;
  }

  /**
   * 初始化数据库表
   */
  static async initTable() {
    const hasContractTable = await db.schema.hasTable(this.CONTRACT_TABLE);
    if (!hasContractTable) {
      logger.info(`📦 Creating ${this.CONTRACT_TABLE} table...`);
      await db.schema.createTable(this.CONTRACT_TABLE, (table) => {
        table.increments('id').primary();
        table.string('tenant_id', 64).notNullable();
        table.json('parties_json').notNullable(); // 存储 SettlementParty[]
        table.boolean('is_active').defaultTo(true);
        table.timestamps(true, true);
        table.index(['tenant_id']);
      });
    }

    const hasSettlementTable = await db.schema.hasTable(this.SETTLEMENT_TABLE);
    if (!hasSettlementTable) {
      logger.info(`📦 Creating ${this.SETTLEMENT_TABLE} table...`);
      await db.schema.createTable(this.SETTLEMENT_TABLE, (table) => {
        table.string('id', 128).primary();
        table.string('tenant_id', 64).notNullable();
        table.string('order_id', 64).notNullable();
        table.string('party_did', 128).notNullable();
        table.string('party_role', 32).notNullable();
        table.decimal('amount', 15, 2).notNullable();
        table.string('proof_hash', 128); // 关联 PrivateAuditService
        table.string('status', 32).defaultTo('PENDING');
        table.timestamp('created_at').defaultTo(db.fn.now());
        table.index(['tenant_id', 'order_id']);
        table.index(['party_did']);
      });
    }
  }
}
