// Stablecoin Compliance Service
// Collateral requirements enforcement

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


export interface StablecoinCreationRequest {
  issuerBankId: string;
  stablecoinCode: string;
  name: string;
  initialCollateral: Array<{
    assetType: string;
    amount: string;
    valuation: string;
  }>;
}

export interface ComplianceCheckResult {
  compliant: boolean;
  collateralizationRatio: string;
  requiredCollateral: string;
  actualCollateral: string;
  shortfall?: string;
}

export class StablecoinComplianceService {
  /**
   * Create sovereign stablecoin
   */
  async createStablecoin(
    request: StablecoinCreationRequest
  ): Promise<{ stablecoinId: string }> {
    const stablecoinId = `STABLE-${uuidv4()}`;

    // Create stablecoin
    const stablecoin = await prisma.sovereign_stablecoins.create({
      data: {
        id: uuidv4(),
        stablecoinId,
        issuerBankId: request.issuerBankId,
        stablecoinCode: request.stablecoinCode,
        name: request.name,
        totalSupply: new Decimal(0),
        collateralizationRatio: new Decimal(1.0), // Must be >= 1.0
        status: 'active',
        createdAt: new Date(),
        updatedAt: new Date(),
      },
    });

    // Add initial collateral
    for (const collateral of request.initialCollateral) {
      await prisma.stablecoin_collaterals.create({
        data: {
          id: uuidv4(),
          collateralId: `COLL-${uuidv4()}`,
          stablecoinId,
          assetType: collateral.assetType,
          amount: new Decimal(collateral.amount),
          valuation: new Decimal(collateral.valuation),
          status: 'active',
          allocatedAt: new Date(),
          createdAt: new Date(),
          updatedAt: new Date(),
        },
      });
    }

    return {
      stablecoinId: stablecoin.stablecoinId,
    };
  }

  /**
   * Check collateral compliance
   */
  async checkCompliance(stablecoinId: string): Promise<ComplianceCheckResult> {
    const stablecoin = await prisma.sovereign_stablecoins.findUnique({
      where: { stablecoinId },
      include: {
        stablecoin_collaterals: {
          where: { status: 'active' },
        },
      },
    });

    if (!stablecoin) {
      throw new Error(`Stablecoin not found: ${stablecoinId}`);
    }

    // Calculate total collateral value
    const actualCollateral = stablecoin.stablecoin_collaterals.reduce(
      (sum, coll) => sum.plus(coll.valuation),
      new Decimal(0)
    );

    // Required collateral = total supply (1:1 backing)
    const requiredCollateral = stablecoin.totalSupply;

    // Calculate collateralization ratio
    const collateralizationRatio = requiredCollateral.isZero()
      ? new Decimal(1.0)
      : actualCollateral.div(requiredCollateral);

    const compliant = collateralizationRatio.gte(new Decimal(1.0));
    const shortfall = compliant
      ? undefined
      : requiredCollateral.minus(actualCollateral).toString();

    // Update collateralization ratio
    await prisma.sovereign_stablecoins.update({
      where: { stablecoinId },
      data: { collateralizationRatio },
    });

    return {
      compliant,
      collateralizationRatio: collateralizationRatio.toString(),
      requiredCollateral: requiredCollateral.toString(),
      actualCollateral: actualCollateral.toString(),
      shortfall,
    };
  }

  /**
   * Add collateral
   */
  async addCollateral(
    stablecoinId: string,
    assetType: string,
    amount: string,
    valuation: string
  ): Promise<{ collateralId: string }> {
    const collateralId = `COLL-${uuidv4()}`;

    await prisma.stablecoin_collaterals.create({
      data: {
        id: uuidv4(),
        collateralId,
        stablecoinId,
        assetType,
        amount: new Decimal(amount),
        valuation: new Decimal(valuation),
        status: 'active',
        allocatedAt: new Date(),
        createdAt: new Date(),
        updatedAt: new Date(),
      },
    });

    // Recheck compliance
    await this.checkCompliance(stablecoinId);

    return { collateralId };
  }

  /**
   * Release collateral
   */
  async releaseCollateral(collateralId: string): Promise<void> {
    const collateral = await prisma.stablecoin_collaterals.findUnique({
      where: { collateralId },
    });

    if (!collateral) {
      throw new Error(`Collateral not found: ${collateralId}`);
    }

    // Check compliance before release
    const compliance = await this.checkCompliance(collateral.stablecoinId);
    if (!compliance.compliant) {
      throw new Error('Cannot release collateral: stablecoin would become non-compliant');
    }

    await prisma.stablecoin_collaterals.update({
      where: { collateralId },
      data: {
        status: 'released',
        releasedAt: new Date(),
      },
    });
  }
}

export const stablecoinComplianceService = new StablecoinComplianceService();

