import { describe, expect, test } from "vitest";
import {
  attachDashboardRefreshLifecycle,
  createDashboardRequestAborter,
  shouldPauseDashboardRefresh,
} from "./dashboard-refresh";

describe("dashboard refresh lifecycle", () => {
  test("pauses refreshes when the document is hidden or the browser is offline", () => {
    expect(
      shouldPauseDashboardRefresh({ visibilityState: "visible", online: true }),
    ).toBe(false);
    expect(
      shouldPauseDashboardRefresh({ visibilityState: "hidden", online: true }),
    ).toBe(true);
    expect(
      shouldPauseDashboardRefresh({ visibilityState: "visible", online: false }),
    ).toBe(true);
  });

  test("aborts shell and tile requests when a new shell run starts", () => {
    const aborter = createDashboardRequestAborter();
    const shellSignal = aborter.beginShellRun();
    const tileSignal = aborter.beginTileRun();

    const nextShellSignal = aborter.beginShellRun();

    expect(shellSignal.aborted).toBe(true);
    expect(tileSignal.aborted).toBe(true);
    expect(nextShellSignal.aborted).toBe(false);
  });

  test("aborts active requests when refreshes are paused", () => {
    const aborter = createDashboardRequestAborter();
    const shellSignal = aborter.beginShellRun();
    const tileSignal = aborter.beginTileRun();

    aborter.abortActiveRequests();

    expect(shellSignal.aborted).toBe(true);
    expect(tileSignal.aborted).toBe(true);
  });

  test("pauses on hidden, offline, and pagehide events then resumes immediately when visible", () => {
    const documentTarget = new EventTarget();
    const windowTarget = new EventTarget();
    const calls: string[] = [];
    let paused = true;

    const detach = attachDashboardRefreshLifecycle({
      documentTarget,
      windowTarget,
      loadDashboard: () => {
        calls.push("load");
      },
      pauseRefreshes: () => {
        calls.push("pause");
      },
      refreshPaused: () => paused,
    });

    documentTarget.dispatchEvent(new Event("visibilitychange"));
    windowTarget.dispatchEvent(new Event("offline"));
    windowTarget.dispatchEvent(new Event("pagehide"));

    paused = false;
    documentTarget.dispatchEvent(new Event("visibilitychange"));
    windowTarget.dispatchEvent(new Event("online"));

    detach();
    documentTarget.dispatchEvent(new Event("visibilitychange"));
    windowTarget.dispatchEvent(new Event("online"));

    expect(calls).toEqual(["pause", "pause", "pause", "load", "load"]);
  });
});
