import { describe, expect, it, vi } from "vitest";

import {
  getPaymentUrl,
  getStripeCustomerSessionClientSecret,
  getStripeClientSecret,
  isEzpayPayment,
  launchEzpayRedirect,
  resolveEzpayLaunchTarget,
} from "../payment_launch";

describe("payment launch helpers", () => {
  it("extracts supported redirect urls from payment params", () => {
    expect(getPaymentUrl({ cashier_url: "https://pay.example/cashier" })).toBe(
      "https://pay.example/cashier",
    );
    expect(getPaymentUrl({ checkoutUrl: "https://pay.example/checkout" })).toBe(
      "https://pay.example/checkout",
    );
    expect(getPaymentUrl({ url: "" })).toBeNull();
  });

  it("detects ezpay provider case-insensitively", () => {
    expect(isEzpayPayment({ provider: "ezpay" })).toBe(true);
    expect(isEzpayPayment({ provider: "EZPAY" })).toBe(true);
    expect(isEzpayPayment({ provider: "stripe" })).toBe(false);
  });

  it("extracts stripe client secrets only for stripe-like providers", () => {
    expect(
      getStripeClientSecret({
        provider: "stripe",
        clientSecret: "pi_secret",
      }),
    ).toBe("pi_secret");
    expect(getStripeClientSecret({ client_secret: "pi_secret_snake" })).toBe(
      "pi_secret_snake",
    );
    expect(
      getStripeClientSecret({
        provider: "ezpay",
        clientSecret: "pi_secret",
      }),
    ).toBeNull();
  });

  it("enables saved cards only with an explicit flag and a Customer Session secret", () => {
    expect(
      getStripeCustomerSessionClientSecret({
        provider: "stripe",
        customerSessionClientSecret: "cuss_123_secret_456",
        savedPaymentMethodsEnabled: true,
      }),
    ).toBe("cuss_123_secret_456");
    expect(
      getStripeCustomerSessionClientSecret({
        customerSessionClientSecret: "cuss_123_secret_456",
        savedPaymentMethodsEnabled: false,
      }),
    ).toBeNull();
    expect(
      getStripeCustomerSessionClientSecret({
        customerSessionClientSecret: "invalid-customer-session",
        savedPaymentMethodsEnabled: true,
      }),
    ).toBeNull();
  });

  it("resolves Ezpay URL and QR launch parameters without treating QR data as a URL", () => {
    expect(
      resolveEzpayLaunchTarget({
        provider: "ezpay",
        channelType: "URL",
        payData: "https://pay.example/qris",
      }),
    ).toEqual({ kind: "url", paymentUrl: "https://pay.example/qris" });
    expect(
      resolveEzpayLaunchTarget({
        provider: "ezpay",
        channelType: "QR",
        payData: "00020101021226670016COM.NOBUBANK.WWW",
      }),
    ).toEqual({
      kind: "qr",
      qrData: "00020101021226670016COM.NOBUBANK.WWW",
    });
    expect(
      resolveEzpayLaunchTarget({
        provider: "ezpay",
        channelType: "QR",
        payData: "",
      }),
    ).toEqual({
      kind: "error",
      errorMessage: "QRIS payment data is missing. Please try again.",
    });
  });

  it("rejects VA and unknown Ezpay channel types with explicit errors", () => {
    expect(
      resolveEzpayLaunchTarget({ provider: "ezpay", channelType: "VA" }),
    ).toEqual({
      kind: "error",
      errorMessage: "Virtual account payments are not supported in this app.",
    });
    expect(
      resolveEzpayLaunchTarget({ provider: "ezpay", channelType: "OTHER" }),
    ).toEqual({
      kind: "error",
      errorMessage: "Unsupported Ezpay payment channel: OTHER.",
    });
  });

  it("reports a launch failure before redirecting without an order id", async () => {
    const onOpened = vi.fn();
    const onFailed = vi.fn();

    await launchEzpayRedirect({
      orderId: null,
      paymentUrl: "https://pay.example/checkout?token=secret",
      subscriptionType: "topup",
      onOpened,
      onFailed,
    });

    expect(onOpened).not.toHaveBeenCalled();
    expect(onFailed).toHaveBeenCalledWith(
      "Missing order id before opening Ezpay.",
    );
  });
});
