// DBIS Unified Dimensional Arbitrage Engine - Dimensional Rebalancing
// Executes rebalancing to restore dimensional equilibrium

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


export interface RebalanceResult {
  rebalanceId: string;
  arbitrageId: string;
  adjustmentAmount: Decimal;
  equilibriumRestored: boolean;
}

export class UdaeRebalanceService {
  /**
   * Execute dimensional rebalance
   * Restores dimensional equilibrium by adjusting prices across dimensions
   */
  async executeDimensionalRebalance(arbitrageId: string): Promise<RebalanceResult> {
    const rebalanceId = `UDAE-REBAL-${uuidv4()}`;

    const arbitrage = await prisma.dimensionalArbitrage.findUnique({
      where: { arbitrageId },
    });

    if (!arbitrage) {
      throw new Error(`Arbitrage calculation not found: ${arbitrageId}`);
    }

    // Calculate adjustment amount (opposite of delta to restore equilibrium)
    const adjustmentAmount = arbitrage.arbitrageDelta.negated();

    // Create rebalance record
    const rebalance = await prisma.dimensionalRebalance.create({
      data: {
        rebalanceId,
        arbitrageId,
        adjustmentAmount,
        dimension: arbitrage.dimension,
        timeline: arbitrage.timeline,
        parallelBranch: arbitrage.parallelBranch,
        quantumState: arbitrage.quantumState,
        status: 'executed',
      },
    });

    // Update arbitrage to mark as rebalanced
    await prisma.dimensionalArbitrage.update({
      where: { arbitrageId },
      data: {
        requiresRebalance: false,
        status: 'rebalanced',
        updatedAt: new Date(),
      },
    });

    // Check if equilibrium is restored (delta should be near zero after adjustment)
    const newDelta = arbitrage.arbitrageDelta.plus(adjustmentAmount);
    const equilibriumRestored = newDelta.abs().lessThan(new Decimal(0.001));

    return {
      rebalanceId,
      arbitrageId,
      adjustmentAmount,
      equilibriumRestored,
    };
  }

  /**
   * Get rebalance by ID
   */
  async getRebalance(rebalanceId: string) {
    return await prisma.dimensionalRebalance.findUnique({
      where: { rebalanceId },
      include: {
        arbitrage: true,
      },
    });
  }

  /**
   * Get all rebalances for arbitrage
   */
  async getRebalancesForArbitrage(arbitrageId: string) {
    return await prisma.dimensionalRebalance.findMany({
      where: { arbitrageId },
      orderBy: { createdAt: 'desc' },
    });
  }

  /**
   * Get rebalances by dimension
   */
  async getRebalancesByDimension(dimension: string) {
    return await prisma.dimensionalRebalance.findMany({
      where: {
        dimension,
        status: 'executed',
      },
      orderBy: { createdAt: 'desc' },
    });
  }
}

export const udaeRebalanceService = new UdaeRebalanceService();

