// STCE Engine Service
// TCU generation and stabilization

import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { TemporalCurrencyUnit } from '@/shared/types';
import { StceValuationService } from './stce-valuation.service';

const valuationService = new StceValuationService();

export interface CreateTcuRequest {
  tcuCode: string;
  tcuName: string;
  description: string;
  baseCurrency?: string;
  presentValue: string;
}

export interface TcuGenerationResult {
  tcuId: string;
  tcuCode: string;
  presentValue: string;
  calculatedValue: string;
  status: string;
}

export class StceEngineService {
  /**
   * Create a Temporal Currency Unit (TCU)
   */
  async createTcu(request: CreateTcuRequest): Promise<TemporalCurrencyUnit> {
    // Check if TCU code already exists
    const existing = await prisma.temporal_currency_units.findUnique({
      where: { tcuCode: request.tcuCode },
    });

    if (existing) {
      throw new Error(`TCU with code ${request.tcuCode} already exists`);
    }

    const tcuId = `TCU-${uuidv4()}`;

    const tcu = await prisma.temporal_currency_units.create({
      data: {
        tcuId,
        tcuCode: request.tcuCode,
        tcuName: request.tcuName,
        description: request.description,
        baseCurrency: request.baseCurrency || null,
        presentValue: new Decimal(request.presentValue),
        primeTemporalBond: true,
        status: 'active',
      },
    });

    return {
      tcuId: tcu.tcuId,
      tcuCode: tcu.tcuCode,
      tcuName: tcu.tcuName,
      description: tcu.description,
      baseCurrency: tcu.baseCurrency || undefined,
      presentValue: tcu.presentValue.toString(),
      primeTemporalBond: tcu.primeTemporalBond,
      status: tcu.status,
    };
  }

  /**
   * Generate TCU value with stabilization
   */
  async generateTcuValue(tcuId: string): Promise<TcuGenerationResult> {
    const tcu = await prisma.temporal_currency_units.findUnique({
      where: { tcuId },
    });

    if (!tcu) {
      throw new Error(`TCU not found: ${tcuId}`);
    }

    // Calculate stabilized value using valuation service
    const stabilityState = await valuationService.calculateTcuValue(tcuId);

    return {
      tcuId: tcu.tcuId,
      tcuCode: tcu.tcuCode,
      presentValue: tcu.presentValue.toString(),
      calculatedValue: stabilityState.calculatedValue,
      status: tcu.status,
    };
  }

  /**
   * Get all TCUs
   */
  async getAllTcus(includeArchived = false): Promise<TemporalCurrencyUnit[]> {
    const where: { status?: string } = {};
    if (!includeArchived) {
      where.status = 'active';
    }

    const tcus = await prisma.temporal_currency_units.findMany({
      where,
      orderBy: { tcuCode: 'asc' },
    });

    return tcus.map((tcu) => ({
      tcuId: tcu.tcuId,
      tcuCode: tcu.tcuCode,
      tcuName: tcu.tcuName,
      description: tcu.description,
      baseCurrency: tcu.baseCurrency || undefined,
      presentValue: tcu.presentValue.toString(),
      primeTemporalBond: tcu.primeTemporalBond,
      status: tcu.status,
    }));
  }

  /**
   * Get TCU by code
   */
  async getTcuByCode(tcuCode: string): Promise<TemporalCurrencyUnit | null> {
    const tcu = await prisma.temporal_currency_units.findUnique({
      where: { tcuCode },
    });

    if (!tcu) {
      return null;
    }

    return {
      tcuId: tcu.tcuId,
      tcuCode: tcu.tcuCode,
      tcuName: tcu.tcuName,
      description: tcu.description,
      baseCurrency: tcu.baseCurrency || undefined,
      presentValue: tcu.presentValue.toString(),
      primeTemporalBond: tcu.primeTemporalBond,
      status: tcu.status,
    };
  }

  /**
   * Update TCU present value
   */
  async updatePresentValue(tcuId: string, presentValue: string): Promise<void> {
    await prisma.temporal_currency_units.update({
      where: { tcuId },
      data: {
        presentValue: new Decimal(presentValue),
      },
    });
  }

  /**
   * Suspend TCU
   */
  async suspendTcu(tcuId: string): Promise<void> {
    await prisma.temporal_currency_units.update({
      where: { tcuId },
      data: { status: 'suspended' },
    });
  }
}

