// DBIS Global Multiversal Monetary Theory - Valuation Service
// Multiversal valuation formula implementation

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


export interface ValuationRequest {
  layerId: string;
  unitId: string;
  assetId?: string;
  classicalValue: number;
  quantumExpectedValue?: number;
  holographicProjection?: number;
  parallelArbitrageAdjustment?: number;
}

export class GmmtValuationService {
  /**
   * Calculate multiversal valuation
   * Formula: value = classical_value + quantum_expected_value + holographic_projection + parallel_arbitrage_adjustment
   */
  async calculateValuation(request: ValuationRequest) {
    // Verify layer and unit exist
    const layer = await prisma.realityLayer.findUnique({
      where: { layerId: request.layerId },
    });

    if (!layer) {
      throw new Error(`Reality layer not found: ${request.layerId}`);
    }

    const unit = await prisma.multiversalMonetaryUnit.findUnique({
      where: { unitId: request.unitId },
    });

    if (!unit) {
      throw new Error(`Monetary unit not found: ${request.unitId}`);
    }

    // Calculate total value
    const classicalValue = new Decimal(request.classicalValue);
    const quantumValue = new Decimal(request.quantumExpectedValue || 0);
    const holographicValue = new Decimal(request.holographicProjection || 0);
    const parallelValue = new Decimal(request.parallelArbitrageAdjustment || 0);

    const totalValue = classicalValue
      .plus(quantumValue)
      .plus(holographicValue)
      .plus(parallelValue);

    const calculationFormula = {
      classical_value: request.classicalValue,
      quantum_expected_value: request.quantumExpectedValue || 0,
      holographic_projection: request.holographicProjection || 0,
      parallel_arbitrage_adjustment: request.parallelArbitrageAdjustment || 0,
      total: totalValue.toNumber(),
    };

    const valuationId = `VAL-${uuidv4()}`;

    const valuation = await prisma.valuationCalculation.create({
      data: {
        valuationId,
        layerId: request.layerId,
        unitId: request.unitId,
        assetId: request.assetId || null,
        classicalValue: classicalValue,
        quantumExpectedValue: request.quantumExpectedValue ? new Decimal(request.quantumExpectedValue) : null,
        holographicProjection: request.holographicProjection ? new Decimal(request.holographicProjection) : null,
        parallelArbitrageAdjustment: request.parallelArbitrageAdjustment ? new Decimal(request.parallelArbitrageAdjustment) : null,
        totalValue: totalValue,
        calculationFormula: calculationFormula,
        status: 'active',
      },
    });

    return valuation;
  }

  /**
   * Get valuation by ID
   */
  async getValuation(valuationId: string) {
    return await prisma.valuationCalculation.findUnique({
      where: { valuationId },
      include: {
        layer: true,
        unit: true,
      },
    });
  }

  /**
   * Get valuations for an asset
   */
  async getValuationsForAsset(assetId: string) {
    return await prisma.valuationCalculation.findMany({
      where: {
        assetId,
        status: 'active',
      },
      orderBy: { calculatedAt: 'desc' },
      include: {
        layer: true,
        unit: true,
      },
    });
  }

  /**
   * Get valuations by layer
   */
  async getValuationsByLayer(layerId: string) {
    return await prisma.valuationCalculation.findMany({
      where: {
        layerId,
        status: 'active',
      },
      orderBy: { calculatedAt: 'desc' },
      include: {
        unit: true,
      },
    });
  }
}

export const gmmtValuationService = new GmmtValuationService();

