// @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 { ConfigTab } from './ConfigTab';

const {
    authState,
    fetchDynamicConfigItemsMock,
    upsertDynamicConfigItemsMock
} = vi.hoisted(() => ({
    authState: {
        profile: { role: 'admin' } as any
    },
    fetchDynamicConfigItemsMock: vi.fn(),
    upsertDynamicConfigItemsMock: vi.fn()
}));

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

vi.mock('../lib/dynamicConfigApi', () => ({
    fetchDynamicConfigItems: fetchDynamicConfigItemsMock,
    upsertDynamicConfigItems: upsertDynamicConfigItemsMock
}));

describe('ConfigTab DOM behavior', () => {
    beforeEach(() => {
        authState.profile.role = 'admin';
        fetchDynamicConfigItemsMock.mockReset();
        upsertDynamicConfigItemsMock.mockReset();
        fetchDynamicConfigItemsMock.mockResolvedValue([
            { key: 'BOT_MODE', value: 'enabled', description: 'Bot mode' },
            { key: 'API_KEY', value: 'masked', description: 'Secret key' }
        ]);
        upsertDynamicConfigItemsMock.mockResolvedValue(undefined);
    });

    it('loads configs, supports edit/reset, and saves with success message', async () => {
        const user = userEvent.setup();
        render(<ConfigTab />);

        await waitFor(() => {
            expect(screen.getByDisplayValue('enabled')).toBeInTheDocument();
            expect(screen.getByRole('button', { name: 'Commit Changes' })).toBeDisabled();
        });

        const modeTextarea = screen.getByDisplayValue('enabled');
        await user.clear(modeTextarea);
        await user.type(modeTextarea, 'disabled');

        expect(screen.getByRole('button', { name: 'Commit Changes' })).toBeEnabled();
        expect(screen.getByRole('button', { name: 'Abort Changes' })).toBeInTheDocument();

        await user.click(screen.getByRole('button', { name: 'Abort Changes' }));
        expect(screen.getByDisplayValue('enabled')).toBeInTheDocument();

        const resetModeTextarea = screen.getByDisplayValue('enabled');
        await user.clear(resetModeTextarea);
        await user.type(resetModeTextarea, 'disabled');
        await user.click(screen.getByRole('button', { name: 'Commit Changes' }));

        await waitFor(() => {
            expect(upsertDynamicConfigItemsMock).toHaveBeenCalledTimes(1);
            expect(screen.getByText('SYNC COMPLETE')).toBeInTheDocument();
        });

        expect(upsertDynamicConfigItemsMock.mock.calls[0][0]).toEqual(
            expect.arrayContaining([
                expect.objectContaining({ key: 'BOT_MODE', value: 'disabled' }),
                expect.objectContaining({ key: 'API_KEY', value: 'masked' })
            ])
        );
    }, 20000);

    it('renders empty-state table when no config rows exist', async () => {
        fetchDynamicConfigItemsMock.mockResolvedValueOnce([]);
        render(<ConfigTab />);

        await waitFor(() => {
            expect(screen.getByText('Configuration Map Null')).toBeInTheDocument();
        });
    });

    it('shows save error banner when upsert fails', async () => {
        upsertDynamicConfigItemsMock.mockRejectedValueOnce(new Error('write failed'));
        const user = userEvent.setup();

        render(<ConfigTab />);

        await waitFor(() => {
            expect(screen.getByDisplayValue('enabled')).toBeInTheDocument();
        });

        const modeTextarea = screen.getByDisplayValue('enabled');
        await user.clear(modeTextarea);
        await user.type(modeTextarea, 'paused');
        await user.click(screen.getByRole('button', { name: 'Commit Changes' }));

        await waitFor(() => {
            expect(screen.getByText('CRITICAL ERROR')).toBeInTheDocument();
            expect(screen.getByText(/Sync failed: write failed/)).toBeInTheDocument();
        });
    }, 20000);

    it('denies access to non-admin users without fetching dynamic config', () => {
        authState.profile.role = 'user';

        render(<ConfigTab />);

        expect(screen.getByText(/Access Denied/i)).toBeInTheDocument();
        expect(fetchDynamicConfigItemsMock).not.toHaveBeenCalled();
    });
});
