import { describe, it, expect, vi, beforeEach } from "vitest";
import { UmamiAnalyticsService } from "./umami";

describe("UmamiAnalyticsService", () => {
  const mockConfig = {
    websiteId: "test-website-id",
    apiEndpoint: "https://analytics.test",
    enabled: true,
  };

  const mockLogger = {
    debug: vi.fn(),
    warn: vi.fn(),
    error: vi.fn(),
    trace: vi.fn(),
  };

  beforeEach(() => {
    vi.clearAllMocks();
    global.fetch = vi.fn();
  });

  it("should not send payload if disabled", async () => {
    const service = new UmamiAnalyticsService({
      ...mockConfig,
      enabled: false,
    });
    service.track("test-event");
    expect(global.fetch).not.toHaveBeenCalled();
  });

  it("should send payload with correct data for track", async () => {
    const service = new UmamiAnalyticsService(mockConfig, mockLogger);

    (global.fetch as any).mockResolvedValue({ ok: true });

    service.track("test-event", { foo: "bar" });

    // Wait for async sendPayload
    await new Promise((resolve) => setTimeout(resolve, 0));

    expect(global.fetch).toHaveBeenCalledWith(
      "https://analytics.test/api/send",
      expect.objectContaining({
        method: "POST",
        body: expect.stringContaining('"type":"event"'),
      }),
    );

    const callBody = JSON.parse((global.fetch as any).mock.calls[0][1].body);
    expect(callBody.payload.name).toBe("test-event");
    expect(callBody.payload.data.foo).toBe("bar");
    expect(callBody.payload.website).toBe("test-website-id");
  });

  it("should log warning if send fails", async () => {
    const service = new UmamiAnalyticsService(mockConfig, mockLogger);

    (global.fetch as any).mockResolvedValue({
      ok: false,
      status: 500,
      text: () => Promise.resolve("Internal error"),
    });

    service.track("test-event");

    await new Promise((resolve) => setTimeout(resolve, 10));

    expect(mockLogger.warn).toHaveBeenCalledWith(
      "Umami API responded with error",
      expect.objectContaining({ status: 500 }),
    );
  });
});
