import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { ActivityMonitorImpl } from "./activity-monitor";

describe("ActivityMonitor", () => {
  let monitor: ActivityMonitorImpl;

  beforeEach(() => {
    vi.useFakeTimers();
    monitor = new ActivityMonitorImpl();
  });

  afterEach(() => {
    monitor.stop();
    vi.useRealTimers();
  });

  it("should return 0 before any activity", () => {
    expect(monitor.getLastActivityTimestamp()).toBe(0);
  });

  it("should update timestamp on keydown", () => {
    monitor.start();
    const before = Date.now();
    window.dispatchEvent(new Event("keydown"));
    expect(monitor.getLastActivityTimestamp()).toBeGreaterThanOrEqual(before);
  });

  it("should update timestamp on click", () => {
    monitor.start();
    const before = Date.now();
    window.dispatchEvent(new Event("click"));
    expect(monitor.getLastActivityTimestamp()).toBeGreaterThanOrEqual(before);
  });

  it("should update timestamp on scroll", () => {
    monitor.start();
    const before = Date.now();
    window.dispatchEvent(new Event("scroll"));
    expect(monitor.getLastActivityTimestamp()).toBeGreaterThanOrEqual(before);
  });

  it("should reflect the most recent activity time", () => {
    monitor.start();

    window.dispatchEvent(new Event("keydown"));
    const first = monitor.getLastActivityTimestamp();

    vi.advanceTimersByTime(5000);
    window.dispatchEvent(new Event("click"));
    const second = monitor.getLastActivityTimestamp();

    expect(second).toBeGreaterThan(first);
  });

  it("should not update timestamp after stop", () => {
    monitor.start();
    window.dispatchEvent(new Event("keydown"));
    const timestampBeforeStop = monitor.getLastActivityTimestamp();

    monitor.stop();
    vi.advanceTimersByTime(5000);
    window.dispatchEvent(new Event("click"));

    expect(monitor.getLastActivityTimestamp()).toBe(timestampBeforeStop);
  });

});
