// Generic Plugin Adapter
// Base class for core banking system adapters

import {
  ParticipantCreateRequest,
  AccountCreateRequest,
  TransferCreateRequest,
  NostroVostroTransfer,
  NostroVostroAccount,
  Participant,
} from '@/core/nostro-vostro/nostro-vostro.types';

/**
 * Base adapter interface for core banking system integrations
 */
export interface IPluginAdapter {
  /**
   * Get adapter name
   */
  getName(): string;

  /**
   * Get adapter version
   */
  getVersion(): string;

  /**
   * Check if adapter is available/connected
   */
  isAvailable(): Promise<boolean>;

  /**
   * Map internal participant to DBIS format
   */
  mapParticipant(internalData: unknown): ParticipantCreateRequest;

  /**
   * Map internal account to DBIS format
   */
  mapAccount(internalData: unknown): AccountCreateRequest;

  /**
   * Map internal transfer to DBIS format
   */
  mapTransfer(internalData: unknown): TransferCreateRequest;

  /**
   * Map DBIS transfer to internal format
   */
  mapTransferToInternal(transfer: NostroVostroTransfer): unknown;

  /**
   * Map DBIS account to internal format
   */
  mapAccountToInternal(account: NostroVostroAccount): unknown;

  /**
   * Post transfer to internal system
   */
  postTransfer(transfer: NostroVostroTransfer): Promise<{ success: boolean; internalId?: string; error?: string }>;

  /**
   * Get account balance from internal system
   */
  getAccountBalance(accountId: string): Promise<{ balance: string; available: string; hold: string }>;

  /**
   * Reconcile accounts
   */
  reconcile(accountId: string, asOfDate: Date): Promise<{ matched: number; breaks: unknown[] }>;
}

/**
 * Base adapter class with common functionality
 */
export abstract class BasePluginAdapter implements IPluginAdapter {
  protected name: string;
  protected version: string;
  protected config: Record<string, unknown>;

  constructor(name: string, version: string, config: Record<string, unknown> = {}) {
    this.name = name;
    this.version = version;
    this.config = config;
  }

  getName(): string {
    return this.name;
  }

  getVersion(): string {
    return this.version;
  }

  abstract isAvailable(): Promise<boolean>;
  abstract mapParticipant(internalData: unknown): ParticipantCreateRequest;
  abstract mapAccount(internalData: unknown): AccountCreateRequest;
  abstract mapTransfer(internalData: unknown): TransferCreateRequest;
  abstract mapTransferToInternal(transfer: NostroVostroTransfer): unknown;
  abstract mapAccountToInternal(account: NostroVostroAccount): unknown;
  abstract postTransfer(transfer: NostroVostroTransfer): Promise<{ success: boolean; internalId?: string; error?: string }>;
  abstract getAccountBalance(accountId: string): Promise<{ balance: string; available: string; hold: string }>;
  abstract reconcile(accountId: string, asOfDate: Date): Promise<{ matched: number; breaks: unknown[] }>;

  /**
   * Validate idempotency key
   */
  protected validateIdempotencyKey(key: string | undefined): boolean {
    if (!key) return false;
    // Basic validation - can be extended
    return key.length > 0 && key.length <= 255;
  }

  /**
   * Generate internal reference ID
   */
  protected generateInternalReference(prefix: string): string {
    return `${prefix}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
  }

  /**
   * Handle errors consistently
   */
  protected handleError(error: unknown, context: string): { success: false; error: string } {
    const message = error instanceof Error ? error.message : 'Unknown error';
    console.error(`[${this.name}] Error in ${context}:`, message);
    return { success: false, error: `${context}: ${message}` };
  }
}

