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


export interface CreateIncentiveRequest {
  economyId: string;
  incentiveType: 'reward' | 'penalty' | 'predictive_nudge';
  targetBehavior: string;
  incentiveAmount: number;
  conditions: Record<string, unknown>;
}

export class FaceIncentiveService {
  /**
   * Create incentive
   */
  async createIncentive(request: CreateIncentiveRequest) {
    const incentiveId = `FACE-INC-${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 incentive = await prisma.face_incentives.create({
      data: {
        id: uuidv4(),
        incentiveId,
        economyId: economy.id, // Use the id field, not economyId
        incentiveType: request.incentiveType,
        targetBehavior: request.targetBehavior,
        incentiveAmount: new Decimal(request.incentiveAmount),
        conditions: request.conditions as Prisma.InputJsonValue,
        status: 'active',
        createdAt: new Date(),
        updatedAt: new Date(),
      },
    });

    return incentive;
  }

  /**
   * Check and apply incentive
   */
  async checkAndApplyIncentive(
    incentiveId: string,
    behaviorData: Record<string, unknown>
  ) {
    const incentive = await prisma.face_incentives.findUnique({
      where: { incentiveId },
      include: {
        face_economies: true,
      },
    });

    if (!incentive) {
      throw new Error(`Incentive not found: ${incentiveId}`);
    }

    if (incentive.status !== 'active') {
      return { applied: false, reason: 'Incentive not active' };
    }

    // Check conditions
    const conditionsMet = this.checkConditions(incentive.conditions as Record<string, unknown>, behaviorData);

    if (!conditionsMet) {
      return { applied: false, reason: 'Conditions not met' };
    }

    // Apply incentive
    // In production, this would:
    // - For rewards: credit CBDC wallet, apply fee reduction, etc.
    // - For penalties: charge fee, restrict access, etc.
    // - For predictive nudges: send notification, adjust rates, etc.

    await prisma.face_incentives.update({
      where: { incentiveId },
      data: {
        status: 'applied',
        appliedAt: new Date(),
      },
    });

    return {
      applied: true,
      incentiveType: incentive.incentiveType,
      amount: incentive.incentiveAmount.toString(),
      targetBehavior: incentive.targetBehavior,
    };
  }

  /**
   * Check if conditions are met
   */
  private checkConditions(
    conditions: Record<string, unknown>,
    behaviorData: Record<string, unknown>
  ): boolean {
    // Simple condition checking
    // In production, would use more sophisticated rule engine

    for (const [key, value] of Object.entries(conditions)) {
      if (key === 'min_velocity' && (behaviorData.velocity as number) < (value as number)) {
        return false;
      }
      if (key === 'max_velocity' && (behaviorData.velocity as number) > (value as number)) {
        return false;
      }
      if (key === 'min_circulation' && (behaviorData.circulation as number) < (value as number)) {
        return false;
      }
    }

    return true;
  }

  /**
   * Get incentives for economy
   */
  async getIncentivesForEconomy(economyId: string) {
    // First find the economy by economyId to get its id
    const economy = await prisma.face_economies.findUnique({
      where: { economyId },
    });

    if (!economy) {
      return [];
    }

    return prisma.face_incentives.findMany({
      where: { economyId: economy.id },
      orderBy: {
        createdAt: 'desc',
      },
    });
  }

  /**
   * Get incentive by ID
   */
  async getIncentive(incentiveId: string) {
    const incentive = await prisma.face_incentives.findUnique({
      where: { incentiveId },
      include: {
        face_economies: true,
      },
    });

    if (!incentive) {
      throw new Error(`Incentive not found: ${incentiveId}`);
    }

    return incentive;
  }
}

export const faceIncentiveService = new FaceIncentiveService();

