// FACE Supply Contract Service
import { Prisma } from '@prisma/client';
// Automatic supply contracts: if velocity < target: mint_cbdc() elif velocity > danger_threshold: burn_cbdc()

import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { cbdcService } from '@/core/cbdc/cbdc.service';


export interface CreateSupplyContractRequest {
  economyId: string;
  velocityTarget: number;
  velocityDangerThreshold: number;
  mintCondition?: Record<string, unknown>;
  burnCondition?: Record<string, unknown>;
}

export class FaceSupplyService {
  /**
   * Create supply contract
   */
  async createSupplyContract(request: CreateSupplyContractRequest) {
    const contractId = `FACE-SUPPLY-${uuidv4()}`;

    // Get the face_economies record by economyId to get its id
    const economy = await prisma.face_economies.findUnique({
      where: { economyId: request.economyId },
    });

    if (!economy) {
      throw new Error(`Economy not found: ${request.economyId}`);
    }

    const contract = await prisma.face_supply_contracts.create({
      data: {
        id: uuidv4(),
        contractId,
        economyId: economy.id, // Use the id field, not economyId
        contractType: 'automatic_supply_adjustment',
        velocityTarget: new Decimal(request.velocityTarget),
        velocityDangerThreshold: new Decimal(request.velocityDangerThreshold),
        mintCondition: (request.mintCondition || {
          condition: 'if velocity < target: mint_cbdc()',
        }) as Prisma.InputJsonValue,
        burnCondition: (request.burnCondition || {
          condition: 'elif velocity > danger_threshold: burn_cbdc()',
        }) as Prisma.InputJsonValue,
        status: 'active',
        createdAt: new Date(),
        updatedAt: new Date(),
      },
    });

    return contract;
  }

  /**
   * Check and execute supply contract
   */
  async checkSupplyContract(contractId: string, currentVelocity: number) {
    const contract = await prisma.face_supply_contracts.findUnique({
      where: { contractId },
      include: {
        face_economies: true,
      },
    });

    if (!contract) {
      throw new Error(`Supply contract not found: ${contractId}`);
    }

    if (contract.status !== 'active') {
      return { triggered: false, reason: 'Contract not active' };
    }

    const velocity = new Decimal(currentVelocity);
    const target = contract.velocityTarget;
    const dangerThreshold = contract.velocityDangerThreshold;

    let action: 'mint' | 'burn' | null = null;
    let amount: Decimal | null = null;

    // if velocity < target: mint_cbdc()
    if (velocity.lt(target)) {
      action = 'mint';
      // Calculate mint amount based on velocity gap
      const gap = target.minus(velocity);
      amount = gap.times(1000000); // Simplified: 1M per 0.1 velocity gap
    }
    // elif velocity > danger_threshold: burn_cbdc()
    else if (velocity.gt(dangerThreshold)) {
      action = 'burn';
      // Calculate burn amount based on excess velocity
      const excess = velocity.minus(dangerThreshold);
      amount = excess.times(1000000); // Simplified: 1M per 0.1 velocity excess
    }

    if (action && amount) {
      // Execute action
      const economy = contract.face_economies;
      const operatorIdentity = `FACE-AUTO-${contractId}`;

      if (action === 'mint') {
        await cbdcService.mintCbdc(
          economy.sovereignBankId,
          null, // No specific wallet
          amount.toString(),
          operatorIdentity,
          `FACE automatic supply adjustment: velocity ${currentVelocity} < target ${target}`
        );
      } else if (action === 'burn') {
        await cbdcService.burnCbdc(
          economy.sovereignBankId,
          null, // No specific wallet
          amount.toString(),
          operatorIdentity,
          `FACE automatic supply adjustment: velocity ${currentVelocity} > danger threshold ${dangerThreshold}`
        );
      }

      // Update contract
      await prisma.face_supply_contracts.update({
        where: { contractId },
        data: {
          lastTriggeredAt: new Date(),
        },
      });

      return {
        triggered: true,
        action,
        amount: amount.toString(),
        velocity: currentVelocity,
      };
    }

    return {
      triggered: false,
      reason: 'Velocity within acceptable range',
      velocity: currentVelocity,
    };
  }

  /**
   * Get supply contracts for economy
   */
  async getContractsForEconomy(economyId: string) {
    return prisma.face_supply_contracts.findMany({
      where: { economyId },
      orderBy: {
        createdAt: 'desc',
      },
    });
  }

  /**
   * Get contract by ID
   */
  async getContract(contractId: string) {
    const contract = await prisma.face_supply_contracts.findUnique({
      where: { contractId },
      include: {
        face_economies: true,
      },
    });

    if (!contract) {
      throw new Error(`Supply contract not found: ${contractId}`);
    }

    return contract;
  }
}

export const faceSupplyService = new FaceSupplyService();

