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

/**
 * [BIZ_SOV_07] 基于零知识证明 (ZKP) 的租户主权准入校验 (ZKPSovereignAdmissionService)
 * @description 在保护租户主权数据（如财务流水、合规记录）的前提下，通过 ZKP 验证租户是否具备进入主权贸易生态的资质。
 */
export class ZKPSovereignAdmissionService {
  private static readonly ADMISSION_TABLE = 'cf_zkp_admission';

  /**
   * 初始化数据库表
   */
  static async initTable() {
    const hasTable = await db.schema.hasTable(this.ADMISSION_TABLE);
    if (!hasTable) {
      logger.info(`📦 Creating ${this.ADMISSION_TABLE} table...`);
      await db.schema.createTable(this.ADMISSION_TABLE, (table) => {
        table.increments('id').primary();
        table.string('tenant_id', 64).notNullable();
        table.string('sovereign_id', 64).notNullable(); // 对应的主权生态 ID
        table.string('admission_requirement', 128).notNullable(); // 准入要求描述
        table.string('zkp_proof_hash', 255).notNullable(); // ZKP 证明哈希
        table.string('status', 32).defaultTo('PENDING'); // PENDING, VERIFIED, REJECTED
        table.dateTime('verified_at');
        table.string('trace_id', 128);
        table.timestamps(true, true);
        table.unique(['tenant_id', 'sovereign_id', 'admission_requirement']);
      });
      logger.info(`✅ Table ${this.ADMISSION_TABLE} created`);
    }
  }

  /**
   * 提交准入申请并进行 ZKP 校验
   * @param tenantId 租户 ID
   * @param sovereignId 主权生态 ID
   * @param requirement 准入要求 (e.g., 'MIN_CREDIT_700', 'COMPLIANCE_SCORE_90')
   * @param proofHash ZKP 证明哈希
   * @param traceId 调用链 ID
   */
  static async requestAdmission(
    tenantId: string,
    sovereignId: string,
    requirement: string,
    proofHash: string,
    traceId: string
  ): Promise<boolean> {
    // 1. 功能开关检查
    if (!(await FeatureGovernanceService.isEnabled('BIZ_SOV_ZKP_ADMISSION', tenantId))) {
      logger.warn(`[ZKPSovereignAdmission] Service disabled for tenant ${tenantId} | traceId: ${traceId}`);
      return false;
    }

    logger.info(`[ZKPSovereignAdmission] Processing admission request for tenant ${tenantId} to ${sovereignId} | requirement: ${requirement} | traceId: ${traceId}`);

    // 2. 调用 AGI 模拟 ZKP 验证逻辑 (此处为 AGI 驱动的“主权验证”)
    // 验证逻辑：基于 requirement 对应的 Circuit 校验 proofHash
    const isValid = await this.verifySovereignProof(requirement, proofHash, traceId);

    const status = isValid ? 'VERIFIED' : 'REJECTED';
    const verifiedAt = isValid ? new Date() : null;

    // 3. 记录验证结果
    await db(this.ADMISSION_TABLE)
      .insert({
        tenant_id: tenantId,
        sovereign_id: sovereignId,
        admission_requirement: requirement,
        zkp_proof_hash: proofHash,
        status: status,
        verified_at: verifiedAt,
        trace_id: traceId,
        created_at: new Date(),
        updated_at: new Date()
      })
      .onConflict(['tenant_id', 'sovereign_id', 'admission_requirement'])
      .merge();

    if (isValid) {
      logger.info(`[ZKPSovereignAdmission] Tenant ${tenantId} successfully admitted to ${sovereignId} | traceId: ${traceId}`);
      
      // 4. 触发主权身份升级 (模拟)
      // TODO: 调用 SovereigntyIdentityService 升级租户权限
    } else {
      logger.error(`[ZKPSovereignAdmission] Tenant ${tenantId} failed ZKP validation for ${sovereignId} | traceId: ${traceId}`);
    }

    return isValid;
  }

  /**
   * 模拟主权级 ZKP 验证
   * 实际生产中会集成外部 ZKP 验证算子 (如 Circom + SnarkJS)
   */
  private static async verifySovereignProof(requirement: string, proofHash: string, traceId: string): Promise<boolean> {
    // 模拟 AGI 验证：如果包含 'valid' 字样或特定规则则通过
    const aiCheck = await AIService.analyzeSecurityRisk(`Verify ZKP Proof: ${proofHash} for requirement: ${requirement}`, traceId);
    return proofHash.startsWith('SOV_PROVE_') && !aiCheck.includes('HIGH_RISK');
  }

  /**
   * 检查租户是否已获得主权准入
   */
  static async isAdmitted(tenantId: string, sovereignId: string): Promise<boolean> {
    const admission = await db(this.ADMISSION_TABLE)
      .where({
        tenant_id: tenantId,
        sovereign_id: sovereignId,
        status: 'VERIFIED'
      })
      .first();
    
    return !!admission;
  }
}
