// Autonomous Liquidity Provision System (ALPS) - Main Service

import { liquidityMonitorService } from './liquidity-monitor.service';
import { stressPredictorService } from './stress-predictor.service';
import { liquidityExecutorService } from './liquidity-executor.service';
import { AutonomousLiquidityAction, LiquidityStressEvent, SovereignLiquidityRatio } from './types';
import { logger } from '@/infrastructure/monitoring/logger';

export class ALPSService {
  /**
   * Main autonomous liquidity engine - monitors and executes actions
   */
  async runAutonomousEngine(): Promise<void> {
    logger.info('Running ALPS autonomous engine');

    // 1. Monitor liquidity
    const ratios = await liquidityMonitorService.monitorLiquidity();

    // 2. Predict stress events
    const stressEvents = await stressPredictorService.predictStressEvents();

    // 3. Execute injections/withdrawals based on thresholds
    for (const ratio of ratios) {
      // Check if injection needed
      if (ratio.ratio < 85) {
        const requiredAmount = await this.calculateRequiredLiquidity(ratio.sovereignBankId, ratio.ratio);
        if (requiredAmount > 0) {
          await liquidityExecutorService.executeInjection(
            ratio.sovereignBankId,
            requiredAmount,
            `SXLR below threshold: ${ratio.ratio.toFixed(2)}%`
          );
        }
      }

      // Check if withdrawal needed (excess liquidity)
      if (ratio.ratio > 120) {
        const excessAmount = await this.calculateExcessLiquidity(ratio.sovereignBankId, ratio.ratio);
        if (excessAmount > 0) {
          await liquidityExecutorService.executeWithdrawal(
            ratio.sovereignBankId,
            excessAmount,
            `SXLR above optimal: ${ratio.ratio.toFixed(2)}%`
          );
        }
      }
    }

    logger.info('ALPS autonomous engine completed');
  }

  /**
   * Calculate required liquidity for injection
   */
  private async calculateRequiredLiquidity(sovereignBankId: string, currentRatio: number): Promise<number> {
    // Target ratio: 100%
    const targetRatio = 100;
    const deficit = targetRatio - currentRatio;

    // Get sovereign's total balance
    const accounts = await liquidityMonitorService.getSXLR(sovereignBankId);
    if (!accounts) {
      return 0;
    }

    // Calculate required amount (simplified)
    const requiredAmount = (deficit / 100) * 1000000; // Base calculation

    return Math.max(0, requiredAmount);
  }

  /**
   * Calculate excess liquidity for withdrawal
   */
  private async calculateExcessLiquidity(sovereignBankId: string, currentRatio: number): Promise<number> {
    // Optimal ratio: 100%
    const optimalRatio = 100;
    const excess = currentRatio - optimalRatio;

    if (excess <= 0) {
      return 0;
    }

    // Calculate excess amount (simplified)
    const excessAmount = (excess / 100) * 1000000; // Base calculation

    return Math.max(0, excessAmount);
  }

  /**
   * Monitor liquidity
   */
  async monitorLiquidity(): Promise<SovereignLiquidityRatio[]> {
    return liquidityMonitorService.monitorLiquidity();
  }

  /**
   * Predict stress events
   */
  async predictStressEvents(): Promise<LiquidityStressEvent[]> {
    return stressPredictorService.predictStressEvents();
  }

  /**
   * Get liquidity actions
   */
  async getActions(sovereignBankId?: string, actionType?: any) {
    return liquidityExecutorService.getActions(sovereignBankId, actionType);
  }
}

export const alpsService = new ALPSService();

