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

export interface DistributedTransaction {
  id: string;
  involvedNodes: string[];
  status: 'PENDING' | 'PREPARED' | 'COMMITTED' | 'ABORTED' | 'INCONSISTENT';
  payload: any;
  createdAt: Date;
}

/**
 * [CORE_DEV_21] 自愈式分布式事务一致性检测器 (TX Sentinel)
 * @description 核心逻辑：监控跨多个节点（如库存服务、支付服务、发布服务）的分布式事务状态。
 * 当检测到事务由于网络分区或节点宕机导致的不一致（如：支付成功但库存未扣减）时，
 * TX Sentinel 会根据预设的补偿逻辑自动发起冲正（Rollback）或补单（Retry）操作。
 */
export class TXSentinelService {
  private static readonly TX_TABLE = 'cf_distributed_transactions';

  /**
   * 初始化数据库表
   */
  static async initTable() {
    const hasTable = await db.schema.hasTable(this.TX_TABLE);
    if (!hasTable) {
      logger.info(`📦 Creating ${this.TX_TABLE} table...`);
      await db.schema.createTable(this.TX_TABLE, (table) => {
        table.string('id', 64).primary();
        table.json('involved_nodes');
        table.string('status', 20).defaultTo('PENDING');
        table.json('payload');
        table.timestamps(true, true);
        table.index(['status', 'created_at']);
      });
    }
  }

  /**
   * 注册并监控分布式事务
   */
  static async registerTX(tx: DistributedTransaction) {
    await db(this.TX_TABLE).insert({
      id: tx.id,
      involved_nodes: JSON.stringify(tx.involvedNodes),
      status: tx.status,
      payload: JSON.stringify(tx.payload),
      created_at: tx.createdAt
    });
  }

  /**
   * 扫描并修复不一致的事务 (Self-Healing Loop)
   */
  static async scanAndHeal(tenantId?: string) {
    // Feature Flag Check
    if (!(await FeatureGovernanceService.isEnabled('CORE_DEV_TX_SENTINEL', tenantId))) {
      return;
    }

    logger.info('[TX-Sentinel] Scanning for inconsistent distributed transactions...');

    // 1. 查找超时未完成或标记为 INCONSISTENT 的事务
    const timeout = new Date(Date.now() - 300 * 1000); // 5分钟超时
    const staleTXs = await db(this.TX_TABLE)
      .whereIn('status', ['PENDING', 'PREPARED', 'INCONSISTENT'])
      .andWhere('created_at', '<', timeout);

    for (const tx of staleTXs) {
      logger.warn(`[TX-Sentinel] Found stale/inconsistent TX: ${tx.id}. Status: ${tx.status}`);
      
      // 2. 执行自愈策略 (Actual: Saga Pattern Compensation or TCC Rollback)
      const success = await this.executeCompensation(tx);
      
      if (success) {
        await db(this.TX_TABLE).where({ id: tx.id }).update({
          status: 'ABORTED', // 或 COMMITTED (补单成功)
          updated_at: new Date()
        });
        logger.info(`[TX-Sentinel] Successfully healed TX ${tx.id}`);
      }
    }
  }

  /**
   * 模拟执行补偿逻辑
   */
  private static async executeCompensation(tx: any): Promise<boolean> {
    // 逻辑：调用涉及节点的补偿接口
    return true;
  }
}
