import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@tests/test-utils';
import LoginForm from '@/app/components/auth/loginForm';
import Cookies from 'js-cookie';
import { signIn } from 'next-auth/react';

// Mock next-auth
vi.mock('next-auth/react', () => ({
  signIn: vi.fn(),
}));

// Mock next/navigation
const mockPush = vi.fn();
const mockSearchParams = new URLSearchParams();

vi.mock('next/navigation', () => ({
  useRouter: () => ({
    push: mockPush,
  }),
  useSearchParams: () => mockSearchParams,
}));

describe('LoginForm Component', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    global.fetch = vi.fn();
  });

  it('should render login form', () => {
    render(<LoginForm />);

    expect(screen.getByRole('textbox', { name: /email/i })).toBeInTheDocument();
    // Use ID selector for password since there are multiple matches
    expect(screen.getByLabelText(/^\*\s*Password$/)).toBeInTheDocument();
  });

  it('should show validation errors for empty fields', async () => {
    render(<LoginForm />);

    // Button text is "Log in" not "login" or "sign in"
    const submitButton = screen.getByRole('button', { name: /^Log in$/i });
    fireEvent.click(submitButton);

    await waitFor(() => {
      // Check for error states or messages
      expect(screen.getByRole('textbox', { name: /email/i })).toBeInTheDocument();
    });
  });

  it('should handle successful login', async () => {
    const mockResponse = {
      ok: true,
      json: async () => ({
        success: true,
        data: {
          token: 'test-token',
          user: { id: '1', name: 'Test User', email: 'test@example.com' },
        },
      }),
    };

    (global.fetch as any).mockResolvedValue(mockResponse);

    render(<LoginForm />);

    const emailInput = screen.getByRole('textbox', { name: /email/i });
    const passwordInput = screen.getByLabelText(/^\*\s*Password$/);
    const submitButton = screen.getByRole('button', { name: /^Log in$/i });

    fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
    fireEvent.change(passwordInput, { target: { value: 'password123' } });
    fireEvent.click(submitButton);

    await waitFor(() => {
      expect(global.fetch).toHaveBeenCalled();
    });
  });

  it('should handle Google sign in', async () => {
    render(<LoginForm />);

    const googleButton = screen.getByRole('button', { name: /google/i });
    fireEvent.click(googleButton);

    await waitFor(() => {
      expect(signIn).toHaveBeenCalledWith('google', expect.any(Object));
    });
  });

  it('should handle API errors', async () => {
    const mockResponse = {
      ok: false,
      json: async () => ({
        success: false,
        message: 'Invalid credentials',
      }),
    };

    (global.fetch as any).mockResolvedValue(mockResponse);

    render(<LoginForm />);

    const emailInput = screen.getByRole('textbox', { name: /email/i });
    const passwordInput = screen.getByLabelText(/^\*\s*Password$/);
    const submitButton = screen.getByRole('button', { name: /^Log in$/i });

    fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
    fireEvent.change(passwordInput, { target: { value: 'wrongpassword' } });
    fireEvent.click(submitButton);

    await waitFor(() => {
      // Check for error message display
      expect(global.fetch).toHaveBeenCalled();
    });
  });
});
