// Sanctions Database Integration Service
// Integrates with OFAC, EU, UN sanctions databases

import { logger } from '@/infrastructure/monitoring/logger';
import { retryWithBackoff } from '@/shared/utils/retry';

export interface SanctionsCheck {
  entityName: string;
  entityType: 'individual' | 'organization' | 'country';
  jurisdiction?: string;
  dateOfBirth?: string;
  identifiers?: Record<string, string>;
}

export interface SanctionsResult {
  match: boolean;
  matches: Array<{
    list: 'OFAC' | 'EU' | 'UN' | 'OTHER';
    entityName: string;
    matchScore: number;
    reason: string;
    url?: string;
  }>;
  riskLevel: 'low' | 'medium' | 'high';
  recommendation: string;
}

export class SanctionsService {
  /**
   * Check entity against sanctions databases
   */
  async checkSanctions(check: SanctionsCheck): Promise<SanctionsResult> {
    const results = await Promise.all([
      this.checkOFAC(check),
      this.checkEU(check),
      this.checkUN(check),
    ]);

    const allMatches = results.flatMap((r) => r.matches);
    const hasMatch = allMatches.length > 0;

    const riskLevel = this.assessRiskLevel(allMatches);
    const recommendation = this.generateRecommendation(hasMatch, riskLevel);

    return {
      match: hasMatch,
      matches: allMatches,
      riskLevel,
      recommendation,
    };
  }

  /**
   * Check OFAC (US Office of Foreign Assets Control) sanctions
   */
  private async checkOFAC(check: SanctionsCheck): Promise<SanctionsResult> {
    const ofacApiUrl = process.env.OFAC_API_URL || 'https://api.ofac.treasury.gov';
    const ofacApiKey = process.env.OFAC_API_KEY;

    if (!ofacApiKey) {
      logger.warn('OFAC API key not configured, skipping OFAC check');
      return {
        match: false,
        matches: [],
        riskLevel: 'low',
        recommendation: 'OFAC check skipped - API key not configured',
      };
    }

    try {
import { retryWithBackoff } from '@/shared/utils/retry';

      const response = await retryWithBackoff(
        async () => {
          return await fetch(`${ofacApiUrl}/v1/sanctions/search`, {
            method: 'POST',
            headers: {
              'Authorization': `Bearer ${ofacApiKey}`,
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              name: check.entityName,
              type: check.entityType,
              jurisdiction: check.jurisdiction,
            }),
          });
        },
        {
          maxRetries: 3,
          initialDelayMs: 1000,
        }
      );

      if (!response.ok) {
        throw new Error(`OFAC API error: ${response.status} ${response.statusText}`);
      }

      const data = await response.json();
      const matches = (data.matches || []).map((match: { name: string; score?: number; reason?: string; url?: string }) => ({
        list: 'OFAC' as const,
        entityName: match.name,
        matchScore: match.score || 0,
        reason: match.reason || 'Potential match in OFAC sanctions list',
        url: match.url,
      }));

      return {
        match: matches.length > 0,
        matches,
        riskLevel: matches.length > 0 ? 'high' : 'low',
        recommendation: matches.length > 0
          ? 'Entity matches OFAC sanctions list - DO NOT PROCEED'
          : 'No OFAC matches found',
      };
    } catch (error) {
      logger.error('OFAC check failed', {
        error: error instanceof Error ? error.message : 'Unknown error',
      });

      return {
        match: false,
        matches: [],
        riskLevel: 'medium',
        recommendation: 'OFAC check failed - manual review recommended',
      };
    }
  }

  /**
   * Check EU sanctions
   */
  private async checkEU(check: SanctionsCheck): Promise<SanctionsResult> {
    const euSanctionsUrl = process.env.EU_SANCTIONS_URL || 'https://ec.europa.eu/sanctions';

    try {
      // EU sanctions are typically accessed via web scraping or API
      // For now, return placeholder
      // In production, integrate with EU sanctions API

      return {
        match: false,
        matches: [],
        riskLevel: 'low',
        recommendation: 'EU sanctions check - integration pending',
      };
    } catch (error) {
      logger.error('EU sanctions check failed', {
        error: error instanceof Error ? error.message : 'Unknown error',
      });

      return {
        match: false,
        matches: [],
        riskLevel: 'medium',
        recommendation: 'EU sanctions check failed - manual review recommended',
      };
    }
  }

  /**
   * Check UN sanctions
   */
  private async checkUN(check: SanctionsCheck): Promise<SanctionsResult> {
    const unSanctionsUrl = process.env.UN_SANCTIONS_URL || 'https://www.un.org/sanctions';

    try {
      // UN sanctions API integration
      const unSanctionsApiUrl = process.env.UN_SANCTIONS_API_URL || 'https://www.un.org/sanctions';
      const unSanctionsApiKey = process.env.UN_SANCTIONS_API_KEY;

      if (!unSanctionsApiKey) {
        logger.warn('UN sanctions API key not configured, skipping UN check');
        return {
          match: false,
          matches: [],
          riskLevel: 'low',
          recommendation: 'UN sanctions check skipped - API key not configured',
        };
      }

import { retryWithBackoff } from '@/shared/utils/retry';

      const response = await retryWithBackoff(
        async () => {
          return await fetch(`${unSanctionsApiUrl}/api/v1/sanctions/search`, {
            method: 'POST',
            headers: {
              'Authorization': `Bearer ${unSanctionsApiKey}`,
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              name: check.entityName,
              type: check.entityType,
              jurisdiction: check.jurisdiction,
            }),
          });
        },
        {
          maxRetries: 3,
          initialDelayMs: 1000,
        }
      );

      if (!response.ok) {
        throw new Error(`UN sanctions API error: ${response.status} ${response.statusText}`);
      }

      const data = await response.json();
      const matches = (data.matches || []).map((match: { name: string; score?: number; reason?: string; url?: string }) => ({
        list: 'UN' as const,
        entityName: match.name,
        matchScore: match.score || 0,
        reason: match.reason || 'Potential match in UN sanctions list',
        url: match.url,
      }));

      return {
        match: matches.length > 0,
        matches,
        riskLevel: matches.length > 0 ? 'high' : 'low',
        recommendation: matches.length > 0
          ? 'Entity matches UN sanctions list - DO NOT PROCEED'
          : 'No UN matches found',
      };
    } catch (error) {
      logger.error('UN sanctions check failed', {
        error: error instanceof Error ? error.message : 'Unknown error',
      });

      return {
        match: false,
        matches: [],
        riskLevel: 'medium',
        recommendation: 'UN sanctions check failed - manual review recommended',
      };
    }
  }

  /**
   * Assess risk level from matches
   */
  private assessRiskLevel(matches: SanctionsResult['matches']): 'low' | 'medium' | 'high' {
    if (matches.length === 0) {
      return 'low';
    }

    const highScoreMatches = matches.filter((m) => m.matchScore > 0.8);
    if (highScoreMatches.length > 0) {
      return 'high';
    }

    return 'medium';
  }

  /**
   * Generate recommendation
   */
  private generateRecommendation(hasMatch: boolean, riskLevel: 'low' | 'medium' | 'high'): string {
    if (hasMatch && riskLevel === 'high') {
      return 'DO NOT PROCEED - Entity matches sanctions list';
    }

    if (hasMatch && riskLevel === 'medium') {
      return 'Manual review required - Potential sanctions match';
    }

    if (riskLevel === 'medium') {
      return 'Enhanced due diligence recommended';
    }

    return 'No sanctions concerns identified';
  }
}

export const sanctionsService = new SanctionsService();
