// FX/CBDC/SSU Simulator Service
// Main simulation orchestrator

import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { fxVolatilityPredictorService } from './fx-volatility-predictor.service';
import { cbdcCirculationDynamicsService } from './cbdc-circulation-dynamics.service';
import { ssuStabilizationImpactService } from './ssu-stabilization-impact.service';
import { multiAssetContagionService } from './multi-asset-contagion.service';


export interface SimulationRequest {
  simulationType: string;
  parameters: Record<string, unknown>;
}

export class FxCbdcSsuSimulatorService {
  /**
   * Run A-FCSS simulation
   */
  async runSimulation(request: SimulationRequest) {
    const simulationId = `AFCSS-${uuidv4()}`;

    const simulation = await prisma.afcssSimulation.create({
      data: {
        simulationId,
        simulationType: request.simulationType,
        parameters: request.parameters,
        status: 'running',
      },
    });

    // Run simulation based on type
    let simulationResults: Record<string, unknown> = {};

    switch (request.simulationType) {
      case 'fx_volatility':
        simulationResults = await fxVolatilityPredictorService.predictVolatility(request.parameters);
        break;
      case 'cbdc_circulation':
        simulationResults = await cbdcCirculationDynamicsService.simulateCirculation(request.parameters);
        break;
      case 'ssu_stabilization':
        simulationResults = await ssuStabilizationImpactService.simulateStabilization(request.parameters);
        break;
      case 'multi_asset_contagion':
        simulationResults = await multiAssetContagionService.analyzeContagion(request.parameters);
        break;
    }

    // Calculate impact score
    const impactScore = this.calculateImpactScore(request.parameters);

    // Update simulation
    await prisma.afcssSimulation.update({
      where: { simulationId },
      data: {
        impactScore: new Decimal(impactScore),
        simulationResults,
        status: 'completed',
        completedAt: new Date(),
      },
    });

    return simulation;
  }

  /**
   * Calculate impact score
   */
  private calculateImpactScore(parameters: Record<string, unknown>): number {
    const fxVol = (parameters.fxVolatility as number) || 0;
    const cbdcVelocity = (parameters.cbdcVelocity as number) || 0;
    const ssuWeight = (parameters.ssuWeight as number) || 0;
    const liquidityShock = (parameters.liquidityShock as number) || 0;
    const sovereignStability = (parameters.sovereignStabilityIndex as number) || 1;

    // impact_score = (FX_vol * CBDC_velocity * SSU_weight) - liquidity_shock + sovereign_stability_index
    return (fxVol * cbdcVelocity * ssuWeight) - liquidityShock + sovereignStability;
  }

  /**
   * Get simulation by ID
   */
  async getSimulation(simulationId: string) {
    return await prisma.afcssSimulation.findUnique({
      where: { simulationId },
      include: {
        impacts: true,
        contagionRisks: true,
      },
    });
  }
}

export const fxCbdcSsuSimulatorService = new FxCbdcSsuSimulatorService();

