export type ComplianceDecision =
  | 'allow'
  | 'block'
  | 'review'
  | 'hold'
  | 'reject';

export type ComplianceEvaluationInput = {
  entityId: string;
  tenantId: string;
  counterpartyId?: string;
  amount: string;
  currency: string;
  transactionType: string;
  riskHints?: string[];
};

export type ComplianceEvaluationResult = {
  decision: ComplianceDecision;
  risk_score: number;
  reason_codes: string[];
  evidence_refs: string[];
  expires_at?: string;
  manual_review_required: boolean;
  audit_event_id: string;
};

export interface ComplianceDecisionEngine {
  evaluateTransaction(input: ComplianceEvaluationInput): Promise<ComplianceEvaluationResult>;
  evaluateEntity(entityId: string, tenantId: string): Promise<ComplianceEvaluationResult>;
  evaluateCounterparty(
    counterpartyId: string,
    tenantId: string
  ): Promise<ComplianceEvaluationResult>;
}

let auditCounter = 0;

function nextAuditId(): string {
  auditCounter += 1;
  return `audit-mock-${auditCounter}`;
}

export class MockComplianceDecisionEngine implements ComplianceDecisionEngine {
  private readonly blockAmountThreshold: number;

  constructor(options?: { blockAmountThreshold?: number }) {
    this.blockAmountThreshold = options?.blockAmountThreshold ?? 1_000_000;
  }

  async evaluateTransaction(
    input: ComplianceEvaluationInput
  ): Promise<ComplianceEvaluationResult> {
    const amount = Number(input.amount);
    const hints = input.riskHints ?? [];

    if (hints.includes('sanctions_hit')) {
      return {
        decision: 'block',
        risk_score: 100,
        reason_codes: ['SANCTIONS_HIT'],
        evidence_refs: ['mock-evidence-sanctions'],
        manual_review_required: true,
        audit_event_id: nextAuditId(),
      };
    }

    if (hints.includes('pep_match')) {
      return {
        decision: 'review',
        risk_score: 75,
        reason_codes: ['PEP_MATCH'],
        evidence_refs: ['mock-evidence-pep'],
        manual_review_required: true,
        audit_event_id: nextAuditId(),
      };
    }

    if (amount >= this.blockAmountThreshold) {
      return {
        decision: 'hold',
        risk_score: 60,
        reason_codes: ['AMOUNT_THRESHOLD'],
        evidence_refs: ['mock-evidence-threshold'],
        manual_review_required: true,
        audit_event_id: nextAuditId(),
      };
    }

    return {
      decision: 'allow',
      risk_score: 10,
      reason_codes: ['CLEAR'],
      evidence_refs: [],
      manual_review_required: false,
      audit_event_id: nextAuditId(),
    };
  }

  async evaluateEntity(
    entityId: string,
    tenantId: string
  ): Promise<ComplianceEvaluationResult> {
    if (entityId.startsWith('blocked-')) {
      return {
        decision: 'reject',
        risk_score: 90,
        reason_codes: ['ENTITY_BLOCKED'],
        evidence_refs: [`mock-entity-${tenantId}-${entityId}`],
        manual_review_required: true,
        audit_event_id: nextAuditId(),
      };
    }
    return {
      decision: 'allow',
      risk_score: 5,
      reason_codes: ['ENTITY_CLEAR'],
      evidence_refs: [],
      manual_review_required: false,
      audit_event_id: nextAuditId(),
    };
  }

  async evaluateCounterparty(
    counterpartyId: string,
    tenantId: string
  ): Promise<ComplianceEvaluationResult> {
    if (counterpartyId.includes('high-risk')) {
      return {
        decision: 'review',
        risk_score: 70,
        reason_codes: ['COUNTERPARTY_HIGH_RISK'],
        evidence_refs: [`mock-cp-${tenantId}`],
        manual_review_required: true,
        audit_event_id: nextAuditId(),
      };
    }
    return this.evaluateEntity(counterpartyId, tenantId);
  }
}
