import type { Request, Response, NextFunction } from 'express';
import path from 'node:path';
import { createComplianceDecisionEngine } from '../../compliance/volume13-engine.js';

const PROXMOX_ROOT = process.env.PROXMOX_ROOT || path.resolve(process.cwd(), '../../../..');
const engine = createComplianceDecisionEngine(PROXMOX_ROOT);

const FINANCIAL_POST_PATHS = [
  '/omnl/iso20022/messages',
];

/**
 * Optional compliance decision gate for financial POST routes.
 * Enable with OMNL_COMPLIANCE_GATE=1 (uses mock engine until provider integration).
 */
export async function omnlComplianceGateMiddleware(
  req: Request,
  res: Response,
  next: NextFunction
): Promise<void> {
  if (process.env.OMNL_COMPLIANCE_GATE !== '1') {
    next();
    return;
  }
  if (req.method !== 'POST') {
    next();
    return;
  }
  const path = req.path.replace(/^\/api\/v1/, '');
  if (!FINANCIAL_POST_PATHS.some((p) => path.endsWith(p))) {
    next();
    return;
  }

  const body = req.body as {
    messageType?: string;
    payload?: string;
    entityId?: string;
    tenantId?: string;
    amount?: string;
    currency?: string;
    riskHints?: string[];
  };

  const result = await engine.evaluateTransaction({
    entityId: body.entityId ?? 'omnl-default',
    tenantId: body.tenantId ?? 'omnl',
    amount: body.amount ?? '0',
    currency: body.currency ?? 'USD',
    transactionType: body.messageType ?? 'iso20022.store',
    riskHints: body.riskHints,
  });

  res.setHeader('X-OMNL-Compliance-Decision', result.decision);
  res.setHeader('X-OMNL-Audit-Event-Id', result.audit_event_id);

  if (result.decision === 'block' || result.decision === 'reject') {
    res.status(403).json({
      error: 'compliance_blocked',
      decision: result.decision,
      reason_codes: result.reason_codes,
      audit_event_id: result.audit_event_id,
      manual_review_required: result.manual_review_required,
    });
    return;
  }

  if (result.decision === 'hold' || result.decision === 'review') {
    res.status(202).json({
      status: 'pending_review',
      decision: result.decision,
      reason_codes: result.reason_codes,
      audit_event_id: result.audit_event_id,
      manual_review_required: true,
    });
    return;
  }

  (req as Request & { complianceAuditId?: string }).complianceAuditId = result.audit_event_id;
  next();
}
