// SNFN Settlement Service
// Fund disbursement via CBDC, SSU, commodity tokens, tokenized bonds

import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';


export interface DisburseRequest {
  nodeId: string;
  loanId?: string;
  disbursementType: string; // cbdc, ssu, commodity_token, tokenized_bond
  amount: string;
  currencyCode: string;
  assetId?: string; // Asset ID if tokenized
}

export interface SettlementResult {
  settlementId: string;
  status: string;
}

export class SnfnSettlementService {
  /**
   * Disburse funds
   */
  async disburseFunds(request: DisburseRequest): Promise<SettlementResult> {
    const node = await prisma.supra_fund_nodes.findUnique({
      where: { nodeId: request.nodeId },
    });

    if (!node) {
      throw new Error(`Node not found: ${request.nodeId}`);
    }

    // Check available liquidity
    const disbursementAmount = new Decimal(request.amount);
    if (disbursementAmount.gt(node.availableLiquidity)) {
      throw new Error('Insufficient liquidity');
    }

    const settlementId = `SNFN-SETTLE-${uuidv4()}`;

    const settlement = await prisma.supra_fund_settlements.create({
      data: {
        settlementId,
        nodeId: request.nodeId,
        loanId: request.loanId || null,
        disbursementType: request.disbursementType,
        amount: disbursementAmount,
        currencyCode: request.currencyCode,
        assetId: request.assetId || null,
        status: 'pending',
      },
    });

    // Update node liquidity
    await prisma.supra_fund_nodes.update({
      where: { nodeId: request.nodeId },
      data: {
        availableLiquidity: node.availableLiquidity.minus(disbursementAmount),
      },
    });

    // Mark as disbursed (in production, this would trigger actual disbursement)
    await prisma.supra_fund_settlements.update({
      where: { settlementId },
      data: {
        status: 'disbursed',
        disbursedAt: new Date(),
      },
    });

    return {
      settlementId: settlement.settlementId,
      status: 'disbursed',
    };
  }

  /**
   * Finalize settlement
   */
  async finalizeSettlement(settlementId: string): Promise<void> {
    await prisma.supra_fund_settlements.update({
      where: { settlementId },
      data: {
        status: 'settled',
        settledAt: new Date(),
      },
    });
  }

  /**
   * Get settlement
   */
  async getSettlement(settlementId: string) {
    return await prisma.supra_fund_settlements.findUnique({
      where: { settlementId },
      include: {
        node: true,
      },
    });
  }

  /**
   * List settlements
   */
  async listSettlements(nodeId?: string, loanId?: string) {
    return await prisma.supra_fund_settlements.findMany({
      where: {
        ...(nodeId ? { nodeId } : {}),
        ...(loanId ? { loanId } : {}),
      },
      orderBy: { createdAt: 'desc' },
    });
  }
}

export const snfnSettlementService = new SnfnSettlementService();

