import { render, screen } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { AuthGuard } from '../auth-guard';
import { useSession } from 'next-auth/react';
import { useTenant } from '../../contexts/tenant-context';
import { useRouter } from 'next/navigation';

vi.mock('next-auth/react', () => ({
  useSession: vi.fn(),
}));

vi.mock('../../contexts/tenant-context', () => ({
  useTenant: vi.fn(),
}));

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

describe('AuthGuard', () => {
  const mockPush = vi.fn();

  beforeEach(() => {
    vi.clearAllMocks();
    (useRouter as ReturnType<typeof vi.fn>).mockReturnValue({ push: mockPush });
  });

  it('renders loading state when session is loading', () => {
    (useSession as ReturnType<typeof vi.fn>).mockReturnValue({ data: null, status: 'loading' });
    (useTenant as ReturnType<typeof vi.fn>).mockReturnValue({ activeClubId: null, clubs: [], setActiveClub: vi.fn(), userRole: null });
    
    render(<AuthGuard><div>Protected</div></AuthGuard>);
    expect(screen.getByText('Loading...')).toBeInTheDocument();
  });

  it('redirects to /login when unauthenticated', () => {
    (useSession as ReturnType<typeof vi.fn>).mockReturnValue({ data: null, status: 'unauthenticated' });
    (useTenant as ReturnType<typeof vi.fn>).mockReturnValue({ activeClubId: null, clubs: [], setActiveClub: vi.fn(), userRole: null });
    
    render(<AuthGuard><div>Protected</div></AuthGuard>);
    expect(mockPush).toHaveBeenCalledWith('/login');
  });

  it('shows Contact admin when 0 clubs', () => {
    (useSession as ReturnType<typeof vi.fn>).mockReturnValue({ data: { user: {} }, status: 'authenticated' });
    (useTenant as ReturnType<typeof vi.fn>).mockReturnValue({ activeClubId: null, clubs: [], setActiveClub: vi.fn(), userRole: null });
    
    render(<AuthGuard><div>Protected</div></AuthGuard>);
    expect(screen.getByText('Contact admin to get access to a club')).toBeInTheDocument();
  });

  it('auto-selects when 1 club and no active club', () => {
    const mockSetActiveClub = vi.fn();
    (useSession as ReturnType<typeof vi.fn>).mockReturnValue({ data: { user: {} }, status: 'authenticated' });
    (useTenant as ReturnType<typeof vi.fn>).mockReturnValue({ 
      activeClubId: null, 
      clubs: [{ id: 'club-1', name: 'Club 1' }], 
      setActiveClub: mockSetActiveClub, 
      userRole: null 
    });
    
    render(<AuthGuard><div>Protected</div></AuthGuard>);
    expect(mockSetActiveClub).toHaveBeenCalledWith('club-1');
  });

  it('redirects to /select-club when multiple clubs and no active club', () => {
    (useSession as ReturnType<typeof vi.fn>).mockReturnValue({ data: { user: {} }, status: 'authenticated' });
    (useTenant as ReturnType<typeof vi.fn>).mockReturnValue({ 
      activeClubId: null, 
      clubs: [{ id: 'club-1', name: 'Club 1' }, { id: 'club-2', name: 'Club 2' }], 
      setActiveClub: vi.fn(), 
      userRole: null 
    });
    
    render(<AuthGuard><div>Protected</div></AuthGuard>);
    expect(mockPush).toHaveBeenCalledWith('/select-club');
  });

  it('renders children when authenticated and active club is set', () => {
    (useSession as ReturnType<typeof vi.fn>).mockReturnValue({ data: { user: {} }, status: 'authenticated' });
    (useTenant as ReturnType<typeof vi.fn>).mockReturnValue({ 
      activeClubId: 'club-1', 
      clubs: [{ id: 'club-1', name: 'Club 1' }], 
      setActiveClub: vi.fn(), 
      userRole: 'admin' 
    });
    
    render(<AuthGuard><div>Protected Content</div></AuthGuard>);
    expect(screen.getByText('Protected Content')).toBeInTheDocument();
  });
});
