
import { describe, it, expect, beforeEach, vi } from 'vitest';
import {
  publish,
  subscribe,
  getSnapshot,
  AwarenessEvent,
  resetBus,
  type AwarenessEventPayload,
} from '@/lib/awareness';

// Set test-specific env vars
process.env.TEST_AWARENESS = 'true';
process.env.TEST_TELEMETRY = 'true';

describe('Awareness Layer', () => {
  beforeEach(() => {
    // Reset bus and snapshot state before each test
    resetBus();
  });

  it('should publish and subscribe to events', () => {
    const listener = vi.fn();
    const unsubscribe = subscribe(listener);

    const event: AwarenessEventPayload = {
      type: AwarenessEvent.WINDOW_OPENED,
      payload: { windowId: 'test-window', timestamp: Date.now() },
    };

    publish(event);

    expect(listener).toHaveBeenCalledOnce();
    expect(listener).toHaveBeenCalledWith(event);

    unsubscribe();
  });

  it('should update snapshot on WINDOW_OPENED', () => {
    const event: AwarenessEventPayload = {
      type: AwarenessEvent.WINDOW_OPENED,
      payload: { windowId: 'window-1', timestamp: Date.now() },
    };

    publish(event);

    const snapshot = getSnapshot();
    expect(snapshot.openWindows).toEqual(['window-1']);
    expect(snapshot.activeWindow).toBe('window-1');
    expect(snapshot.windowCount).toBe(1);
    expect(snapshot.lastEvent).toBe(AwarenessEvent.WINDOW_OPENED);
  });

  it('should update snapshot on WINDOW_FOCUSED', () => {
    // First, open a couple of windows
    publish({
      type: AwarenessEvent.WINDOW_OPENED,
      payload: { windowId: 'window-1', timestamp: Date.now() },
    });
    publish({
      type: AwarenessEvent.WINDOW_OPENED,
      payload: { windowId: 'window-2', timestamp: Date.now() },
    });

    // Now, focus on the first one
    const focusEvent: AwarenessEventPayload = {
      type: AwarenessEvent.WINDOW_FOCUSED,
      payload: { windowId: 'window-1', timestamp: Date.now() },
    };

    publish(focusEvent);

    const snapshot = getSnapshot();
    expect(snapshot.openWindows).toEqual(['window-1', 'window-2']);
    expect(snapshot.activeWindow).toBe('window-1');
    expect(snapshot.lastEvent).toBe(AwarenessEvent.WINDOW_FOCUSED);
  });

  it('should update snapshot on WINDOW_CLOSED', () => {
    publish({
      type: AwarenessEvent.WINDOW_OPENED,
      payload: { windowId: 'window-1', timestamp: Date.now() },
    });
    publish({
      type: AwarenessEvent.WINDOW_OPENED,
      payload: { windowId: 'window-2', timestamp: Date.now() },
    });

    const closeEvent: AwarenessEventPayload = {
      type: AwarenessEvent.WINDOW_CLOSED,
      payload: { windowId: 'window-1', timestamp: Date.now() },
    };

    publish(closeEvent);

    const snapshot = getSnapshot();
    expect(snapshot.openWindows).toEqual(['window-2']);
    expect(snapshot.windowCount).toBe(1);
    // The active window should fall back to the last one in the list
    expect(snapshot.activeWindow).toBe('window-2');
    expect(snapshot.lastEvent).toBe(AwarenessEvent.WINDOW_CLOSED);
  });

  it('should correctly handle closing the active window', () => {
    publish({ type: AwarenessEvent.WINDOW_OPENED, payload: { windowId: 'w1', timestamp: 1 } });
    publish({ type: AwarenessEvent.WINDOW_OPENED, payload: { windowId: 'w2', timestamp: 2 } });
    publish({ type: AwarenessEvent.WINDOW_FOCUSED, payload: { windowId: 'w2', timestamp: 3 } });

    publish({ type: AwarenessEvent.WINDOW_CLOSED, payload: { windowId: 'w2', timestamp: 4 } });

    const snapshot = getSnapshot();
    expect(snapshot.openWindows).toEqual(['w1']);
    expect(snapshot.activeWindow).toBe('w1'); // Falls back to the remaining window
  });

    it('should handle closing the last window', () => {
    publish({ type: AwarenessEvent.WINDOW_OPENED, payload: { windowId: 'w1', timestamp: 1 } });
    publish({ type: AwarenessEvent.WINDOW_CLOSED, payload: { windowId: 'w1', timestamp: 2 } });

    const snapshot = getSnapshot();
    expect(snapshot.openWindows).toEqual([]);
    expect(snapshot.activeWindow).toBeNull();
    expect(snapshot.windowCount).toBe(0);
  });

  it('should handle DESKTOP_LOADED event', () => {
    const event: AwarenessEventPayload = {
        type: AwarenessEvent.DESKTOP_LOADED,
        payload: {
            timestamp: Date.now(),
            openWindows: 0,
            activeWindow: null,
        }
    };

    publish(event);

    const snapshot = getSnapshot();
    expect(snapshot.lastEvent).toBe(AwarenessEvent.DESKTOP_LOADED);
    expect(snapshot.windowCount).toBe(0);
    expect(snapshot.activeWindow).toBeNull();
  });
});
