// CBDC Velocity Control Service
import { Prisma } from '@prisma/client';
// Wallet limits, spending categories, throttles

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


export interface VelocityControlRequest {
  sovereignBankId: string;
  walletId?: string;
  walletLevelLimit?: number;
  spendingCategory?: string;
  timeBasedThrottle?: Record<string, unknown>;
  committeeId?: string;
  effectiveDate: Date;
  expiryDate?: Date;
}

export class CbdcVelocityControlService {
  /**
   * Create velocity control
   */
  async createVelocityControl(request: VelocityControlRequest) {
    return await prisma.cbdc_velocity_controls.create({
      data: {
        id: uuidv4(),
        controlId: `VELOCITY-${uuidv4()}`,
        committeeId: request.committeeId,
        sovereignBankId: request.sovereignBankId,
        walletId: request.walletId,
        walletLevelLimit: request.walletLevelLimit ? new Decimal(request.walletLevelLimit) : null,
        spendingCategory: request.spendingCategory,
        timeBasedThrottle: request.timeBasedThrottle ? (request.timeBasedThrottle as Prisma.InputJsonValue) : Prisma.JsonNull,
        status: 'active',
        effectiveDate: request.effectiveDate,
        expiryDate: request.expiryDate || null,
        createdAt: new Date(),
        updatedAt: new Date(),
      },
    });
  }

  /**
   * Get active velocity controls
   */
  async getActiveControls(sovereignBankId?: string, walletId?: string) {
    const where: any = {
      status: 'active',
      effectiveDate: {
        lte: new Date(),
      },
      OR: [
        { expiryDate: null },
        { expiryDate: { gte: new Date() } },
      ],
    };

    if (sovereignBankId) {
      where.sovereignBankId = sovereignBankId;
    }
    if (walletId) {
      where.walletId = walletId;
    }

    return await prisma.cbdc_velocity_controls.findMany({
      where,
    });
  }

  /**
   * Check velocity limit
   */
  async checkVelocityLimit(
    walletId: string,
    amount: number,
    category?: string
  ): Promise<boolean> {
    const controls = await this.getActiveControls(undefined, walletId);

    for (const control of controls) {
      // Check category match
      if (control.spendingCategory && category && control.spendingCategory !== category) {
        continue;
      }

      // Check wallet level limit
      if (control.walletLevelLimit && amount > parseFloat(control.walletLevelLimit.toString())) {
        return false;
      }
    }

    return true;
  }
}

export const cbdcVelocityControlService = new CbdcVelocityControlService();

