import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import { LoginPage } from './LoginPage';

describe('LoginPage Component', () => {
  it('should render the login form with default values', () => {
    render(<LoginPage onLogin={() => {}} error={null} />);

    // Check for the main heading
    expect(screen.getByText('Sign in to Flyer Crawler')).not.toBeNull();

    // Check that inputs have their default values
    expect(screen.getByLabelText('Email address')).toHaveValue('test@test.com');
    expect(screen.getByLabelText('Password')).toHaveValue('pass123');

    // Check that the button is rendered
    expect(screen.getByRole('button', { name: 'Sign in' })).not.toBeNull();
  });

  it('should allow typing in email and password fields', () => {
    render(<LoginPage onLogin={() => {}} error={null} />);

    const emailInput = screen.getByLabelText('Email address');
    const passwordInput = screen.getByLabelText('Password');

    fireEvent.change(emailInput, { target: { value: 'new@email.com' } });
    fireEvent.change(passwordInput, { target: { value: 'newpassword' } });

    expect(emailInput).toHaveValue('new@email.com');
    expect(passwordInput).toHaveValue('newpassword');
  });

  it('should call onLogin with the correct credentials on submit', async () => {
    const handleLogin = vi.fn();
    render(<LoginPage onLogin={handleLogin} error={null} />);

    const emailInput = screen.getByLabelText('Email address');
    const passwordInput = screen.getByLabelText('Password');
    const submitButton = screen.getByRole('button', { name: 'Sign in' });

    // Change credentials
    fireEvent.change(emailInput, { target: { value: 'user@example.com' } });
    fireEvent.change(passwordInput, { target: { value: 'password123' } });

    // Submit the form
    fireEvent.click(submitButton);

    // The button should be disabled and show a loading state
    expect(submitButton).toBeDisabled();
    expect(screen.queryByText('Sign in')).toBeNull(); // Text is replaced by spinner

    // Wait for the setTimeout in the component to fire
    await waitFor(() => {
      expect(handleLogin).toHaveBeenCalledWith('user@example.com', 'password123');
    });
  });

  it('should display an error message when the error prop is provided', () => {
    const errorMessage = 'Invalid credentials, please try again.';
    render(<LoginPage onLogin={() => {}} error={errorMessage} />);

    expect(screen.getByText(errorMessage)).not.toBeNull();
  });

  it('should not display an error message when the error prop is null', () => {
    render(<LoginPage onLogin={() => {}} error={null} />);

    // The error container shouldn't even be in the DOM
    expect(screen.queryByText(/invalid/i)).toBeNull();
  });
});