import { describe, it, expect, beforeEach, vi } from 'vitest';
import { useAuthStore } from '@/stores/auth';
import { useUIStore } from '@/stores/ui';
import { useChatStore } from '@/stores/chat';
import { useLibraryStore } from '@/stores/library';
import { usePlayerStore } from '@/stores/player';

// Mock localStorage
const localStorageMock = {
  getItem: vi.fn(),
  setItem: vi.fn(),
  removeItem: vi.fn(),
  clear: vi.fn(),
};
Object.defineProperty(window, 'localStorage', {
  value: localStorageMock,
});

describe('Zustand Stores', () => {
  beforeEach(() => {
    // Reset stores before each test
    useAuthStore.getState().logout();
    useUIStore.getState().clearNotifications();
    useChatStore.getState().setConnected(false);
    useLibraryStore.getState().clearItems();
    usePlayerStore.getState().clearQueue();
  });

  describe('Auth Store', () => {
    it('should have initial state', () => {
      const state = useAuthStore.getState();
      expect(state.user).toBeNull();
      expect(state.isAuthenticated).toBe(false);
      // isLoading peut être true si le store est en cours de rehydration
      expect(typeof state.isLoading).toBe('boolean');
      expect(state.error).toBeNull();
    });

    it('should handle login action', () => {
      const { login } = useAuthStore.getState();
      expect(typeof login).toBe('function');
    });

    it('should handle logout action', () => {
      const { logout } = useAuthStore.getState();
      expect(typeof logout).toBe('function');
    });

    it('should handle clearError action', () => {
      const { clearError } = useAuthStore.getState();
      expect(typeof clearError).toBe('function');
    });

    it('should set user and authentication state on login', () => {
      const mockUser = {
        id: 1,
        username: 'testuser',
        email: 'test@example.com',
        first_name: 'Test',
        last_name: 'User',
        role: 'user' as const,
        is_active: true,
        is_verified: true,
        created_at: '2024-01-01T00:00:00Z',
      };

      // Mock the login function to simulate successful login
      vi.spyOn(useAuthStore.getState(), 'login').mockImplementation(
        async () => {
          useAuthStore.setState({
            user: mockUser,
            isAuthenticated: true,
            isLoading: false,
            error: null,
          });
        }
      );

      expect(useAuthStore.getState().isAuthenticated).toBe(false);
    });

    it('should clear user and authentication state on logout', () => {
      const { logout } = useAuthStore.getState();

      // Set initial state
      useAuthStore.setState({
        user: { id: 1, username: 'test', email: 'test@example.com' } as any,
        isAuthenticated: true,
      });

      logout();

      const state = useAuthStore.getState();
      expect(state.user).toBeNull();
      expect(state.isAuthenticated).toBe(false);
    });
  });

  describe('UI Store', () => {
    it('should have initial state', () => {
      const state = useUIStore.getState();
      expect(state.theme).toBe('system');
      expect(state.language).toBe('en');
      expect(state.sidebarOpen).toBe(true);
      expect(state.notifications).toEqual([]);
    });

    it('should handle theme changes', () => {
      const { setTheme } = useUIStore.getState();
      setTheme('dark');
      expect(useUIStore.getState().theme).toBe('dark');
    });

    it('should handle language changes', () => {
      const { setLanguage } = useUIStore.getState();
      setLanguage('fr');
      expect(useUIStore.getState().language).toBe('fr');
    });

    it('should handle sidebar toggle', () => {
      const { setSidebarOpen } = useUIStore.getState();
      setSidebarOpen(false);
      expect(useUIStore.getState().sidebarOpen).toBe(false);
    });
  });

  describe('Chat Store', () => {
    it('should have initial state', () => {
      const state = useChatStore.getState();
      expect(state.conversations).toEqual([]);
      expect(state.currentConversation).toBeNull();
      expect(state.messages).toEqual({});
      expect(state.typingUsers).toEqual({});
      expect(state.isConnected).toBe(false);
      expect(state.isLoading).toBe(false);
      expect(state.error).toBeNull();
    });

    it('should handle conversation actions', () => {
      const { setConversations, setCurrentConversation } =
        useChatStore.getState();
      expect(typeof setConversations).toBe('function');
      expect(typeof setCurrentConversation).toBe('function');
    });

    it('should handle message actions', () => {
      const { addMessage, sendMessage } = useChatStore.getState();
      expect(typeof addMessage).toBe('function');
      expect(typeof sendMessage).toBe('function');
    });
  });

  describe('Library Store', () => {
    it('should have initial state', () => {
      const state = useLibraryStore.getState();
      expect(state.items).toEqual([]);
      expect(state.favorites).toEqual([]);
      expect(state.isLoading).toBe(false);
      expect(state.error).toBeNull();
    });

    it('should handle library actions', () => {
      const { fetchItems, uploadFile, toggleFavorite } =
        useLibraryStore.getState();
      expect(typeof fetchItems).toBe('function');
      expect(typeof uploadFile).toBe('function');
      expect(typeof toggleFavorite).toBe('function');
    });
  });

  describe('Player Store', () => {
    it('should have initial state', () => {
      const state = usePlayerStore.getState();
      expect(state.currentTrack).toBeNull();
      expect(state.isPlaying).toBe(false);
      expect(state.currentTime).toBe(0);
      expect(state.duration).toBe(0);
      expect(state.volume).toBe(100);
      expect(state.muted).toBe(false);
      expect(state.queue).toEqual([]);
      expect(state.currentIndex).toBe(-1);
      expect(state.repeat).toBe('off');
      expect(state.shuffle).toBe(false);
    });

    it('should handle play action', () => {
      const { play } = usePlayerStore.getState();
      const mockTrack = {
        id: '1',
        title: 'Test Track',
        artist: 'Test Artist',
        duration: 180,
        url: 'https://example.com/track.mp3',
      } as any;
      
      play(mockTrack);
      const state = usePlayerStore.getState();
      expect(state.currentTrack).toEqual(mockTrack);
      expect(state.isPlaying).toBe(true);
    });

    it('should handle pause action', () => {
      const { pause } = usePlayerStore.getState();
      pause();
      expect(usePlayerStore.getState().isPlaying).toBe(false);
    });

    it('should handle resume action', () => {
      const { resume } = usePlayerStore.getState();
      resume();
      expect(usePlayerStore.getState().isPlaying).toBe(true);
    });

    it('should handle volume changes', () => {
      const { setVolume } = usePlayerStore.getState();
      setVolume(50);
      expect(usePlayerStore.getState().volume).toBe(50);
    });

    it('should handle toggle mute', () => {
      const { toggleMute } = usePlayerStore.getState();
      const initialMuted = usePlayerStore.getState().muted;
      toggleMute();
      expect(usePlayerStore.getState().muted).toBe(!initialMuted);
    });

    it('should handle add to queue', () => {
      const { addToQueue } = usePlayerStore.getState();
      const mockTrack = {
        id: '1',
        title: 'Test Track',
      } as any;
      
      addToQueue(mockTrack);
      const state = usePlayerStore.getState();
      expect(state.queue).toHaveLength(1);
      expect(state.queue[0]).toEqual(mockTrack);
    });

    it('should handle clear queue', () => {
      const { addToQueue, clearQueue } = usePlayerStore.getState();
      const mockTrack = { id: '1' } as any;
      
      addToQueue(mockTrack);
      clearQueue();
      
      const state = usePlayerStore.getState();
      expect(state.queue).toEqual([]);
      expect(state.currentIndex).toBe(-1);
      expect(state.currentTrack).toBeNull();
    });

    it('should handle toggle shuffle', () => {
      const { toggleShuffle } = usePlayerStore.getState();
      const initialShuffle = usePlayerStore.getState().shuffle;
      toggleShuffle();
      expect(usePlayerStore.getState().shuffle).toBe(!initialShuffle);
    });

    it('should handle set repeat', () => {
      const { setRepeat } = usePlayerStore.getState();
      setRepeat('playlist');
      expect(usePlayerStore.getState().repeat).toBe('playlist');
    });
  });
});
