// IBIN Settlement Service
// Real-time bond trade settlement

import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { gssMasterLedgerService } from '@/core/settlement/gss/gss-master-ledger.service';
import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';

export interface BondSettlementRequest {
  tradeId: string;
  nodeId: string;
}

export interface SettlementResult {
  settlementId: string;
  status: string;
  sovereignLedgerHash?: string;
  dbisLedgerHash?: string;
}

export class IbinSettlementService {
  /**
   * Settle bond trade
   */
  async settleTrade(
    request: BondSettlementRequest
  ): Promise<SettlementResult> {
    const trade = await prisma.bond_trades.findUnique({
      where: { tradeId: request.tradeId },
      include: { bond: true },
    });

    if (!trade) {
      throw new Error(`Trade not found: ${request.tradeId}`);
    }

    if (trade.status !== 'pending') {
      throw new Error(`Trade cannot be settled: ${trade.status}`);
    }

    // Post to GSS Master Ledger for dual-ledger settlement
    const ledgerResult = await gssMasterLedgerService.postToMasterLedger({
      nodeId: request.nodeId,
      sourceBankId: trade.sellerBankId,
      destinationBankId: trade.buyerBankId,
      amount: trade.tradeAmount.toString(),
      currencyCode: trade.gru_bonds.currencyCode,
      assetType: 'security',
    });

    // Update trade with settlement reference
    const settlementId = `BSETTLE-${uuidv4()}`;
    await prisma.bond_trades.update({
      where: { tradeId: request.tradeId },
      data: {
        settlementId,
        status: 'settled',
        settledAt: new Date(),
      },
    });

    return {
      settlementId,
      status: 'settled',
      sovereignLedgerHash: ledgerResult.sovereignLedgerHash,
      dbisLedgerHash: ledgerResult.dbisLedgerHash,
    };
  }

  /**
   * Get settlement status
   */
  async getSettlementStatus(tradeId: string): Promise<string | null> {
    const trade = await prisma.bond_trades.findUnique({
      where: { tradeId },
      select: { status: true },
    });

    return trade?.status || null;
  }

  /**
   * Batch settle trades
   */
  async batchSettleTrades(
    tradeIds: string[],
    nodeId: string
  ): Promise<SettlementResult[]> {
    const results: SettlementResult[] = [];

    for (const tradeId of tradeIds) {
      try {
        const result = await this.settleTrade({ tradeId, nodeId });
        results.push(result);
      } catch (error) {
        // Continue with other trades
        logger.error('Failed to settle trade', {
          tradeId,
          error: error instanceof Error ? error.message : 'Unknown error',
        });
      }
    }

    return results;
  }
}

export const ibinSettlementService = new IbinSettlementService();

