// Sub-Ledger Service - FX, Securities, Commodities, Derivatives, CBDC, Custody, Collateral

import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';


/**
 * Sub-Ledger Service
 * Manages specialized sub-ledgers for different asset types
 */
export class SubLedgerService {
  /**
   * Create FX sub-ledger entry
   */
  async createFxSubLedgerEntry(
    ledgerEntryId: string,
    fxTradeId: string,
    baseCurrency: string,
    quoteCurrency: string,
    baseAmount: string,
    quoteAmount: string,
    fxRate: string
  ): Promise<void> {
    await prisma.fxSubLedger.create({
      data: {
        ledgerEntryId,
        fxTradeId,
        baseCurrency,
        quoteCurrency,
        baseAmount: new Decimal(baseAmount),
        quoteAmount: new Decimal(quoteAmount),
        fxRate: new Decimal(fxRate),
      },
    });
  }

  /**
   * Create Securities sub-ledger entry
   */
  async createSecuritiesSubLedgerEntry(
    ledgerEntryId: string,
    securityId: string,
    securityType: string,
    quantity: string,
    price?: string
  ): Promise<void> {
    await prisma.securitiesSubLedger.create({
      data: {
        ledgerEntryId,
        securityId,
        securityType,
        quantity: new Decimal(quantity),
        price: price ? new Decimal(price) : null,
      },
    });
  }

  /**
   * Create Commodities sub-ledger entry
   */
  async createCommoditiesSubLedgerEntry(
    ledgerEntryId: string,
    commodityType: string,
    quantity: string,
    unit: string,
    price?: string
  ): Promise<void> {
    await prisma.commoditiesSubLedger.create({
      data: {
        ledgerEntryId,
        commodityType,
        quantity: new Decimal(quantity),
        unit,
        price: price ? new Decimal(price) : null,
      },
    });
  }

  /**
   * Create Derivatives sub-ledger entry
   */
  async createDerivativesSubLedgerEntry(
    ledgerEntryId: string,
    derivativeType: string,
    notionalAmount: string,
    markToMarket?: string
  ): Promise<void> {
    await prisma.derivativesSubLedger.create({
      data: {
        ledgerEntryId,
        derivativeType,
        notionalAmount: new Decimal(notionalAmount),
        markToMarket: markToMarket ? new Decimal(markToMarket) : null,
      },
    });
  }

  /**
   * Create CBDC sub-ledger entry
   */
  async createCbdcSubLedgerEntry(
    ledgerEntryId: string,
    cbdcIssuanceId: string,
    walletId: string | null,
    operationType: string,
    amount: string
  ): Promise<void> {
    await prisma.cbdcSubLedger.create({
      data: {
        ledgerEntryId,
        cbdcIssuanceId,
        walletId,
        operationType,
        amount: new Decimal(amount),
      },
    });
  }

  /**
   * Create Custody sub-ledger entry
   */
  async createCustodySubLedgerEntry(
    ledgerEntryId: string,
    custodianId: string,
    assetType: string,
    quantity: string
  ): Promise<void> {
    await prisma.custodySubLedger.create({
      data: {
        ledgerEntryId,
        custodianId,
        assetType,
        quantity: new Decimal(quantity),
      },
    });
  }

  /**
   * Create Collateral sub-ledger entry
   */
  async createCollateralSubLedgerEntry(
    ledgerEntryId: string,
    collateralType: string,
    pledgedAmount: string,
    valuation: string
  ): Promise<void> {
    await prisma.collateralSubLedger.create({
      data: {
        ledgerEntryId,
        collateralType,
        pledgedAmount: new Decimal(pledgedAmount),
        valuation: new Decimal(valuation),
      },
    });
  }

  /**
   * Get FX sub-ledger entries for a trade
   */
  async getFxSubLedgerEntries(fxTradeId: string) {
    return await prisma.fxSubLedger.findMany({
      where: { fxTradeId },
    });
  }

  /**
   * Get Securities sub-ledger entries for a security
   */
  async getSecuritiesSubLedgerEntries(securityId: string) {
    return await prisma.securitiesSubLedger.findMany({
      where: { securityId },
    });
  }

  /**
   * Get Commodities sub-ledger entries
   */
  async getCommoditiesSubLedgerEntries(commodityType: string) {
    return await prisma.commoditiesSubLedger.findMany({
      where: { commodityType },
    });
  }

  /**
   * Get CBDC sub-ledger entries for an issuance
   */
  async getCbdcSubLedgerEntries(cbdcIssuanceId: string) {
    return await prisma.cbdcSubLedger.findMany({
      where: { cbdcIssuanceId },
    });
  }
}

export const subLedgerService = new SubLedgerService();

