// DBIS Admin Console - CBDC & FX Service
// CBDC wallet schemas, FX/GRU/SSU routing

import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';
import Decimal from 'decimal.js';

export interface CBDCSchema {
  scbId: string;
  scbName: string;
  cbdcTypes: Array<{
    type: string; // rCBDC, wCBDC, iCBDC
    status: 'active' | 'pending' | 'suspended';
    inCirculation: number;
  }>;
  crossBorderCorridors: Array<{
    targetSCB: string;
    settlementAsset: string; // SSU, GRU
    status: 'active' | 'pending';
  }>;
}

export interface FXRouting {
  corridors: Array<{
    sourceSCB: string;
    destinationSCB: string;
    preferredSettlementAsset: string;
    volume24h: number;
    spreads: {
      min: number;
      max: number;
    };
    fees: {
      min: number;
      max: number;
    };
    circuitBreakers: {
      enabled: boolean;
      volatilityThreshold: number;
    };
  }>;
  ssuUsage: {
    totalVolume: number;
    activeCorridors: number;
  };
  gruBridgeUsage: {
    totalVolume: number;
    activeCorridors: number;
  };
}

export interface CBDCFXDashboard {
  cbdcSchemas: CBDCSchema[];
  fxRouting: FXRouting;
}

export class CBDCFXService {
  /**
   * Get CBDC & FX dashboard
   */
  async getCBDCFXDashboard(): Promise<CBDCFXDashboard> {
    const [cbdcSchemas, fxRouting] = await Promise.all([
      this.getCBDCSchemas(),
      this.getFXRouting(),
    ]);

    return { cbdcSchemas, fxRouting };
  }

  /**
   * Get CBDC schemas across all SCBs
   */
  async getCBDCSchemas(): Promise<CBDCSchema[]> {
    const scbs = await prisma.sovereignBank.findMany({
      where: { status: 'active' },
    });

    const schemas: CBDCSchema[] = [];

    for (const scb of scbs) {
      // Get CBDC issuances
      const issuances = await prisma.cbdcIssuance.findMany({
        where: { sovereignBankId: scb.id },
      });

      // Get CBDC wallets
      const wallets = await prisma.cbdcWallet.findMany({
        where: { sovereignBankId: scb.id },
      });

      // Group by type
      const cbdcTypes = [
        {
          type: 'rCBDC',
          status: 'active' as const,
          inCirculation: wallets
            .filter((w) => w.walletType === 'retail')
            .reduce((sum, w) => sum.plus(w.balance), new Decimal(0))
            .toNumber(),
        },
        {
          type: 'wCBDC',
          status: 'active' as const,
          inCirculation: wallets
            .filter((w) => w.walletType === 'wholesale')
            .reduce((sum, w) => sum.plus(w.balance), new Decimal(0))
            .toNumber(),
        },
        {
          type: 'iCBDC',
          status: 'active' as const,
          inCirculation: wallets
            .filter((w) => w.walletType === 'institutional')
            .reduce((sum, w) => sum.plus(w.balance), new Decimal(0))
            .toNumber(),
        },
      ];

      // Get cross-border corridors
      const routes = await prisma.settlementRoute.findMany({
        where: {
          OR: [{ sourceBankId: scb.id }, { destinationBankId: scb.id }],
          status: 'active',
        },
      });

      const crossBorderCorridors = routes.map((route) => ({
        targetSCB: route.sourceBankId === scb.id ? route.destinationBankId : route.sourceBankId,
        settlementAsset: 'SSU', // Default, would check actual usage
        status: 'active' as const,
      }));

      schemas.push({
        scbId: scb.id,
        scbName: scb.name,
        cbdcTypes,
        crossBorderCorridors,
      });
    }

    return schemas;
  }

  /**
   * Get FX routing information
   */
  async getFXRouting(): Promise<FXRouting> {
    const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);

    // Get all active routes
    const routes = await prisma.settlementRoute.findMany({
      where: { status: 'active' },
    });

    // Get FX trades
    const fxTrades = await prisma.fxTrade.findMany({
      where: {
        createdAt: { gte: oneDayAgo },
      },
    });

    // Get SSU transactions
    const ssuTransactions = await prisma.ssuTransaction.findMany({
      where: {
        createdAt: { gte: oneDayAgo },
        status: 'completed',
      },
    });

    const ssuVolume = ssuTransactions.reduce(
      (sum, t) => sum.plus(t.amount),
      new Decimal(0)
    ).toNumber();

    // Build corridors
    const corridors = routes.map((route) => {
      const routeTrades = fxTrades.filter(
        (t) =>
          (t.sovereignBankId === route.sourceBankId ||
            t.sovereignBankId === route.destinationBankId) &&
          t.baseCurrency === route.currencyCode
      );

      const volume24h = routeTrades
        .filter((t) => t.status === 'executed')
        .reduce((sum, t) => sum.plus(t.quantity), new Decimal(0))
        .toNumber();

      return {
        sourceSCB: route.sourceBankId,
        destinationSCB: route.destinationBankId,
        preferredSettlementAsset: 'SSU', // Default
        volume24h,
        spreads: {
          min: 0.0001,
          max: 0.01,
        },
        fees: {
          min: 0.001,
          max: 0.05,
        },
        circuitBreakers: {
          enabled: true,
          volatilityThreshold: 0.05, // 5%
        },
      };
    });

    return {
      corridors,
      ssuUsage: {
        totalVolume: ssuVolume,
        activeCorridors: new Set(routes.map((r) => `${r.sourceBankId}-${r.destinationBankId}`))
          .size,
      },
      gruBridgeUsage: {
        totalVolume: 0, // Would calculate from GRU transactions
        activeCorridors: 0,
      },
    };
  }
}

export const cbdcFxService = new CBDCFXService();

