/** Extended canonical financial event aligned to ISO 20022 concepts (not full XML). */

export type PartyAccount = {
  id: string;
  name?: string;
  iban?: string;
  bic?: string;
  address?: string;
};

export type FinancialParty = {
  id: string;
  name?: string;
  lei?: string;
  jurisdiction?: string;
  account?: PartyAccount;
};

export type ComplianceDecisionRef = 'allow' | 'block' | 'review' | 'hold' | 'reject' | 'pending';

export type CanonicalFinancialEvent = {
  schema_version: string;
  message_id: string;
  end_to_end_id: string;
  transaction_id?: string;
  uetr?: string;
  debtor: FinancialParty;
  creditor: FinancialParty;
  debtor_agent?: FinancialParty;
  creditor_agent?: FinancialParty;
  debtor_account?: PartyAccount;
  creditor_account?: PartyAccount;
  amount: string;
  currency: string;
  settlement_date?: string;
  purpose_code?: string;
  remittance_information?: string;
  status?: string;
  reason_code?: string;
  source_system: string;
  target_system: string;
  entity_id: string;
  tenant_id: string;
  risk_score?: number;
  compliance_decision?: ComplianceDecisionRef;
  audit_event_id?: string;
  raw_reference?: string;
};

export type CanonicalValidationResult = {
  valid: boolean;
  errors: string[];
};

const REQUIRED_FIELDS: (keyof CanonicalFinancialEvent)[] = [
  'schema_version',
  'message_id',
  'end_to_end_id',
  'debtor',
  'creditor',
  'amount',
  'currency',
  'source_system',
  'target_system',
  'entity_id',
  'tenant_id',
];

export function validateCanonicalFinancialEvent(
  event: Partial<CanonicalFinancialEvent>
): CanonicalValidationResult {
  const errors: string[] = [];

  for (const field of REQUIRED_FIELDS) {
    const value = event[field];
    if (value === undefined || value === null || value === '') {
      errors.push(`Missing required field: ${field}`);
    }
  }

  if (event.debtor && !event.debtor.id) {
    errors.push('debtor.id is required');
  }
  if (event.creditor && !event.creditor.id) {
    errors.push('creditor.id is required');
  }

  if (event.amount !== undefined && !/^\d+(\.\d+)?$/.test(event.amount)) {
    errors.push('amount must be a numeric string');
  }

  if (event.currency !== undefined && !/^[A-Z]{3}$/.test(event.currency)) {
    errors.push('currency must be a 3-letter ISO 4217 code');
  }

  return { valid: errors.length === 0, errors };
}
