// CSSE Reconciliation Service
// Reconciliation: delay cost, FX drift, commodity shock delta

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


export interface CreateReconciliationRequest {
  delayCost: number;
  fxDrift: number;
  commodityShockDelta: number;
}

export class CsseReconciliationService {
  /**
   * Create reconciliation
   */
  async createReconciliation(
    settlementId: string,
    request: CreateReconciliationRequest
  ) {
    const settlement = await prisma.chronoSettlement.findUnique({
      where: { settlementId },
    });

    if (!settlement) {
      throw new Error(`Settlement not found: ${settlementId}`);
    }

    if (settlement.status !== 'committed') {
      throw new Error('Settlement must be committed before reconciliation');
    }

    // Calculate adjustment amount
    const delayCost = new Decimal(request.delayCost);
    const fxDrift = new Decimal(request.fxDrift);
    const commodityShockDelta = new Decimal(request.commodityShockDelta);

    const adjustmentAmount = delayCost.plus(fxDrift).plus(commodityShockDelta);

    const reconciliationId = `CSSE-REC-${uuidv4()}`;

    const reconciliation = await prisma.temporalReconciliation.create({
      data: {
        reconciliationId,
        settlementId,
        delayCost,
        fxDrift,
        commodityShockDelta,
        adjustmentAmount,
        reconciliationData: {
          originalAmount: settlement.amount.toString(),
          adjustments: {
            delayCost: request.delayCost,
            fxDrift: request.fxDrift,
            commodityShockDelta: request.commodityShockDelta,
          },
        },
        status: 'pending',
      },
    });

    return reconciliation;
  }

  /**
   * Apply reconciliation
   */
  async applyReconciliation(reconciliationId: string) {
    const reconciliation = await prisma.temporalReconciliation.findUnique({
      where: { reconciliationId },
      include: {
        settlement: true,
      },
    });

    if (!reconciliation) {
      throw new Error(`Reconciliation not found: ${reconciliationId}`);
    }

    if (reconciliation.status !== 'pending') {
      throw new Error(`Reconciliation already ${reconciliation.status}`);
    }

    // In production, this would:
    // 1. Adjust settlement amount based on adjustmentAmount
    // 2. Update ledger entries
    // 3. Record reconciliation in audit log

    // Update reconciliation status
    await prisma.temporalReconciliation.update({
      where: { reconciliationId },
      data: {
        status: 'applied',
        appliedAt: new Date(),
      },
    });

    // Update settlement
    await prisma.chronoSettlement.update({
      where: { settlementId: reconciliation.settlementId },
      data: {
        reconciledAt: new Date(),
      },
    });

    return reconciliation;
  }

  /**
   * Calculate reconciliation automatically
   */
  async calculateReconciliation(settlementId: string) {
    const settlement = await prisma.chronoSettlement.findUnique({
      where: { settlementId },
    });

    if (!settlement) {
      throw new Error(`Settlement not found: ${settlementId}`);
    }

    // Calculate delay cost based on time offset
    const timeOffsetSeconds = parseFloat(settlement.timeOffset.toString());
    const delayCost = timeOffsetSeconds * 0.0001; // Simplified: 0.0001 per second

    // Calculate FX drift (would integrate with FX engine in production)
    const fxDrift = 0; // Placeholder

    // Calculate commodity shock delta (would integrate with commodity service in production)
    const commodityShockDelta = 0; // Placeholder

    return this.createReconciliation(settlementId, {
      delayCost,
      fxDrift,
      commodityShockDelta,
    });
  }

  /**
   * Get reconciliation by ID
   */
  async getReconciliation(reconciliationId: string) {
    const reconciliation = await prisma.temporalReconciliation.findUnique({
      where: { reconciliationId },
      include: {
        settlement: true,
      },
    });

    if (!reconciliation) {
      throw new Error(`Reconciliation not found: ${reconciliationId}`);
    }

    return reconciliation;
  }

  /**
   * Get reconciliations for settlement
   */
  async getReconciliationsForSettlement(settlementId: string) {
    return prisma.temporalReconciliation.findMany({
      where: { settlementId },
      orderBy: {
        createdAt: 'desc',
      },
    });
  }
}

export const csseReconciliationService = new CsseReconciliationService();

