// BEIE Incentive Service
// CBDC micro-rewards and SSU fee adjustments

import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { beieMetricsService } from './beie-metrics.service';


export interface CreateIncentiveRequest {
  entityId: string;
  entityType: string; // retail_cbdc_user, institution, sovereign
  incentiveType: string; // cbdc_micro_reward, ssu_fee_adjustment
  incentiveAmount?: string;
  incentiveReason: string; // stabilizing_behavior, low_risk_flow
  expiresAt?: Date;
}

export interface IncentiveResult {
  incentiveId: string;
  status: string;
}

export class BeieIncentiveService {
  /**
   * Create behavioral incentive
   */
  async createIncentive(request: CreateIncentiveRequest): Promise<IncentiveResult> {
    // Calculate incentive amount if not provided
    let incentiveAmount = new Decimal(0);
    if (request.incentiveAmount) {
      incentiveAmount = new Decimal(request.incentiveAmount);
    } else {
      incentiveAmount = await this.calculateIncentiveAmount(
        request.entityId,
        request.entityType,
        request.incentiveType
      );
    }

    const incentiveId = `BEIE-INC-${uuidv4()}`;

    const incentive = await prisma.behavioralIncentive.create({
      data: {
        incentiveId,
        entityId: request.entityId,
        entityType: request.entityType,
        incentiveType: request.incentiveType,
        incentiveAmount,
        incentiveReason: request.incentiveReason,
        status: 'pending',
        expiresAt: request.expiresAt || null,
      },
    });

    // Auto-apply if conditions are met
    await this.applyIncentive(incentiveId);

    return {
      incentiveId: incentive.incentiveId,
      status: incentive.status,
    };
  }

  /**
   * Calculate incentive amount based on behavior
   */
  private async calculateIncentiveAmount(
    entityId: string,
    entityType: string,
    incentiveType: string
  ): Promise<Decimal> {
    // Get behavioral metrics
    const metrics = await beieMetricsService.getMetrics(entityId);

    let amount = new Decimal(0);

    if (incentiveType === 'cbdc_micro_reward') {
      // Reward for stabilizing behaviors
      const ccv = metrics.find((m) => m.metricType === 'ccv');
      if (ccv) {
        const ccvValue = parseFloat(ccv.metricValue.toString());
        // Higher CCV (spending) = higher reward
        amount = new Decimal(ccvValue * 10); // Scale factor
      }
    } else if (incentiveType === 'ssu_fee_adjustment') {
      // Lower fees for low-risk flow patterns
      const ilb = metrics.find((m) => m.metricType === 'ilb');
      if (ilb) {
        const ilbValue = parseFloat(ilb.metricValue.toString());
        // Negative ILB (dumping) = fee increase, Positive (hoarding) = fee decrease
        amount = new Decimal(ilbValue * -5); // Negative for fee reduction
      }
    }

    return amount;
  }

  /**
   * Apply incentive
   */
  async applyIncentive(incentiveId: string): Promise<void> {
    const incentive = await prisma.behavioralIncentive.findUnique({
      where: { incentiveId },
    });

    if (!incentive || incentive.status !== 'pending') {
      return;
    }

    // In production, this would actually apply the incentive (transfer funds, adjust fees, etc.)
    await prisma.behavioralIncentive.update({
      where: { incentiveId },
      data: {
        status: 'applied',
        appliedAt: new Date(),
      },
    });
  }

  /**
   * Get incentive
   */
  async getIncentive(incentiveId: string) {
    return await prisma.behavioralIncentive.findUnique({
      where: { incentiveId },
    });
  }

  /**
   * List incentives for entity
   */
  async listIncentives(entityId: string, status?: string) {
    return await prisma.behavioralIncentive.findMany({
      where: {
        entityId,
        ...(status ? { status } : {}),
      },
      orderBy: { createdAt: 'desc' },
    });
  }
}

export const beieIncentiveService = new BeieIncentiveService();

