import test from "node:test";
import assert from "node:assert/strict";
import { BlinkWebhookProcessor } from "./BlinkWebhookProcessor";
import { PendingBlinkInvoiceRecord } from "./types";

function buildPendingInvoice(): PendingBlinkInvoiceRecord {
  return {
    provider: "blink",
    network: "bitcoin_lightning",
    asset: "BTC",
    payment_request: "lnbc25u1test",
    payment_hash: "bf6b61f814b2e2284f5cbb7c9f9e67887018ffe3f53bedb9b70dec0a15ebca1c",
    amount_sats: 2707,
    expires_at: null,
    reference: "ln_dep_123",
    user_id: 42,
    currency: "BTC",
    status: "pending",
    created_at: "2026-05-06T10:00:00.000Z",
    updated_at: "2026-05-06T10:00:00.000Z",
    raw_invoice_payload: {},
    raw_webhook_payload: null,
  };
}

test("normalizes a receive.lightning Blink webhook into a queued deposit event", async () => {
  const pending = buildPendingInvoice();
  let confirmedReference: string | null = null;
  const processor = new BlinkWebhookProcessor({
    async savePending() {
      return;
    },
    async findPendingByPaymentHashOrReference(paymentHash) {
      return paymentHash === pending.payment_hash ? pending : null;
    },
    async markConfirmed(reference) {
      confirmedReference = reference;
    },
  });

  const result = await processor.process({
    accountId: "acct_1",
    eventType: "receive.lightning",
    walletId: "wallet_1",
    transaction: {
      createdAt: "2026-05-06T12:00:00.000Z",
      id: "txn_123",
      initiationVia: {
        paymentHash: pending.payment_hash,
        type: "lightning",
      },
      settlementAmount: 2707,
      settlementCurrency: "BTC",
      settlementDisplayPrice: {
        walletCurrency: "BTC",
      },
      status: "success",
    },
  });

  assert.equal(confirmedReference, pending.reference);
  assert.equal(result.events.length, 1);
  assert.equal(result.events[0].idempotency_key, `blink:${pending.payment_hash}`);
  assert.equal(result.events[0].user_id, 42);
  assert.equal(result.events[0].amount_sats, 2707);
  assert.equal(result.events[0].payment_hash, pending.payment_hash);
  assert.equal(result.events[0].provider_reference, "txn_123");
  assert.deepEqual(result.metrics, {
    ignored: 0,
    unsupported: 0,
    unmatched: 0,
  });
});

test("ignores non-success Blink webhook statuses", async () => {
  const processor = new BlinkWebhookProcessor({
    async savePending() {
      return;
    },
    async findPendingByPaymentHashOrReference() {
      return buildPendingInvoice();
    },
    async markConfirmed() {
      throw new Error("should not be called");
    },
  });

  const result = await processor.process({
    eventType: "receive.lightning",
    transaction: {
      initiationVia: {
        paymentHash: buildPendingInvoice().payment_hash,
      },
      status: "pending",
    },
  });

  assert.equal(result.events.length, 0);
  assert.deepEqual(result.metrics, {
    ignored: 1,
    unsupported: 0,
    unmatched: 0,
  });
});
