// MACE Valuation Service
// Multi-asset valuation

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


export interface ValuationRequest {
  assetType: string;
  amount: string;
  currencyCode: string;
}

export interface ValuationResult {
  valuation: string;
  currencyCode: string;
  fxRate?: string;
}

export class MaceValuationService {
  /**
   * Valuate asset
   */
  async valuateAsset(request: ValuationRequest): Promise<ValuationResult> {
    switch (request.assetType) {
      case 'fiat':
        return this.valuateFiat(request);
      case 'cbdc':
        return this.valuateCBDC(request);
      case 'commodity':
        return this.valuateCommodity(request);
      case 'security':
        return this.valuateSecurity(request);
      case 'ssu':
        return this.valuateSSU(request);
      default:
        throw new Error(`Unsupported asset type: ${request.assetType}`);
    }
  }

  /**
   * Valuate fiat
   */
  private async valuateFiat(request: ValuationRequest): Promise<ValuationResult> {
    // Fiat is already in currency, return as-is
    return {
      valuation: request.amount,
      currencyCode: request.currencyCode,
    };
  }

  /**
   * Valuate CBDC
   */
  private async valuateCBDC(request: ValuationRequest): Promise<ValuationResult> {
    // CBDC is 1:1 with fiat, return as-is
    return {
      valuation: request.amount,
      currencyCode: request.currencyCode,
    };
  }

  /**
   * Valuate commodity
   */
  private async valuateCommodity(request: ValuationRequest): Promise<ValuationResult> {
    // Get commodity price
    const commodity = await prisma.commodity_digital_tokens.findFirst({
      where: {
        commodityType: request.currencyCode, // Using currencyCode as commodity type
      },
    });

    if (!commodity) {
      throw new Error(`Commodity not found: ${request.currencyCode}`);
    }

    const amount = new Decimal(request.amount);
    // TODO: Fetch spot price from external pricing service or pricing table
    // For now, use default value of 1.0
    const spotPrice = new Decimal(1.0);
    const valuation = amount.mul(spotPrice);

    return {
      valuation: valuation.toString(),
      currencyCode: 'USD', // Commodities typically valued in USD
      fxRate: spotPrice.toString(),
    };
  }

  /**
   * Valuate security
   */
  private async valuateSecurity(request: ValuationRequest): Promise<ValuationResult> {
    // Get security price
    const security = await prisma.securities_sub_ledger.findFirst({
      where: {
        securityId: request.currencyCode, // Using currencyCode as security ID
      },
    });

    if (!security || !security.price) {
      throw new Error(`Security not found or no price: ${request.currencyCode}`);
    }

    const amount = new Decimal(request.amount);
    const valuation = amount.mul(security.price);

    return {
      valuation: valuation.toString(),
      currencyCode: request.currencyCode,
      fxRate: security.price.toString(),
    };
  }

  /**
   * Valuate SSU
   */
  private async valuateSSU(request: ValuationRequest): Promise<ValuationResult> {
    // Get SSU conversion rate
    const ssu = await prisma.synthetic_settlement_units.findFirst({
      where: {
        status: 'active',
      },
    });

    if (!ssu || !ssu.conversionRate) {
      throw new Error('SSU not found or no conversion rate');
    }

    const amount = new Decimal(request.amount);
    const valuation = amount.mul(ssu.conversionRate);

    return {
      valuation: valuation.toString(),
      currencyCode: request.currencyCode,
      fxRate: ssu.conversionRate.toString(),
    };
  }
}

export const maceValuationService = new MaceValuationService();

