import { render, screen } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import { MemoryRouter, Routes, Route } from 'react-router-dom';
import ProtectedRoute from '../components/ProtectedRoute';

const mockUseAuth = vi.fn();

vi.mock('../context/AuthContext', () => ({
  useAuth: () => mockUseAuth(),
}));

const renderProtected = (user, allowedRoles, initialPath = '/protected') =>
  render(
    <MemoryRouter initialEntries={[initialPath]}>
      <Routes>
        <Route path="/login"     element={<div>Login Page</div>} />
        <Route path="/dashboard" element={<div>Dashboard</div>} />
        <Route path="/admin"     element={<div>Admin Page</div>} />
        <Route element={<ProtectedRoute allowedRoles={allowedRoles} />}>
          <Route path="/protected" element={<div>Protected Content</div>} />
        </Route>
      </Routes>
    </MemoryRouter>
  );

describe('ProtectedRoute', () => {
  it('redirects unauthenticated users to /login', () => {
    mockUseAuth.mockReturnValue({ user: null });
    renderProtected(null, ['client']);
    expect(screen.getByText('Login Page')).toBeInTheDocument();
  });

  it('renders the outlet for a user with the correct role', () => {
    mockUseAuth.mockReturnValue({ user: { role: 'client' } });
    renderProtected({ role: 'client' }, ['client']);
    expect(screen.getByText('Protected Content')).toBeInTheDocument();
  });

  it('redirects a client away from an admin-only route to /dashboard', () => {
    mockUseAuth.mockReturnValue({ user: { role: 'client' } });
    renderProtected({ role: 'client' }, ['admin']);
    expect(screen.getByText('Dashboard')).toBeInTheDocument();
  });

  it('redirects an admin away from a client-only route to /admin', () => {
    mockUseAuth.mockReturnValue({ user: { role: 'admin' } });
    renderProtected({ role: 'admin' }, ['client']);
    expect(screen.getByText('Admin Page')).toBeInTheDocument();
  });
});
