import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { AuthProvider, useAuthContext } from './AuthProvider';
import { AuthenticationConfiguration, ResourceBrowserSourceWithConfig } from '../types';
import { useAuth } from '../Hooks/useAuth';

jest.mock('../Hooks/useAuth');

const mockUseAuth = useAuth as jest.MockedFunction<typeof useAuth>;

describe('AuthContext', () => {
    const authConfig: AuthenticationConfiguration = {
        authUrl: 'https://auth.example.com',
        clientId: 'example-client-id',
        redirectUrl: 'https://example.com/callback',
        scope: 'offline',
    };

    const sourceConfig: ResourceBrowserSourceWithConfig = {
        id: '1',
        type: 'dam',
        configuration: authConfig,
    };

    const authState = {
        authToken: 'testAuthToken',
        isAuthenticated: true,
        login: jest.fn(),
        refreshAccessToken: jest.fn(),
        alwaysUseResourceRequestProxy: false,
    };

    beforeEach(() => {
        jest.clearAllMocks();
        mockUseAuth.mockReturnValue(authState);
    });

    it('should provide auth state and functions to consumers', async () => {
        const TestComponent = () => {
            const { authToken, isAuthenticated, login, alwaysUseResourceRequestProxy } = useAuthContext();
            return (
                <div>
                    <span>{`Token: ${authToken}`}</span>
                    <span>{`Authenticated: ${isAuthenticated}`}</span>
                    <button onClick={login}>Login</button>
                    <span>{`Always use resource request proxy: ${alwaysUseResourceRequestProxy}`}</span>
                </div>
            );
        };

        render(
            <AuthProvider authConfig={sourceConfig}>
                <TestComponent />
            </AuthProvider>,
        );

        expect(screen.getByText(/Token: testAuthToken/)).toBeInTheDocument();
        expect(screen.getByText(/Authenticated: true/)).toBeInTheDocument();
        expect(screen.getByText(/Always use resource request proxy: false/)).toBeInTheDocument();

        fireEvent.click(screen.getByText('Login'));

        expect(authState.login).toHaveBeenCalled();
    });

    it('should throw an error if used outside of AuthProvider', () => {
        jest.spyOn(console, 'error').mockImplementation(() => {});

        const TestComponent = () => {
            useAuthContext();
            return <div />;
        };

        expect(() => render(<TestComponent />)).toThrowError('useAuthContext must be used within an AuthProvider');
    });
});
