import { describe, it, expect, vi, beforeEach } from "vitest";
import { createEcapEventManager, LAST_WORKED_DIAGNOSTICS_KEY } from "./ecap-event-manager";

const createMockGlobalStateManager = (data: Record<string, unknown> = {}) =>
  ({
    getData: vi.fn((key: string) => data[key]),
    setData: vi.fn(),
    clearData: vi.fn(),
  }) as any;

describe("EcapEventManagerImpl", () => {
  const mockPostMessage = vi.fn();
  const mockConsoleLog = vi.fn();

  beforeEach(() => {
    vi.clearAllMocks();
    vi.stubGlobal("console", {
      ...console,
      log: mockConsoleLog,
    });
    (window.parent as any) = {
      postMessage: mockPostMessage,
    };
  });

  it("should publish and post the event correctly without diagnostics for non-whitelisted events", () => {
    const diagnostics = [{ codi: "J06" }];
    const globalStateManager = createMockGlobalStateManager({ [LAST_WORKED_DIAGNOSTICS_KEY]: diagnostics });
    const eventManager = createEcapEventManager(globalStateManager);
    const payload = { url: "https://example.com", user: "john" };

    eventManager.publish("click", "navigate", payload);

    const postedEvent = JSON.parse(mockPostMessage.mock.calls[0][0]);
    expect(postedEvent.DIAGNOSTICS).toBeUndefined();
    expect(globalStateManager.getData).not.toHaveBeenCalled();
  });

  it("should include diagnostics for whitelisted events", () => {
    const diagnostics = [{ codi: "J06", cataleg: "CIM-10", descripcio: "Test", idEcap: "1", idCipds: "2", idCdr: "3" }];
    const globalStateManager = createMockGlobalStateManager({ [LAST_WORKED_DIAGNOSTICS_KEY]: diagnostics });
    const eventManager = createEcapEventManager(globalStateManager);

    eventManager.publish("PRESCRIPCIO_ACTIVA", "NO_TANCAR", {});

    const postedEvent = JSON.parse(mockPostMessage.mock.calls[0][0]);
    expect(postedEvent.DIAGNOSTICS).toEqual(diagnostics);
    expect(globalStateManager.getData).toHaveBeenCalledWith(LAST_WORKED_DIAGNOSTICS_KEY);
  });

  it.each([
    "PROVES_ORDRES_CLINIQUES_CONSULTAR",
    "RESULT_OC",
    "LABORATORI_SEROTECA_PETICIO_CONSULTA",
    "ORDRE_TRACTAMENT",
    "PRESCRIPCIO_ACTIVA",
    "REV_IT",
    "OC_EXPRES",
  ])("should include diagnostics for whitelisted event %s", (eventType) => {
    const diagnostics = [{ codi: "J06" }];
    const globalStateManager = createMockGlobalStateManager({ [LAST_WORKED_DIAGNOSTICS_KEY]: diagnostics });
    const eventManager = createEcapEventManager(globalStateManager);

    eventManager.publish(eventType, "NO_TANCAR", {});

    const postedEvent = JSON.parse(mockPostMessage.mock.calls[0][0]);
    expect(postedEvent.DIAGNOSTICS).toEqual(diagnostics);
  });

  it("should include empty diagnostics array for whitelisted events when none set", () => {
    const globalStateManager = createMockGlobalStateManager();
    const eventManager = createEcapEventManager(globalStateManager);

    eventManager.publish("ORDRE_TRACTAMENT", "NO_TANCAR", {});

    const postedEvent = JSON.parse(mockPostMessage.mock.calls[0][0]);
    expect(postedEvent.DIAGNOSTICS).toEqual([]);
  });

  it("should not fail if window.parent is undefined", () => {
    (window as any).parent = undefined;

    const globalStateManager = createMockGlobalStateManager();
    const eventManager = createEcapEventManager(globalStateManager);
    const payload = { id: "123" };

    expect(() => {
      eventManager.publish("custom", "action", payload);
    }).not.toThrow();

    expect(mockConsoleLog).toHaveBeenCalled();
  });
});
