/**
 * Tests for the #4431 fix: Socket.IO connects lazily on /chat/.
 *
 * The chat page must NOT open a Socket.IO connection on page load — that
 * per-navigation connect/disconnect churn freezes the werkzeug dev server.
 * Other realtime pages keep their eager auto-connect.
 *
 * We drive the module's auto-init (a setTimeout scheduled at import time)
 * with fake timers and assert whether io() — the connection factory — was
 * called, per page path. resetModules + dynamic import gives each case a
 * fresh evaluation of the IIFE with its own window.location.pathname.
 */
import { beforeEach, afterEach, describe, it, expect, vi } from 'vitest';

function setupEnv(pathname) {
    vi.resetModules();
    Object.defineProperty(window, 'location', {
        configurable: true,
        value: { pathname, protocol: 'http:', host: 'localhost' },
    });
    const io = vi.fn(() => ({
        on: vi.fn(),
        emit: vi.fn(),
        off: vi.fn(),
        connected: false,
    }));
    globalThis.io = io;
    window.api = { getResearchStatus: vi.fn(), getCsrfToken: () => '' };
    window.ResearchStates = { isTerminal: () => false, logLevel: () => 'info' };
    return io;
}

describe('Socket.IO auto-connect gating (#4431)', () => {
    beforeEach(() => vi.useFakeTimers());
    afterEach(() => {
        vi.useRealTimers();
        delete globalThis.io;
    });

    it('does NOT auto-connect on a /chat/ page (lazy)', async () => {
        const io = setupEnv('/chat/some-session-id');
        await import('@js/services/socket.js');
        // Fire the auto-init setTimeout(…, 100) scheduled at import.
        vi.advanceTimersByTime(300);
        expect(io).not.toHaveBeenCalled();
    });

    it('DOES auto-connect on a /progress/ page (eager, unchanged)', async () => {
        const io = setupEnv('/progress/abc-123');
        await import('@js/services/socket.js');
        vi.advanceTimersByTime(300);
        expect(io).toHaveBeenCalledTimes(1);
    });

    it('DOES auto-connect on a /research page (eager, unchanged)', async () => {
        const io = setupEnv('/research');
        await import('@js/services/socket.js');
        vi.advanceTimersByTime(300);
        expect(io).toHaveBeenCalledTimes(1);
    });

    it('still connects lazily on /chat/ when a research is subscribed', async () => {
        const io = setupEnv('/chat/some-session-id');
        await import('@js/services/socket.js');
        vi.advanceTimersByTime(300);
        expect(io).not.toHaveBeenCalled(); // confirmed lazy at load

        // Subscribing to a research must initialize the socket on demand.
        window.socket.subscribeToResearch('research-1', () => {});
        expect(io).toHaveBeenCalledTimes(1);
    });
});
