import { describe, it, expect, beforeEach, vi } from 'vitest';
import { renderHook, act } from '@testing-library/react';
import { useActiveClub } from '../useActiveClub';

const mockUseSession = vi.fn();

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

describe('useActiveClub', () => {
  let localStorageData: Record<string, string> = {};

  beforeEach(() => {
    localStorageData = {};
    
    mockUseSession.mockReturnValue({
      data: {
        user: {
          id: '1',
          name: 'Test User',
          email: 'test@example.com',
          clubs: {
            'club-1': 'owner',
            'club-2': 'member',
            'club-3': 'admin',
          },
        },
        accessToken: 'mock-token',
        expires: '2099-01-01',
      },
      status: 'authenticated',
    });
    
    (localStorage.getItem as ReturnType<typeof vi.fn>).mockImplementation((key: string) => {
      return localStorageData[key] || null;
    });
    
    (localStorage.setItem as ReturnType<typeof vi.fn>).mockImplementation((key: string, value: string) => {
      localStorageData[key] = value;
    });
    
    (localStorage.clear as ReturnType<typeof vi.fn>).mockImplementation(() => {
      localStorageData = {};
    });
  });

  it('should return first club from session when localStorage is empty', () => {
    const { result } = renderHook(() => useActiveClub());

    expect(result.current.activeClubId).toBe('club-1');
    expect(result.current.role).toBe('owner');
  });

  it('should return active club from localStorage if valid', () => {
    localStorageData['activeClubId'] = 'club-2';

    const { result } = renderHook(() => useActiveClub());

    expect(result.current.activeClubId).toBe('club-2');
    expect(result.current.role).toBe('member');
  });

  it('should fallback to first club if localStorage contains invalid club ID', () => {
    localStorageData['activeClubId'] = 'invalid-club';

    const { result } = renderHook(() => useActiveClub());

    expect(result.current.activeClubId).toBe('club-1');
    expect(result.current.role).toBe('owner');
  });

  it('should update localStorage when setActiveClub is called', () => {
    const { result } = renderHook(() => useActiveClub());

    act(() => {
      result.current.setActiveClub('club-3');
    });

    expect(result.current.activeClubId).toBe('club-3');
    expect(result.current.role).toBe('admin');
    expect(localStorageData['activeClubId']).toBe('club-3');
  });

  it('should return null when no session exists', () => {
    mockUseSession.mockReturnValueOnce({
      data: null,
      status: 'unauthenticated',
    });

    const { result } = renderHook(() => useActiveClub());

    expect(result.current.activeClubId).toBeNull();
    expect(result.current.role).toBeNull();
  });

  it('should return null when user has no clubs', () => {
    mockUseSession.mockReturnValueOnce({
      data: {
        user: {
          id: '1',
          name: 'Test User',
          clubs: {},
        },
        accessToken: 'mock-token',
        expires: '2099-01-01',
      },
      status: 'authenticated',
    });

    const { result } = renderHook(() => useActiveClub());

    expect(result.current.activeClubId).toBeNull();
    expect(result.current.role).toBeNull();
  });

  it('should return all clubs from session', () => {
    const { result } = renderHook(() => useActiveClub());

    expect(result.current.clubs).toEqual({
      'club-1': 'owner',
      'club-2': 'member',
      'club-3': 'admin',
    });
  });
});
