// MACE Allocation Service
// Optimal collateral allocation logic

import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { maceOptimizationService } from './mace-optimization.service';


export interface AllocationRequest {
  requiredAmount: string;
  currencyCode: string;
  assetTypes: string[]; // fiat, cbdc, commodity, security, ssu
  targetBankId?: string;
}

export interface AllocationResult {
  collateralId: string;
  allocations: Array<{
    assetType: string;
    amount: string;
    valuation: string;
  }>;
  totalValuation: string;
}

export class MaceAllocationService {
  /**
   * Allocate multi-asset collateral
   */
  async allocateCollateral(
    request: AllocationRequest
  ): Promise<AllocationResult> {
    // Get available assets
    const availableAssets = await this.getAvailableAssets(
      request.assetTypes,
      request.targetBankId
    );

    // Optimize allocation
    const optimization = await maceOptimizationService.optimizeAllocation({
      requiredAmount: request.requiredAmount,
      currencyCode: request.currencyCode,
      availableAssets,
      targetBankId: request.targetBankId,
    });

    // Create collateral allocations
    const collateralId = `COLL-${uuidv4()}`;
    const allocations = [];

    for (const allocation of optimization.optimalAllocation) {
      const valuation = await this.valuateAsset(
        allocation.assetType,
        allocation.amount,
        request.currencyCode
      );

      await prisma.multi_asset_collaterals.create({
        data: {
          id: uuidv4(),
          collateralId: `${collateralId}-${allocation.assetType}`,
          updatedAt: new Date(),
          assetType: allocation.assetType,
          assetId: allocation.assetId,
          amount: new Decimal(allocation.amount),
          valuation,
          status: 'active',
          createdAt: new Date(),
        },
      });

      allocations.push({
        assetType: allocation.assetType,
        amount: allocation.amount,
        valuation: valuation.toString(),
      });
    }

    // Calculate total valuation
    const totalValuation = allocations.reduce(
      (sum, alloc) => sum.plus(new Decimal(alloc.valuation)),
      new Decimal(0)
    );

    // Apply optimization
    await maceOptimizationService.applyOptimization(optimization.optimizationId);

    return {
      collateralId,
      allocations,
      totalValuation: totalValuation.toString(),
    };
  }

  /**
   * Get available assets
   */
  private async getAvailableAssets(
    assetTypes: string[],
    targetBankId?: string
  ): Promise<Array<{ assetType: string; assetId?: string; amount: string }>> {
    // In production, would query actual asset holdings
    // For now, return mock data
    const assets: Array<{ assetType: string; assetId?: string; amount: string }> = [];

    for (const assetType of assetTypes) {
      assets.push({
        assetType,
        amount: '1000000', // Mock amount
      });
    }

    return assets;
  }

  /**
   * Valuate asset
   */
  private async valuateAsset(
    assetType: string,
    amount: string,
    targetCurrency: string
  ): Promise<Decimal> {
    // In production, would use actual valuation service
    // For now, return amount as valuation (1:1)
    return new Decimal(amount);
  }

  /**
   * Release collateral
   */
  async releaseCollateral(collateralId: string): Promise<void> {
    await prisma.multi_asset_collaterals.updateMany({
      where: {
        collateralId: {
          startsWith: collateralId,
        },
        status: 'active',
      },
      data: {
        status: 'released',
        releasedAt: new Date(),
      },
    });
  }
}

export const maceAllocationService = new MaceAllocationService();

