// GRU ARI Integration Service
// Volume II: Supranational Reserve Framework
// Autonomous Regulatory Intelligence for compliance and automated warnings

import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { logger } from '@/infrastructure/monitoring/logger';
import { gruSareIntegrationService } from './gru-sare-integration.service';


export interface ComplianceWarning {
  warningId: string;
  warningType: string;
  severity: 'low' | 'medium' | 'high' | 'critical';
  entityId?: string;
  poolId?: string;
  sovereignBankId?: string;
  message: string;
  recommendation: string;
  timestamp: Date;
}

export interface ComplianceCheckResult {
  compliant: boolean;
  warnings: ComplianceWarning[];
  violations: ComplianceWarning[];
}

export class GruAriIntegrationService {
  /**
   * Ensure compliance with reserve pool regulations
   */
  async ensureCompliance(
    poolId?: string,
    entityId?: string
  ): Promise<ComplianceCheckResult> {
    logger.info('GRU ARI: Ensuring compliance', { poolId, entityId });

    const warnings: ComplianceWarning[] = [];
    const violations: ComplianceWarning[] = [];

    if (poolId) {
      // Check specific pool
      const poolChecks = await this.checkPoolCompliance(poolId);
      warnings.push(...poolChecks.warnings);
      violations.push(...poolChecks.violations);
    } else if (entityId) {
      // Check all pools for entity
      const pools = await prisma.gruReservePool.findMany({
        where: { entityId },
      });

      for (const pool of pools) {
        const poolChecks = await this.checkPoolCompliance(pool.poolId);
        warnings.push(...poolChecks.warnings);
        violations.push(...poolChecks.violations);
      }
    } else {
      // Check all pools
      const pools = await prisma.gruReservePool.findMany({
        where: { status: 'active' },
      });

      for (const pool of pools) {
        const poolChecks = await this.checkPoolCompliance(pool.poolId);
        warnings.push(...poolChecks.warnings);
        violations.push(...poolChecks.violations);
      }
    }

    const compliant = violations.length === 0;

    logger.info('GRU ARI: Compliance check completed', {
      compliant,
      warnings: warnings.length,
      violations: violations.length,
    });

    return {
      compliant,
      warnings,
      violations,
    };
  }

  /**
   * Check pool compliance
   */
  private async checkPoolCompliance(
    poolId: string
  ): Promise<{ warnings: ComplianceWarning[]; violations: ComplianceWarning[] }> {
    const warnings: ComplianceWarning[] = [];
    const violations: ComplianceWarning[] = [];

    const pool = await prisma.gruReservePool.findUnique({
      where: { poolId },
      include: {
        entity: true,
        allocations: {
          where: { status: 'confirmed' },
        },
        withdrawals: {
          where: { approvalStatus: 'pending' },
        },
      },
    });

    if (!pool) {
      return { warnings, violations };
    }

    // Check 1: Reserve adequacy
    const adequacy = await gruSareIntegrationService.calculateReserveAdequacy(
      pool.entityId || undefined
    );

    if (adequacy.reserveAdequacy.lt(80)) {
      const warning: ComplianceWarning = {
        warningId: `WARN-${uuidv4()}`,
        warningType: 'reserve_adequacy',
        severity: adequacy.reserveAdequacy.lt(60) ? 'critical' : 'high',
        poolId,
        entityId: pool.entityId || undefined,
        message: `Reserve adequacy is ${adequacy.reserveAdequacy.toString()}% (below 80% threshold)`,
        recommendation: 'Increase reserve allocations to meet adequacy requirements',
        timestamp: new Date(),
      };

      if (adequacy.reserveAdequacy.lt(60)) {
        violations.push(warning);
      } else {
        warnings.push(warning);
      }
    }

    // Check 2: Excessive withdrawals
    const pendingWithdrawals = pool.withdrawals.reduce(
      (sum, w) => sum.plus(w.amount),
      new Decimal(0)
    );

    const withdrawalRatio = pool.totalReserves.gt(0)
      ? pendingWithdrawals.dividedBy(pool.totalReserves)
      : new Decimal(0);

    if (withdrawalRatio.gt(0.5)) {
      const warning: ComplianceWarning = {
        warningId: `WARN-${uuidv4()}`,
        warningType: 'excessive_withdrawals',
        severity: withdrawalRatio.gt(0.75) ? 'high' : 'medium',
        poolId,
        entityId: pool.entityId || undefined,
        message: `Pending withdrawals represent ${withdrawalRatio.times(100).toString()}% of total reserves`,
        recommendation: 'Review withdrawal requests and ensure adequate reserves remain',
        timestamp: new Date(),
      };

      if (withdrawalRatio.gt(0.75)) {
        violations.push(warning);
      } else {
        warnings.push(warning);
      }
    }

    // Check 3: Pool status
    if (pool.status !== 'active') {
      const warning: ComplianceWarning = {
        warningId: `WARN-${uuidv4()}`,
        warningType: 'pool_status',
        severity: 'medium',
        poolId,
        entityId: pool.entityId || undefined,
        message: `Pool status is ${pool.status} (expected: active)`,
        recommendation: 'Review pool status and reactivate if appropriate',
        timestamp: new Date(),
      };

      warnings.push(warning);
    }

    // Check 4: Reserve concentration
    if (pool.allocations.length > 0) {
      const allocationAmounts = pool.allocations.map((a) => a.amount);
      const maxAllocation = Decimal.max(...allocationAmounts);
      const concentrationRatio = pool.totalReserves.gt(0)
        ? maxAllocation.dividedBy(pool.totalReserves)
        : new Decimal(0);

      if (concentrationRatio.gt(0.4)) {
        const warning: ComplianceWarning = {
          warningId: `WARN-${uuidv4()}`,
          warningType: 'reserve_concentration',
          severity: 'medium',
          poolId,
          entityId: pool.entityId || undefined,
          message: `Single allocation represents ${concentrationRatio.times(100).toString()}% of total reserves`,
          recommendation: 'Diversify reserve allocations to reduce concentration risk',
          timestamp: new Date(),
        };

        warnings.push(warning);
      }
    }

    return { warnings, violations };
  }

