// CBDC Liquidity Management Service
// Liquidity windows, CBDC-to-SSU swaps

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


export interface LiquidityWindowRequest {
  sovereignBankId: string;
  windowType: string; // standing, emergency
  availableLiquidity: number;
  swapRate?: number;
}

export class CbdcLiquidityManagementService {
  /**
   * Create liquidity window
   */
  async createLiquidityWindow(request: LiquidityWindowRequest) {
    return await prisma.cbdc_liquidity_windows.create({
      data: {
        id: uuidv4(),
        windowId: `WINDOW-${uuidv4()}`,
        sovereignBankId: request.sovereignBankId,
        windowType: request.windowType,
        availableLiquidity: new Decimal(request.availableLiquidity),
        swapRate: request.swapRate ? new Decimal(request.swapRate) : null,
        status: 'open',
        createdAt: new Date(),
        updatedAt: new Date(),
      },
    });
  }

  /**
   * Close liquidity window
   */
  async closeLiquidityWindow(windowId: string) {
    return await prisma.cbdc_liquidity_windows.update({
      where: { windowId },
      data: {
        status: 'closed',
        closedAt: new Date(),
      },
    });
  }

  /**
   * Get open liquidity windows
   */
  async getOpenWindows(sovereignBankId?: string) {
    const where: any = {
      status: 'open',
    };

    if (sovereignBankId) {
      where.sovereignBankId = sovereignBankId;
    }

    return await prisma.cbdc_liquidity_windows.findMany({
      where,
    });
  }

  /**
   * Execute CBDC-to-SSU swap
   */
  async executeCbdcToSsuSwap(
    windowId: string,
    cbdcAmount: number,
    swapRate: number
  ) {
    const window = await prisma.cbdc_liquidity_windows.findUnique({
      where: { windowId },
    });

    if (!window || window.status !== 'open') {
      throw new Error('Liquidity window not available');
    }

    const ssuAmount = cbdcAmount * swapRate;
    const available = parseFloat(window.availableLiquidity.toString());

    if (available < cbdcAmount) {
      throw new Error('Insufficient liquidity');
    }

    // Update available liquidity
    await prisma.cbdc_liquidity_windows.update({
      where: { windowId },
      data: {
        availableLiquidity: new Decimal(available - cbdcAmount),
      },
    });

    return {
      cbdcAmount,
      ssuAmount,
      swapRate,
    };
  }
}

export const cbdcLiquidityManagementService = new CbdcLiquidityManagementService();

