// DBIS Admin Console - Participants & Jurisdictions Service
// SCB directory, jurisdiction settings, corridor management

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

export interface ParticipantInfo {
  scbId: string;
  name: string;
  country: string;
  bic?: string;
  lei?: string;
  status: string;
  connectivity: 'connected' | 'degraded' | 'disconnected';
  lastHeartbeat?: Date;
  latency?: number;
  errorRate?: number;
}

export interface JurisdictionSettings {
  scbId: string;
  allowedAssetClasses: string[];
  corridorRules: Array<{
    targetSCB: string;
    caps: number;
    allowedSettlementAssets: string[];
  }>;
  regulatoryProfiles: {
    amlStrictness: 'low' | 'medium' | 'high';
    sanctionsLists: string[];
    reportingFrequency: string;
  };
}

export interface CorridorInfo {
  routeId: string;
  sourceSCB: string;
  destinationSCB: string;
  currencyCode: string;
  status: string;
  volume24h: number;
  latency: number;
  errorRate: number;
}

export class ParticipantsService {
  /**
   * Get participant directory
   */
  async getParticipantDirectory(): Promise<ParticipantInfo[]> {
    const scbs = await prisma.sovereign_banks.findMany({
      orderBy: { name: 'asc' },
    });

    const participants: ParticipantInfo[] = [];

    for (const scb of scbs) {
      // Get recent activity to determine connectivity
      const recentSettlements = await prisma.atomic_settlements.findMany({
        where: {
          OR: [{ sourceBankId: scb.id }, { destinationBankId: scb.id }],
          createdAt: {
            gte: new Date(Date.now() - 5 * 60 * 1000),
          },
        },
        take: 10,
      });

      const connectivity =
        recentSettlements.length > 0 ? 'connected' : 'degraded';

      participants.push({
        scbId: scb.id,
        name: scb.name,
        country: scb.sovereignCode,
        bic: scb.bic || undefined,
        lei: scb.lei || undefined,
        status: scb.status,
        connectivity,
        lastHeartbeat: scb.updatedAt,
      });
    }

    return participants;
  }

  /**
   * Get participant details
   */
  async getParticipantDetails(scbId: string): Promise<ParticipantInfo | null> {
    const scb = await prisma.sovereign_banks.findUnique({
      where: { id: scbId },
    });

    if (!scb) {
      return null;
    }

      const recentSettlements = await prisma.atomic_settlements.findMany({
      where: {
        OR: [{ sourceBankId: scb.id }, { destinationBankId: scb.id }],
        createdAt: {
          gte: new Date(Date.now() - 5 * 60 * 1000),
        },
      },
      take: 100,
    });

    const successCount = recentSettlements.filter((s) => s.status === 'settled').length;
    const errorRate = recentSettlements.length > 0 ? 1 - successCount / recentSettlements.length : 0;

    return {
      scbId: scb.id,
      name: scb.name,
      country: scb.sovereignCode,
      bic: scb.bic || undefined,
      lei: scb.lei || undefined,
      status: scb.status,
      connectivity: recentSettlements.length > 0 ? 'connected' : 'degraded',
      lastHeartbeat: scb.updatedAt,
      errorRate,
    };
  }

  /**
   * Get jurisdiction settings for SCB
   */
  async getJurisdictionSettings(scbId: string): Promise<JurisdictionSettings | null> {
    const scb = await prisma.sovereign_banks.findUnique({
      where: { id: scbId },
    });

    if (!scb) {
      return null;
    }

    // Get corridors for this SCB
    const routes = await prisma.settlement_routes.findMany({
      where: {
        OR: [{ sourceBankId: scbId }, { destinationBankId: scbId }],
        status: 'active',
      },
    });

    const corridorRules = routes.map((route) => ({
      targetSCB: route.sourceBankId === scbId ? route.destinationBankId : route.sourceBankId,
      caps: route.sireCost ? parseFloat(route.sireCost.toString()) : 0,
      allowedSettlementAssets: [route.currencyCode],
    }));

    return {
      scbId,
      allowedAssetClasses: ['FIAT', 'CBDC', 'GRU', 'SSU', 'commodities'],
      corridorRules,
      regulatoryProfiles: {
        amlStrictness: 'medium',
        sanctionsLists: ['OFAC', 'EU', 'UN'],
        reportingFrequency: 'daily',
      },
    };
  }

  /**
   * Get all corridors
   */
  async getCorridors(): Promise<CorridorInfo[]> {
    const routes = await prisma.settlement_routes.findMany({
      where: { status: 'active' },
      // include: {
      //   routingDecisions: { // Field doesn't exist in schema
      //     orderBy: { createdAt: 'desc' },
      //     take: 1,
      //   },
      // },
    });

    const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);

    const corridors: CorridorInfo[] = [];

    for (const route of routes) {
      // Get 24h volume
      const settlements = await prisma.atomic_settlements.findMany({
        where: {
          sourceBankId: route.sourceBankId,
          destinationBankId: route.destinationBankId,
          currencyCode: route.currencyCode,
          createdAt: { gte: oneDayAgo },
        },
      });

      const volume24h = settlements
        .filter((s: any) => s.status === 'settled')
        .reduce((sum: any, s: any) => sum.plus(s.amount), new Decimal(0))
        .toNumber();

      const successCount = settlements.filter((s: any) => s.status === 'settled').length;
      const errorRate = settlements.length > 0 ? 1 - successCount / settlements.length : 0;

      corridors.push({
        routeId: route.routeId,
        sourceSCB: route.sourceBankId,
        destinationSCB: route.destinationBankId,
        currencyCode: route.currencyCode,
        status: route.status,
        volume24h,
        latency: route.estimatedLatency || 0,
        errorRate,
      });
    }

    return corridors;
  }
}

export const participantsService = new ParticipantsService();

