import { Injectable } from "@nestjs/common";
import { DMoneyProvider, DMoneyWebhookPayload } from "@edr/payment-providers";
import { WebhookProcessorService } from "../webhook-processor.service";

@Injectable()
export class DMoneyWebhookService {
  constructor(
    private readonly provider: DMoneyProvider,
    private readonly processor: WebhookProcessorService,
  ) {}

  async handle(payload: DMoneyWebhookPayload): Promise<void> {
    const signatureValid = this.provider.verifyWebhookSignature(
      payload as unknown as Record<string, unknown>,
    );
    const mapped = this.provider.mapWebhookTradeStatus(payload.trade_status);
    const providerTxnId = payload.transId ?? payload.payment_order_id;

    await this.processor.process({
      provider: this.provider.method,
      externalEventId: `${payload.payment_order_id}_${payload.trade_status}`,
      merchantOrderId: payload.merch_order_id,
      providerTxnId,
      signatureValid,
      rawStatus: payload.trade_status,
      payload: payload as unknown as Record<string, unknown>,
      result: {
        status: mapped,
        providerTxnId,
        paidAt: this.parseTransEndTime(payload.trans_end_time),
        failureCode: payload.trade_status,
      },
    });
  }

  /** D-Money sends trans_end_time either as epoch ms/s or "YYYY-MM-DD HH:mm:ss". */
  private parseTransEndTime(raw: string | undefined): Date | undefined {
    if (!raw) return undefined;
    if (/^\d+$/.test(raw)) {
      const n = parseInt(raw, 10);
      if (Number.isNaN(n)) return undefined;
      // 13-digit value is milliseconds, otherwise seconds.
      return new Date(raw.length >= 13 ? n : n * 1000);
    }
    const parsed = new Date(raw.replace(" ", "T"));
    return Number.isNaN(parsed.getTime()) ? undefined : parsed;
  }
}
