// Risk Tiering Service

import prisma from '@/shared/database/prisma';
import { RiskTier } from './types';
import { sasCalculatorService } from './sas-calculator.service';
import { logger } from '@/infrastructure/monitoring/logger';


export class RiskTieringService {
  /**
   * Assign risk tier to entity
   */
  async assignRiskTier(entityId: string): Promise<RiskTier> {
    // Get recent SAS scores
    const recentSAS = await prisma.suspicious_activity_scores.findMany({
      where: {
        entityId,
        calculatedAt: {
          gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000), // Last 30 days
        },
      },
      orderBy: { calculatedAt: 'desc' },
      take: 10,
    });

    if (recentSAS.length === 0) {
      // Default to TIER_1 if no history
      await this.storeRiskTier(entityId, RiskTier.TIER_1);
      return RiskTier.TIER_1;
    }

    // Calculate average score
    const avgScore = recentSAS.reduce((sum: number, sas: { score?: unknown }) => sum + Number(sas.score), 0) / recentSAS.length;

    // Determine tier
    let riskTier: RiskTier;
    if (avgScore >= 75) {
      riskTier = RiskTier.TIER_4;
    } else if (avgScore >= 50) {
      riskTier = RiskTier.TIER_3;
    } else if (avgScore >= 25) {
      riskTier = RiskTier.TIER_2;
    } else {
      riskTier = RiskTier.TIER_1;
    }

    await this.storeRiskTier(entityId, riskTier);

    logger.info(`Assigned risk tier ${riskTier} to entity ${entityId}`, {
      avgScore,
    });

    return riskTier;
  }

  /**
   * Store risk tier assignment
   */
  private async storeRiskTier(entityId: string, riskTier: RiskTier): Promise<void> {
    await prisma.risk_tiers.upsert({
      where: { entityId },
      create: {
        id: `RISK-TIER-${entityId}-${Date.now()}`,
        entityId,
        riskTier,
        assignedAt: new Date(),
        updatedAt: new Date(),
      },
      update: {
        riskTier,
        assignedAt: new Date(),
      },
    });
  }

  /**
   * Get risk tier for entity
   */
  async getRiskTier(entityId: string): Promise<RiskTier | null> {
    const tier = await prisma.risk_tiers.findUnique({
      where: { entityId },
    });

    if (!tier) {
      return null;
    }

    return tier.riskTier as RiskTier;
  }

  /**
   * Recalculate risk tier for entity
   */
  async recalculateRiskTier(entityId: string): Promise<RiskTier> {
    // Get all recent transactions for entity
    const transactions = await prisma.ledger_entries.findMany({
      where: {
        OR: [
          { bank_accounts_ledger_entries_debitAccountIdTobank_accounts: { sovereignBankId: entityId } },
          { bank_accounts_ledger_entries_creditAccountIdTobank_accounts: { sovereignBankId: entityId } },
        ],
        createdAt: {
          gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000),
        },
      },
      take: 100,
    });

    // Calculate SAS for recent transactions if not exists
    for (const tx of transactions.slice(0, 10)) {
      const existingSAS = await prisma.suspicious_activity_scores.findFirst({
        where: { transactionId: tx.id },
      });

      if (!existingSAS) {
        await sasCalculatorService.calculateSAS(tx.id, entityId);
      }
    }

    // Reassign tier
    return this.assignRiskTier(entityId);
  }
}

export const riskTieringService = new RiskTieringService();

