// DBIS Admin Console - GAS & QPS Control Service
// GAS atomic settlement control, QPS legacy rails management

import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';
import Decimal from 'decimal.js';
import { listGatewayRailAdapterIds } from '@/core/gateway/adapters/gateway-adapter-registry';

export interface GASMetrics {
  atomicSettlementSuccessRate: number;
  averageLatency: number;
  perAssetBreakdown: {
    currency: { successRate: number; volume: number };
    cbdc: { successRate: number; volume: number };
    commodity: { successRate: number; volume: number };
    security: { successRate: number; volume: number };
  };
  assetLevelLimits: Array<{
    assetClass: string;
    maxNotionalPerSCB: number;
  }>;
}

export interface QPSMetrics {
  legacyRails: Array<{
    railType: string; // SWIFT, ISO20022, RTGS
    enabled: boolean;
    volume24h: number;
    errorRate: number;
  }>;
  mappingProfiles: Array<{
    profileId: string;
    profileName: string;
    acceptedMessages: string[];
    validationLevel: string;
  }>;
}

export interface GASQPSDashboard {
  gas: GASMetrics;
  qps: QPSMetrics;
}

export class GASQPSService {
  /**
   * Get GAS & QPS dashboard
   */
  async getGASQPSDashboard(): Promise<GASQPSDashboard> {
    const [gas, qps] = await Promise.all([this.getGASMetrics(), this.getQPSMetrics()]);

    return { gas, qps };
  }

  /**
   * Get GAS metrics
   */
  async getGASMetrics(): Promise<GASMetrics> {
    const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);

    // Get all atomic settlements in last 24 hours
    const settlements = await prisma.atomic_settlements.findMany({
      where: {
        createdAt: { gte: oneDayAgo },
      },
    });

    const total = settlements.length;
    const successful = settlements.filter((s: any) => s.status === 'settled').length;
    const successRate = total > 0 ? successful / total : 1.0;

    // Calculate average latency
    const settledSettlements = settlements.filter((s: any) => s.status === 'settled' && s.settlementTime);
    const avgLatency =
      settledSettlements.length > 0
        ? settledSettlements.reduce((sum: any, s: any) => sum + (s.settlementTime || 0), 0) /
          settledSettlements.length
        : 0;

    // Per asset breakdown
    const perAssetBreakdown = {
      currency: { successRate: 0, volume: 0 },
      cbdc: { successRate: 0, volume: 0 },
      commodity: { successRate: 0, volume: 0 },
      security: { successRate: 0, volume: 0 },
    };

    ['currency', 'cbdc', 'commodity', 'security'].forEach((assetType) => {
      const assetSettlements = settlements.filter((s: any) => s.assetType === assetType);
      const assetSuccessful = assetSettlements.filter((s: any) => s.status === 'settled').length;
      const assetVolume = assetSettlements
        .filter((s: any) => s.status === 'settled')
        .reduce((sum: any, s: any) => sum.plus(s.amount), new Decimal(0))
        .toNumber();

      perAssetBreakdown[assetType as keyof typeof perAssetBreakdown] = {
        successRate: assetSettlements.length > 0 ? assetSuccessful / assetSettlements.length : 0,
        volume: assetVolume,
      };
    });

    // Asset level limits (placeholder - would come from configuration)
    const assetLevelLimits = [
      { assetClass: 'currency', maxNotionalPerSCB: 1000000000 },
      { assetClass: 'cbdc', maxNotionalPerSCB: 500000000 },
      { assetClass: 'commodity', maxNotionalPerSCB: 200000000 },
      { assetClass: 'security', maxNotionalPerSCB: 1000000000 },
    ];

    return {
      atomicSettlementSuccessRate: successRate,
      averageLatency: avgLatency,
      perAssetBreakdown,
      assetLevelLimits,
    };
  }

  /**
   * Get QPS metrics
   */
  async getQPSMetrics(): Promise<QPSMetrics> {
    const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);

    // Get ISO 20022 messages (QPS)
    const isoMessages = await prisma.iso_messages.findMany({
      where: {
        createdAt: { gte: oneDayAgo },
      },
    });

    // Group by message type
    const messageTypes = new Map<string, number>();
    isoMessages.forEach((msg: any) => {
      const count = messageTypes.get(msg.messageType) || 0;
      messageTypes.set(msg.messageType, count + 1);
    });

    // Legacy rails: core buckets + SolaceNet gateway adapter IDs (volumes still heuristic until QPS integration)
    const solaceNetRails = listGatewayRailAdapterIds().map((adapterId) => ({
      railType: adapterId,
      enabled: true,
      volume24h: 0,
      errorRate: 0,
    }));
    const legacyRails = [
      {
        railType: 'SWIFT',
        enabled: true,
        volume24h: isoMessages.filter((m: any) => m.messageType.includes('SWIFT')).length,
        errorRate: 0.01,
      },
      {
        railType: 'ISO20022',
        enabled: true,
        volume24h: isoMessages.length,
        errorRate: 0.005,
      },
      {
        railType: 'RTGS',
        enabled: true,
        volume24h: 0,
        errorRate: 0,
      },
      ...solaceNetRails,
    ];

    // Mapping profiles (placeholder)
    const mappingProfiles = [
      {
        profileId: 'default',
        profileName: 'Default ISO 20022 Profile',
        acceptedMessages: Array.from(messageTypes.keys()),
        validationLevel: 'standard',
      },
    ];

    return {
      legacyRails,
      mappingProfiles,
    };
  }
}

export const gasQpsService = new GASQPSService();

