import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { I18nextProvider } from 'react-i18next';
import LoginPage from '@/features/auth/pages/LoginPage';
import { LocaleProvider } from '@/app/providers/LocaleProvider';
import { ThemeProvider } from '@/app/providers/ThemeProvider';
import { authService } from '@/features/auth/services/authService';
import i18n from '@/locales/i18n';

vi.mock('@/features/auth/services/authService', () => ({
  authService: {
    ensureCsrfCookie: vi.fn(),
    requestOtp: vi.fn(),
    verifyOtp: vi.fn(),
    requestMagicLink: vi.fn(),
    fetchMe: vi.fn(),
    logout: vi.fn(),
  },
}));

const renderLoginPage = () =>
  render(
    <MemoryRouter>
      <I18nextProvider i18n={i18n}>
        <ThemeProvider>
          <LocaleProvider>
            <LoginPage />
          </LocaleProvider>
        </ThemeProvider>
      </I18nextProvider>
    </MemoryRouter>,
  );

describe('LoginPage', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    vi.mocked(authService.ensureCsrfCookie).mockResolvedValue();
    vi.mocked(authService.requestOtp).mockResolvedValue({
      message: 'ok',
      retry_after_seconds: 60,
    });
  });

  it('requests OTP when email is submitted', async () => {
    renderLoginPage();

    fireEvent.change(screen.getByPlaceholderText(/you@mountainview-eg.com/i), {
      target: { value: 'agent@mountainview-eg.com' },
    });
    fireEvent.click(screen.getByRole('button', { name: /send login code/i }));

    await waitFor(() => {
      expect(authService.requestOtp).toHaveBeenCalledWith('agent@mountainview-eg.com');
    });

    expect(await screen.findAllByRole('textbox', { name: /digit \d of 6/i })).toHaveLength(6);
  });

  it('shows resend countdown after OTP is requested', async () => {
    renderLoginPage();

    fireEvent.change(screen.getByPlaceholderText(/you@mountainview-eg.com/i), {
      target: { value: 'agent@mountainview-eg.com' },
    });
    fireEvent.click(screen.getByRole('button', { name: /send login code/i }));

    expect(await screen.findByRole('button', { name: /resend in/i })).toBeDisabled();
  });

  it('disables verify button until OTP has six digits', async () => {
    renderLoginPage();

    fireEvent.change(screen.getByPlaceholderText(/you@mountainview-eg.com/i), {
      target: { value: 'agent@mountainview-eg.com' },
    });
    fireEvent.click(screen.getByRole('button', { name: /send login code/i }));

    const verifyButton = await screen.findByRole('button', { name: /verify & sign in/i });
    expect(verifyButton).toBeDisabled();

    const digitInputs = screen.getAllByRole('textbox', { name: /digit \d of 6/i });
    '123456'.split('').forEach((digit, index) => {
      fireEvent.change(digitInputs[index], { target: { value: digit } });
    });

    expect(verifyButton).not.toBeDisabled();
  });
});
