import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import AuthLogin from './AuthLogin';
import { useAuth } from '../hooks/useAuth';

// Mock do hook useAuth
jest.mock('../hooks/useAuth');

const createWrapper = () => {
    const queryClient = new QueryClient({
        defaultOptions: {
            queries: { retry: false },
            mutations: { retry: false },
        },
    });

    return ({ children }: { children: React.ReactNode }) => (
        <QueryClientProvider client={queryClient}>
            {children}
        </QueryClientProvider>
    );
};

describe('AuthLogin Component', () => {
    const mockLoginMutation = {
        mutate: jest.fn(),
        isPending: false,
        isError: false,
        isSuccess: false,
        error: null,
    };

    beforeEach(() => {
        jest.clearAllMocks();
        (useAuth as jest.Mock).mockReturnValue({
            loginMutation: mockLoginMutation,
        });
    });

    describe('Renderização', () => {
        it('deve renderizar formulário de login', () => {
            render(<AuthLogin title="Login" />, { wrapper: createWrapper() });

            expect(screen.getByLabelText(/usuário/i)).toBeInTheDocument();
            expect(screen.getByLabelText(/senha/i)).toBeInTheDocument();
            expect(screen.getByRole('button', { name: /sign in/i })).toBeInTheDocument();
        });

        it('deve renderizar título quando fornecido', () => {
            render(<AuthLogin title="Bem-vindo" />, { wrapper: createWrapper() });
            expect(screen.getByText('Bem-vindo')).toBeInTheDocument();
        });

        it('deve renderizar checkbox "Manter-me conectado"', () => {
            render(<AuthLogin />, { wrapper: createWrapper() });
            expect(screen.getByText(/manter-me conectado/i)).toBeInTheDocument();
        });

        it('deve renderizar link "Esqueceu sua senha"', () => {
            render(<AuthLogin />, { wrapper: createWrapper() });
            const link = screen.getByText(/esqueceu sua senha/i);
            expect(link).toBeInTheDocument();
        });
    });

    describe('Validação', () => {
        it('deve validar campos obrigatórios', async () => {
            render(<AuthLogin />, { wrapper: createWrapper() });

            const submitButton = screen.getByRole('button', { name: /sign in/i });
            fireEvent.click(submitButton);

            await waitFor(() => {
                expect(screen.getByText(/usuário é obrigatório/i)).toBeInTheDocument();
            });
        });

        it('deve validar senha mínima', async () => {
            render(<AuthLogin />, { wrapper: createWrapper() });

            const usernameInput = screen.getByLabelText(/usuário/i);
            const passwordInput = screen.getByLabelText(/senha/i);
            const submitButton = screen.getByRole('button', { name: /sign in/i });

            fireEvent.change(usernameInput, { target: { value: 'testuser' } });
            fireEvent.change(passwordInput, { target: { value: '123' } });
            fireEvent.click(submitButton);

            await waitFor(() => {
                expect(screen.getByText(/senha deve ter no mínimo 4 caracteres/i)).toBeInTheDocument();
            });
        });
    });

    describe('Submissão', () => {
        it('deve submeter formulário com credenciais válidas', async () => {
            render(<AuthLogin />, { wrapper: createWrapper() });

            const usernameInput = screen.getByLabelText(/usuário/i);
            const passwordInput = screen.getByLabelText(/senha/i);
            const submitButton = screen.getByRole('button', { name: /sign in/i });

            fireEvent.change(usernameInput, { target: { value: 'testuser' } });
            fireEvent.change(passwordInput, { target: { value: 'password123' } });
            fireEvent.click(submitButton);

            await waitFor(() => {
                expect(mockLoginMutation.mutate).toHaveBeenCalledWith({
                    username: 'testuser',
                    password: 'password123',
                });
            });
        });
    });

    describe('Estados de Loading e Erro', () => {
        it('deve desabilitar botão durante loading', () => {
            const loadingMutation = {
                ...mockLoginMutation,
                isPending: true,
            };

            (useAuth as jest.Mock).mockReturnValue({
                loginMutation: loadingMutation,
            });

            render(<AuthLogin />, { wrapper: createWrapper() });

            const submitButton = screen.getByRole('button', { name: /logging in/i });
            expect(submitButton).toBeDisabled();
        });

        it('deve mostrar mensagem de erro quando login falha', () => {
            const errorMutation = {
                ...mockLoginMutation,
                isError: true,
                error: {
                    response: {
                        data: { message: 'Credenciais inválidas' },
                    },
                },
            };

            (useAuth as jest.Mock).mockReturnValue({
                loginMutation: errorMutation,
            });

            render(<AuthLogin />, { wrapper: createWrapper() });

            expect(screen.getByText(/credenciais inválidas/i)).toBeInTheDocument();
        });

        // 🐛 TESTE QUE REVELA BUG: Erro não limpa durante nova tentativa
        it('🐛 BUG: deve esconder erro durante nova tentativa de login', () => {
            const errorAndLoadingMutation = {
                ...mockLoginMutation,
                isError: true,
                isPending: true, // Está tentando novamente
                error: {
                    response: {
                        data: { message: 'Credenciais inválidas' },
                    },
                },
            };

            (useAuth as jest.Mock).mockReturnValue({
                loginMutation: errorAndLoadingMutation,
            });

            render(<AuthLogin />, { wrapper: createWrapper() });

            // ❌ ESTE TESTE VAI FALHAR - erro ainda aparece durante loading!
            expect(screen.queryByText(/credenciais inválidas/i)).not.toBeInTheDocument();
        });
    });

    describe('🐛 Bugs Identificados', () => {
        // 🐛 BUG: Link "Esqueceu senha" vai para home
        it('🐛 BUG: link "Esqueceu senha" deve ir para /forgot-password', () => {
            render(<AuthLogin />, { wrapper: createWrapper() });

            const link = screen.getByText(/esqueceu sua senha/i).closest('a');

            // ❌ ESTE TESTE VAI FALHAR - href é "/"
            expect(link).toHaveAttribute('href', '/forgot-password');
        });

        // 🐛 BUG: Checkbox não funciona
        it('🐛 BUG: checkbox "Manter-me conectado" deve ser controlado', () => {
            render(<AuthLogin />, { wrapper: createWrapper() });

            const checkbox = screen.getByRole('checkbox', { name: /manter-me conectado/i });

            // Checkbox está sempre marcado
            expect(checkbox).toBeChecked();

            // Tenta desmarcar
            fireEvent.click(checkbox);

            // ❌ ESTE TESTE VAI FALHAR - checkbox não muda de estado!
            expect(checkbox).not.toBeChecked();
        });
    });
});
