import type { HybxClient } from './HybxClient';
import type {
  HybxPaymentRequest,
  HybxPaymentResponse,
  HybxSettlementEvent,
  HybxWebhookPayload,
} from './types';

const payments = new Map<string, HybxPaymentResponse>();

export class MockHybxClient implements HybxClient {
  readonly environment: string;

  constructor(environment = 'sandbox') {
    this.environment = environment;
  }

  async initiatePayment(request: HybxPaymentRequest): Promise<HybxPaymentResponse> {
    const paymentId = `mock-pay-${request.idempotencyKey.slice(0, 16)}`;
    const existing = payments.get(request.idempotencyKey);
    if (existing) return existing;

    const response: HybxPaymentResponse = {
      paymentId,
      status: 'accepted',
      uetr: `mock-uetr-${paymentId}`,
      messageId: `mock-msg-${paymentId}`,
      createdAt: new Date().toISOString(),
      rawReference: request.endToEndId,
    };
    payments.set(request.idempotencyKey, response);
    payments.set(paymentId, response);
    return response;
  }

  async getPaymentStatus(paymentId: string): Promise<HybxPaymentResponse> {
    const found = payments.get(paymentId);
    if (!found) {
      return {
        paymentId,
        status: 'pending',
        createdAt: new Date().toISOString(),
      };
    }
    return found;
  }

  async listSettlementEvents(): Promise<HybxSettlementEvent[]> {
    return Array.from(payments.values()).map((p) => ({
      eventId: `evt-${p.paymentId}`,
      paymentId: p.paymentId,
      status: p.status,
      settlementDate: new Date().toISOString().slice(0, 10),
      timestamp: new Date().toISOString(),
    }));
  }

  parseWebhookPayload(body: string): HybxWebhookPayload {
    const parsed = JSON.parse(body) as Record<string, unknown>;
    return {
      eventType: String(parsed.eventType ?? 'payment.status'),
      eventId: String(parsed.eventId ?? `wh-${Date.now()}`),
      timestamp: String(parsed.timestamp ?? new Date().toISOString()),
      data: (parsed.data as Record<string, unknown>) ?? parsed,
    };
  }
}
