import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import LoginPage from '../app/(auth)/login/page';
import { useAuthStore } from '../stores/auth-store';

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

// Mock useTranslation
vi.mock('../shared/hooks/use-translation', () => ({
  useTranslation: () => ({
    t: (key: string) => key,
  }),
}));

// Mock auth store
vi.mock('../stores/auth-store', () => ({
  useAuthStore: vi.fn(),
}));

describe('Auth Flow Integration', () => {
  let queryClient: QueryClient;
  let mockAuthStore: any;

  beforeEach(() => {
    queryClient = new QueryClient({
      defaultOptions: {
        queries: { retry: false },
        mutations: { retry: false },
      },
    });

    mockAuthStore = {
      login: vi.fn(),
      isLoading: false,
      user: null,
      isAuthenticated: false,
    };

    (useAuthStore as any).mockReturnValue(mockAuthStore);
  });

  const renderLoginPage = () => {
    return render(
      <QueryClientProvider client={queryClient}>
        <LoginPage />
      </QueryClientProvider>
    );
  };

  describe('Login Page', () => {
    it('renders login form with required fields', () => {
      renderLoginPage();

      expect(screen.getByLabelText(/email/i)).toBeInTheDocument();
      expect(screen.getByLabelText(/password/i)).toBeInTheDocument();
      expect(screen.getByRole('button', { name: /login/i })).toBeInTheDocument();
      expect(screen.getByText(/remember me/i)).toBeInTheDocument();
    });

    it('shows validation errors for empty fields', async () => {
      renderLoginPage();

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

      await waitFor(() => {
        expect(screen.getByText(/validation\.emailRequired/i)).toBeInTheDocument();
        expect(screen.getByText(/validation\.password/i)).toBeInTheDocument();
      });
    });

    it('shows validation error for invalid email', async () => {
      renderLoginPage();

      const emailInput = screen.getByLabelText(/email/i);
      const passwordInput = screen.getByLabelText(/password/i);
      const submitButton = screen.getByRole('button', { name: /login/i });

      fireEvent.change(emailInput, { target: { value: 'invalid-email' } });
      fireEvent.change(passwordInput, { target: { value: 'password123' } });
      fireEvent.click(submitButton);

      await waitFor(() => {
        expect(screen.getByText(/validation\.email/i)).toBeInTheDocument();
      });
    });

    it('calls login function on valid form submission', async () => {
      mockAuthStore.login.mockResolvedValue(undefined);

      renderLoginPage();

      const emailInput = screen.getByLabelText(/email/i);
      const passwordInput = screen.getByLabelText(/password/i);
      const submitButton = screen.getByRole('button', { name: /login/i });

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

      await waitFor(() => {
        expect(mockAuthStore.login).toHaveBeenCalledWith('test@example.com', 'password123');
      });
    });

    it('shows loading state during login', async () => {
      mockAuthStore.isLoading = true;
      mockAuthStore.login.mockImplementation(() => new Promise(() => {})); // Never resolves

      renderLoginPage();

      const emailInput = screen.getByLabelText(/email/i);
      const passwordInput = screen.getByLabelText(/password/i);
      const submitButton = screen.getByRole('button', { name: /login/i });

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

      expect(screen.getByText(/auth\.login\.loginButtonLoading/i)).toBeInTheDocument();
      expect(submitButton).toBeDisabled();
    });

    it('shows error message on login failure', async () => {
      const errorMessage = 'Invalid credentials';
      mockAuthStore.login.mockRejectedValue(new Error(errorMessage));

      renderLoginPage();

      const emailInput = screen.getByLabelText(/email/i);
      const passwordInput = screen.getByLabelText(/password/i);
      const submitButton = screen.getByRole('button', { name: /login/i });

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

      await waitFor(() => {
        expect(screen.getByText(errorMessage)).toBeInTheDocument();
      });
    });
  });
});