import {
  ScreenRevealManager,
  COMPONENT_LOADING_STATE,
} from "../ScreenRevealManager";

describe("ScreenRevealManager", () => {
  const mockCallback = jest.fn();

  beforeEach(() => {
    jest.clearAllMocks();
  });

  it("should initialize with the correct number of components to wait for", () => {
    const componentsToRender: ZappUIComponent[] = [
      { component_type: "component1" },
      { component_type: "component2" },
      { component_type: "component3" },
    ];

    const manager = new ScreenRevealManager(componentsToRender, mockCallback);

    expect(manager.numberOfComponentsWaitToLoadBeforePresent).toBe(3);

    expect(manager.renderingState).toEqual([
      COMPONENT_LOADING_STATE.UNKNOWN,
      COMPONENT_LOADING_STATE.UNKNOWN,
      COMPONENT_LOADING_STATE.UNKNOWN,
    ]);
  });

  it("should call the callback when the required number of components are loaded successfully", () => {
    const componentsToRender: ZappUIComponent[] = [
      { component_type: "component1" },
      { component_type: "component2" },
      { component_type: "component3" },
    ];

    const manager = new ScreenRevealManager(componentsToRender, mockCallback);

    manager.onLoadFinished(0);
    manager.onLoadFinished(1);
    manager.onLoadFinished(2);

    expect(mockCallback).toHaveBeenCalledTimes(1);
  });

  it("should call the callback when the required number of components fail to load", () => {
    const componentsToRender: ZappUIComponent[] = [
      { component_type: "component1" },
      { component_type: "component2" },
      { component_type: "component3" },
    ];

    const manager = new ScreenRevealManager(componentsToRender, mockCallback);

    manager.onLoadFailed(0);
    manager.onLoadFailed(1);
    manager.onLoadFailed(2);

    expect(mockCallback).toHaveBeenCalledTimes(1);
  });

  it("should call the callback when a mix of successful and failed loads meet the required number", () => {
    const componentsToRender: ZappUIComponent[] = [
      { component_type: "component1" },
      { component_type: "component2" },
      { component_type: "component3" },
    ];

    const manager = new ScreenRevealManager(componentsToRender, mockCallback);

    manager.onLoadFinished(0);
    manager.onLoadFailed(1);
    manager.onLoadFinished(2);

    expect(mockCallback).toHaveBeenCalledTimes(1);
  });

  it("should not call the callback if the required number of components are not loaded", () => {
    const componentsToRender: ZappUIComponent[] = [
      { component_type: "component1" },
      { component_type: "component2" },
      { component_type: "component3" },
    ];

    const manager = new ScreenRevealManager(componentsToRender, mockCallback);

    manager.onLoadFinished(0);
    manager.onLoadFailed(1);

    expect(mockCallback).not.toHaveBeenCalled();
  });

  it("should call the callback when the when first component is gallery and it was loaded successfully", () => {
    const componentsToRender: ZappUIComponent[] = [
      { component_type: "gallery-qb" },
      { component_type: "component2" },
      { component_type: "component3" },
    ];

    const manager = new ScreenRevealManager(componentsToRender, mockCallback);

    manager.onLoadFinished(0);

    expect(mockCallback).toHaveBeenCalledTimes(1);
  });
});
