
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { LoginPage } from '../Login';
import * as api from '../api';

// Mock API
vi.mock('../api', () => ({
    apiLogin: vi.fn(),
    apiRegister: vi.fn(),
}));

describe('LoginPage Component', () => {
    const mockOnLogin = vi.fn();

    beforeEach(() => {
        vi.clearAllMocks();
        mockOnLogin.mockClear();
    });

    it('renders login form by default', () => {
        render(<LoginPage onLogin={mockOnLogin} />);
        expect(screen.getByText(/scrum-manager/i)).toBeInTheDocument(); // Logo check
        expect(screen.getByLabelText(/email/i)).toBeInTheDocument();
        expect(screen.getByLabelText(/password/i)).toBeInTheDocument();
        expect(screen.getByRole('button', { name: /sign in/i })).toBeInTheDocument();
        expect(screen.getByText(/no account\? register here/i)).toBeInTheDocument();
    });


    it('switches to register mode', async () => {
        render(<LoginPage onLogin={mockOnLogin} />);
        await userEvent.click(screen.getByText(/no account\? register here/i));

        expect(screen.getByLabelText(/name/i)).toBeInTheDocument();
        expect(screen.getByRole('button', { name: /create account/i })).toBeInTheDocument();
        expect(screen.getByText(/already have an account\? sign in/i)).toBeInTheDocument();
    });

    it('handles successful login', async () => {
        const mockUser = { id: 'u1', name: 'Test', email: 'test@example.com', role: 'emp', dept: 'dev' };
        (api.apiLogin as any).mockResolvedValue(mockUser);

        render(<LoginPage onLogin={mockOnLogin} />);

        await userEvent.type(screen.getByLabelText(/email/i), 'test@example.com');
        await userEvent.type(screen.getByLabelText(/password/i), 'password');
        await userEvent.click(screen.getByRole('button', { name: /sign in/i }));

        await waitFor(() => {
            expect(api.apiLogin).toHaveBeenCalledWith('test@example.com', 'password');
            expect(mockOnLogin).toHaveBeenCalledWith(mockUser);
        });
    });

    it('handles login failure', async () => {
        (api.apiLogin as any).mockRejectedValue(new Error('Invalid credentials'));

        render(<LoginPage onLogin={mockOnLogin} />);

        await userEvent.type(screen.getByLabelText(/email/i), 'wrong@example.com');
        await userEvent.type(screen.getByLabelText(/password/i), 'wrongpass');
        await userEvent.click(screen.getByRole('button', { name: /sign in/i }));

        await waitFor(() => {
            expect(screen.getByText(/invalid credentials/i)).toBeInTheDocument();
        });
        expect(mockOnLogin).not.toHaveBeenCalled();
    });

    it('handles successful registration', async () => {
        const mockUser = { id: 'u2', name: 'New User', email: 'new@example.com', role: 'employee', dept: 'dev' };
        (api.apiRegister as any).mockResolvedValue(mockUser);

        render(<LoginPage onLogin={mockOnLogin} />);
        await userEvent.click(screen.getByText(/no account\? register here/i));

        await userEvent.type(screen.getByLabelText(/name/i), 'New User');
        await userEvent.type(screen.getByLabelText(/email/i), 'new@example.com');
        await userEvent.type(screen.getByLabelText(/password/i), 'password123');
        await userEvent.type(screen.getByLabelText(/department/i), 'DevOps'); // "e.g. Backend..." placeholder, checking label

        await userEvent.click(screen.getByRole('button', { name: /create account/i }));

        await waitFor(() => {
            expect(api.apiRegister).toHaveBeenCalledWith({
                name: 'New User',
                email: 'new@example.com',
                password: 'password123',
                role: 'employee', // Default
                dept: 'DevOps'
            });
            expect(mockOnLogin).toHaveBeenCalledWith(mockUser);
        });
    });

    it('validates registration inputs', async () => {
        render(<LoginPage onLogin={mockOnLogin} />);
        await userEvent.click(screen.getByText(/no account\? register here/i));

        await userEvent.click(screen.getByRole('button', { name: /create account/i }));

        expect(screen.getByText(/all fields are required/i)).toBeInTheDocument();
        expect(api.apiRegister).not.toHaveBeenCalled();
    });
});
