// @vitest-environment jsdom
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { AdminTab } from './AdminTab';


const { authState, socketMock } = vi.hoisted(() => ({
    authState: {
        user: { id: 'admin-1' } as any,
        profile: { role: 'admin' } as any
    },
    socketMock: {
        on: vi.fn(),
        off: vi.fn()
    }
}));

vi.mock('../components/AuthContext', () => ({
    useAuth: () => authState
}));

vi.mock('../hooks/useWebSocket', () => ({
    useWebSocket: () => ({
        socket: socketMock,
        connected: true
    })
}));

const DUMMY_BOT_STATE: any = {
    settings: { isAlgoEnabled: true },
    symbols: {},
    health: { tradingLoopHealthy: true, reconciliationLoopHealthy: true, lockContentionCount: 0 },
    positions: [],
    orders: [],
    history: []
};

describe('AdminTab coverage', () => {
    beforeEach(() => {
        vi.clearAllMocks();
        authState.profile.role = 'admin';
    });


    it('denies access to non-admins', () => {
        authState.profile.role = 'user';
        render(<AdminTab botState={DUMMY_BOT_STATE} />);
        expect(screen.getByText(/Access Denied/i)).toBeInTheDocument();
    });

    it('listens for debug logs and slices them', async () => {
        const user = userEvent.setup();
        authState.profile.role = 'admin';
        let logHandler: any;
        socketMock.on.mockImplementation((event, rb) => {
            if (event === 'debug_log') logHandler = rb;
        });

        render(<AdminTab botState={DUMMY_BOT_STATE} />);

        // Switch to Debug tab to see logs
        const debugTabBtn = screen.getByRole('button', { name: /Debug/i });
        await user.click(debugTabBtn);

        expect(socketMock.on).toHaveBeenCalledWith('debug_log', expect.any(Function));

        // Simulate 101 logs to test slicing
        for (let i = 0; i < 105; i++) {
            logHandler({ message: `Log ${i}` });
        }

        await waitFor(() => expect(screen.getByText(/Log 104/i)).toBeInTheDocument());
        // Log 0 should have been sliced away (limit 100)
        expect(screen.queryByText(/Log 0/i)).not.toBeInTheDocument();
    });

});
