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

import { PaymentPlan } from "@/data/dto/payment";

import {
  behaviorAnalytics,
  sanitizeAnalyticsCheckoutUrl,
  type CozsweetBehaviorAnalyticsSdk,
} from "../behavior_analytics";
import {
  getBehaviorAnalyticsBaseUrl,
  getBehaviorAnalyticsEndpoint,
  getBehaviorAnalyticsScriptUrl,
} from "../behavior_analytics_config";

function createSdkMock(): CozsweetBehaviorAnalyticsSdk {
  return {
    elementClick: vi.fn(),
    paywallShown: vi.fn(),
    rechargeModalOpen: vi.fn(),
    planImpression: vi.fn(),
    planClick: vi.fn(),
    createOrderStart: vi.fn(),
    createOrderSuccess: vi.fn(),
    createOrderFailed: vi.fn(),
    checkoutOpened: vi.fn(),
    checkoutFailed: vi.fn(),
    statusPollStart: vi.fn(),
    statusPollUpdate: vi.fn(),
    statusPollTimeout: vi.fn(),
  };
}

const plan = PaymentPlan.from({
  planId: "credits-100",
  planName: "100 Credits",
  orderType: "dol",
  vipDays: null,
  dolAmount: 100,
  creditBalance: 100,
  amountCents: 499,
  originalAmountCents: null,
  currency: "USD",
});

afterEach(() => {
  delete window.CozsweetPaymentAnalytics;
  vi.restoreAllMocks();
});

describe("behavior analytics configuration", () => {
  it("uses production endpoints only for the production app environment", () => {
    expect(getBehaviorAnalyticsBaseUrl("production")).toBe(
      "https://api.banlv-ai.com",
    );
    expect(getBehaviorAnalyticsBaseUrl("development")).toBe(
      "https://proapi.banlv-ai.com",
    );
    expect(getBehaviorAnalyticsBaseUrl("test")).toBe(
      "https://proapi.banlv-ai.com",
    );
    expect(getBehaviorAnalyticsEndpoint("test")).toBe(
      "https://proapi.banlv-ai.com/api/behavior/events",
    );
    expect(getBehaviorAnalyticsScriptUrl("production")).toBe(
      "https://api.banlv-ai.com/js/cozsweet-payment-analytics.js",
    );
  });
});

describe("behavior analytics adapter", () => {
  it("does nothing when the SDK is unavailable and swallows SDK errors", () => {
    expect(() =>
      behaviorAnalytics.planClick(plan, {
        entryPoint: "subscription_direct",
        triggerReason: "manual_recharge",
      }),
    ).not.toThrow();

    const sdk = createSdkMock();
    vi.mocked(sdk.planClick).mockImplementation(() => {
      throw new Error("analytics unavailable");
    });
    window.CozsweetPaymentAnalytics = sdk;

    expect(() =>
      behaviorAnalytics.planClick(plan, {
        entryPoint: "subscription_direct",
        triggerReason: "manual_recharge",
      }),
    ).not.toThrow();
  });

  it("forwards payment context and strips checkout query parameters", () => {
    const sdk = createSdkMock();
    window.CozsweetPaymentAnalytics = sdk;

    behaviorAnalytics.planClick(plan, {
      entryPoint: "chat_unlock",
      triggerReason: "insufficient_credits",
    });
    behaviorAnalytics.checkoutOpened({
      orderId: "order-1",
      plan,
      payChannel: "stripe",
      checkoutUrl:
        "https://checkout.example/pay/session?client_secret=secret#payment",
    });

    expect(sdk.planClick).toHaveBeenCalledWith(
      expect.objectContaining({ planId: "credits-100", amountCents: 499 }),
      {
        entryPoint: "chat_unlock",
        triggerReason: "insufficient_credits",
      },
    );
    expect(sdk.checkoutOpened).toHaveBeenCalledWith(
      "order-1",
      expect.objectContaining({ planId: "credits-100" }),
      "stripe",
      "https://checkout.example/pay/session",
    );
  });

  it("uses a safe placeholder for invalid checkout urls", () => {
    expect(sanitizeAnalyticsCheckoutUrl("stripe_embedded")).toBe(
      "stripe_embedded",
    );
    expect(sanitizeAnalyticsCheckoutUrl("not a url")).toBe(
      "external_checkout",
    );
    expect(sanitizeAnalyticsCheckoutUrl("javascript:alert('no')")).toBe(
      "external_checkout",
    );
  });
});
