import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { ToastProvider } from '@/components/ui/Toast';
import { I18nProvider } from '@/lib/i18n';
import LoginPage from '@/app/(auth)/login/page';

// Mock the API module
vi.mock('@/lib/api', () => ({
  login: vi.fn(),
  setTokens: vi.fn(),
  clearTokens: vi.fn(),
  isAuthenticated: () => false,
}));

// Mock next/navigation
vi.mock('next/navigation', () => ({
  useRouter: () => ({
    push: vi.fn(),
    replace: vi.fn(),
    back: vi.fn(),
    refresh: vi.fn(),
  }),
  redirect: vi.fn(),
}));

import { login as mockLogin } from '@/lib/api';

describe('LoginPage', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('renders the login form with email and password fields', () => {
    render(
      <I18nProvider initialLocale="de">
        <ToastProvider>
          <LoginPage />
        </ToastProvider>
      </I18nProvider>
    );

    expect(screen.getByTestId('login-form')).toBeInTheDocument();
    expect(screen.getByTestId('email-input')).toBeInTheDocument();
    expect(screen.getByTestId('password-input')).toBeInTheDocument();
    expect(screen.getByTestId('login-button')).toBeInTheDocument();
  });

  it('shows validation errors for empty fields', async () => {
    render(
      <I18nProvider initialLocale="de">
        <ToastProvider>
          <LoginPage />
        </ToastProvider>
      </I18nProvider>
    );

    const submitButton = screen.getByTestId('login-button');
    fireEvent.click(submitButton);

    await waitFor(() => {
      expect(screen.getByText('E-Mail-Adresse ist erforderlich')).toBeInTheDocument();
      expect(screen.getByText('Passwort ist erforderlich')).toBeInTheDocument();
    });
  });

  it('calls login API on submit with valid credentials', async () => {
    (mockLogin as any).mockResolvedValue({
      access_token: 'fake-token',
      refresh_token: 'fake-refresh',
      token_type: 'bearer',
      expires_in: 900,
    });

    render(
      <I18nProvider initialLocale="de">
        <ToastProvider>
          <LoginPage />
        </ToastProvider>
      </I18nProvider>
    );

    const emailInput = screen.getByTestId('email-input');
    const passwordInput = screen.getByTestId('password-input');
    const submitButton = screen.getByTestId('login-button');

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

    await waitFor(() => {
      expect(mockLogin).toHaveBeenCalledWith('admin@test.com', 'Admin12345!');
    });
  });

  it('shows error toast on login failure', async () => {
    (mockLogin as any).mockRejectedValue({
      error: { code: 'INVALID_CREDENTIALS', message: 'Invalid email or password' },
    });

    render(
      <I18nProvider initialLocale="de">
        <ToastProvider>
          <LoginPage />
        </ToastProvider>
      </I18nProvider>
    );

    const emailInput = screen.getByTestId('email-input');
    const passwordInput = screen.getByTestId('password-input');
    const submitButton = screen.getByTestId('login-button');

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

    await waitFor(() => {
      const toastContainer = screen.getByTestId('toast-container');
      expect(toastContainer).toHaveTextContent('Invalid email or password');
    });
  });

  it('renders with English locale when selected', () => {
    render(
      <I18nProvider initialLocale="en">
        <ToastProvider>
          <LoginPage />
        </ToastProvider>
      </I18nProvider>
    );

    expect(screen.getAllByText('Sign In').length).toBeGreaterThanOrEqual(1);
    expect(screen.getByText('Email Address')).toBeInTheDocument();
    expect(screen.getByText('Password')).toBeInTheDocument();
  });
});
