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();
    });
  });
});