  /**
   * Issue automated warning
   */
  async issueWarning(warning: ComplianceWarning): Promise<void> {
    logger.warn('GRU ARI: Issuing compliance warning', {
      warningId: warning.warningId,
      warningType: warning.warningType,
      severity: warning.severity,
    });

    // In production, would:
    // 1. Store warning in database
    // 2. Send notification to relevant parties
    // 3. Trigger automated responses if critical
    // 4. Log to compliance audit trail

    // For now, just log
    if (warning.severity === 'critical') {
      logger.error('GRU ARI: CRITICAL compliance violation', {
        warningId: warning.warningId,
        message: warning.message,
      });
    }
  }

  /**
   * Check SMIA compliance (Sovereign Monetary Instruments Act)
   */
  async checkSmiaCompliance(
    entityId?: string,
    sovereignBankId?: string
  ): Promise<boolean> {
    logger.info('GRU ARI: Checking SMIA compliance', {
      entityId,
      sovereignBankId,
    });

    if (entityId) {
      const entity = await prisma.supranationalEntity.findUnique({
        where: { entityId },
      });

      if (!entity || entity.status !== 'active') {
        return false;
      }

      // Check member compliance
      const members = await prisma.supranationalEntityMember.findMany({
        where: { entityId, status: 'active' },
        include: { sovereignBank: true },
      });

      return members.every((m) => m.sovereignBank.status === 'active');
    } else if (sovereignBankId) {
      const bank = await prisma.sovereignBank.findUnique({
        where: { id: sovereignBankId },
      });

      return bank?.status === 'active';
    }

    return false;
  }

  /**
   * Check ILIE compliance (causality-stable sovereign identity)
   */
  async checkIlieCompliance(sovereignBankId: string): Promise<boolean> {
    logger.info('GRU ARI: Checking ILIE compliance', { sovereignBankId });

    const bank = await prisma.sovereignBank.findUnique({
      where: { id: sovereignBankId },
      include: {
        identities: {
          where: { status: 'active' },
        },
      },
    });

    if (!bank) {
      return false;
    }

    // Check for root sovereign key (causality-stable identity)
    if (!bank.rootSovereignKey) {
      return false;
    }

    // Check for active identities
    if (bank.identities.length === 0) {
      return false;
    }

    return true;
  }

  /**
   * Automated compliance monitoring
   * Runs periodic checks and issues warnings
   */
  async automatedMonitoring(): Promise<void> {
    logger.info('GRU ARI: Running automated compliance monitoring');

    const compliance = await this.ensureCompliance();

    // Issue warnings for all violations and high-severity warnings
    for (const violation of compliance.violations) {
      await this.issueWarning(violation);
    }

    for (const warning of compliance.warnings) {
      if (warning.severity === 'high' || warning.severity === 'critical') {
        await this.issueWarning(warning);
      }
    }

    logger.info('GRU ARI: Automated monitoring completed', {
      violations: compliance.violations.length,
      warnings: compliance.warnings.length,
    });
  }
}

export const gruAriIntegrationService = new GruAriIntegrationService();

