/**
 * Store Selectors
 * FE-STATE-008: Optimize state selectors to prevent unnecessary re-renders
 *
 * Provides optimized selectors for Zustand stores to prevent unnecessary re-renders.
 * Use these selectors instead of accessing the entire store.
 */

// CRITICAL FIX: Ensure React.Children is available before importing zustand/react/shallow
// The issue is that with-selector accesses React.Children at module import time
// We need to ensure React is fully initialized before this module is evaluated

// CRITICAL: ALL imports must be at the top to avoid "Cannot access before initialization" errors
// Import React FIRST to ensure it's available before useShallow
import React from 'react';
import { useShallow } from 'zustand/react/shallow';
import { useQueryClient } from '@tanstack/react-query';
import { useAuthStore } from '@/features/auth/store/authStore';
import { useUser } from '@/features/auth/hooks/useUser';
import { useUIStore, type UIStore } from '@/stores/ui';
import { useLibraryStore, type LibraryStore } from '@/stores/library';
import { useChatStore, type ChatStore } from '@/stores/chat';
import {
  useLibraryItems as useLibraryItemsQuery,
  useLibraryFavorites as useLibraryFavoritesQuery,
  libraryQueryKeys,
  type LibraryItemsParams,
} from '@/features/library/hooks/useLibraryItems';
import type { User, LibraryItem, ChatMessage, Conversation } from '@/types';
import type { ApiError } from '@/types/api';

// CRITICAL FIX: Make React available globally AFTER all imports
// This ensures React.Children exists before any other module tries to access it
// NOTE: This runs after imports are evaluated, so React should already be loaded
if (typeof window !== 'undefined') {
  (window as any).React = React;
  // Verify React.Children exists
  if (React && !React.Children) {
    console.error('[CRITICAL] React.Children not available after import');
  }
}

/**
 * FE-STATE-008: Optimized selectors for AuthStore
 *
 * These hooks only re-render when the selected values actually change.
 * 
 * Action 4.1.1.3: Migrated to use React Query hook instead of Zustand store
 */
export function useAuthUser(): User | null {
  const { data: user } = useUser();
  return user ?? null;
}

export function useAuthStatus(): {
  isAuthenticated: boolean;
  isLoading: boolean;
  error: ApiError | null;
} {
  return useAuthStore(
    useShallow((state) => ({
      isAuthenticated: state.isAuthenticated,
      isLoading: state.isLoading,
      error: state.error,
    })),
  );
}

export function useAuthActions() {
  return useAuthStore(
    useShallow((state) => ({
      login: state.login,
      register: state.register,
      logout: state.logout,
      refreshUser: state.refreshUser,
      checkAuthStatus: state.checkAuthStatus,
      clearError: state.clearError,
      setLoading: state.setLoading,
    })),
  );
}

/**
 * FE-STATE-008: Optimized selectors for UIStore
 */
export function useUITheme(): 'light' | 'dark' | 'system' {
  return useUIStore(useShallow((state: UIStore) => state.theme));
}

export function useUILanguage(): 'en' | 'fr' {
  return useUIStore(useShallow((state: UIStore) => state.language));
}

export function useUISidebar() {
  return useUIStore(
    useShallow((state: UIStore) => ({
      sidebarOpen: state.sidebarOpen,
      setSidebarOpen: state.setSidebarOpen,
    })),
  );
}

export function useUINotifications() {
  return useUIStore(
    useShallow((state: UIStore) => ({
      notifications: state.notifications,
      addNotification: state.addNotification,
      removeNotification: state.removeNotification,
      markNotificationAsRead: state.markNotificationAsRead,
      clearNotifications: state.clearNotifications,
    })),
  );
}

export function useUIActions() {
  return useUIStore(
    useShallow((state: UIStore) => ({
      setTheme: state.setTheme,
      setLanguage: state.setLanguage,
      setSidebarOpen: state.setSidebarOpen,
    })),
  );
}

/**
 * FE-STATE-008: Optimized selectors for LibraryStore
 * FE-STATE-009: Convert normalized state to arrays for compatibility
 *
 * NOTE: These selectors now use React Query hooks instead of Zustand store.
 * They maintain the same interface for backward compatibility.
 */
export function useLibraryItems(
  params: LibraryItemsParams = {},
): LibraryItem[] {
  const { data } = useLibraryItemsQuery(params);
  return data?.items ?? [];
}

export function useLibraryFavorites(): LibraryItem[] {
  const { data } = useLibraryFavoritesQuery();
  return data ?? [];
}

/**
 * FE-STATE-009: Get normalized state directly (for advanced use cases)
 * 
 * @deprecated Domain data (items, favorites) have been migrated to React Query.
 * Use useLibraryItems() or useLibraryFavorites() instead.
 */
export function useLibraryItemsNormalized() {
  // Domain data removed from store - return empty normalized state for backward compatibility
  return { byId: {}, allIds: [] };
}

/**
 * @deprecated Domain data (items, favorites) have been migrated to React Query.
 * Use useLibraryFavorites() instead.
 */
export function useLibraryFavoritesNormalized() {
  // Domain data removed from store - return empty normalized state for backward compatibility
  return { byId: {}, allIds: [] };
}

export function useLibraryFilters() {
  return useLibraryStore(
    useShallow((state: LibraryStore) => ({
      filters: state.filters,
      setFilters: state.setFilters,
    })),
  );
}

export function useLibraryPagination(params: LibraryItemsParams = {}) {
  const { data } = useLibraryItemsQuery(params);
  return {
    page: data?.page ?? 1,
    limit: data?.limit ?? 20,
    total: data?.total ?? 0,
    // Map snake_case from API to camelCase for backward compatibility
    hasNext: data?.has_next ?? false,
    hasPrev: data?.has_prev ?? false,
    // Also provide snake_case for API compatibility
    has_next: data?.has_next ?? false,
    has_prev: data?.has_prev ?? false,
  };
}

export function useLibraryStatus(): {
  isLoading: boolean;
  error: ApiError | null;
} {
  const itemsQuery = useLibraryItemsQuery({});
  const favoritesQuery = useLibraryFavoritesQuery();

  return {
    isLoading: itemsQuery.isLoading || favoritesQuery.isLoading,
    error: (itemsQuery.error || favoritesQuery.error) as ApiError | null,
  };
}

export function useLibraryActions() {
  const queryClient = useQueryClient();

  return {
    fetchItems: async (params?: LibraryItemsParams) => {
      await queryClient.refetchQueries({
        queryKey: libraryQueryKeys.items(params),
      });
    },
    fetchFavorites: async () => {
      await queryClient.refetchQueries({
        queryKey: libraryQueryKeys.favorites(),
      });
    },
    uploadFile: async (
      file: File,
      metadata: { title: string; description?: string },
    ) => {
      // TODO: Migrate to React Query mutation with optimistic update
      // For now, call API and invalidate queries
      const { apiClient } = await import('@/services/api/client');
      const formData = new FormData();
      formData.append('file', file);
      formData.append('title', metadata.title);
      if (metadata.description) {
        formData.append('description', metadata.description);
      }
      await apiClient.post('/tracks', formData, {
        headers: { 'Content-Type': 'multipart/form-data' },
      });
      await queryClient.invalidateQueries({ queryKey: libraryQueryKeys.all });
    },
    toggleFavorite: async (itemId: string) => {
      // TODO: Migrate to React Query mutation with optimistic update
      // For now, call API and invalidate queries
      const { apiClient } = await import('@/services/api/client');
      await apiClient.post(`/tracks/${itemId}/favorite`);
      await queryClient.invalidateQueries({ queryKey: libraryQueryKeys.all });
    },
    deleteItem: async (itemId: string) => {
      // TODO: Migrate to React Query mutation with optimistic update
      // For now, call API and invalidate queries
      const { apiClient } = await import('@/services/api/client');
      await apiClient.delete(`/tracks/${itemId}`);
      await queryClient.invalidateQueries({ queryKey: libraryQueryKeys.all });
    },
    clearItems: () => {
      // Invalidate all library queries instead of clearing store
      queryClient.invalidateQueries({ queryKey: libraryQueryKeys.all });
    },
  };
}

/**
 * FE-STATE-008: Optimized selectors for ChatStore
 */
export function useChatConversations(): Conversation[] {
  return useChatStore(useShallow((state: ChatStore) => state.conversations));
}

export function useChatCurrentConversation(): Conversation | null {
  return useChatStore(
    useShallow((state: ChatStore) => state.currentConversation),
  );
}

export function useChatMessages(conversationId: string): ChatMessage[] {
  return useChatStore(
    useShallow((state: ChatStore) => state.messages[conversationId] || []),
  );
}

export function useChatTypingUsers(conversationId: string): string[] {
  return useChatStore(
    useShallow((state: ChatStore) => state.typingUsers[conversationId] || []),
  );
}

export function useChatConnection(): {
  isConnected: boolean;
  isLoading: boolean;
  error: string | null;
} {
  return useChatStore(
    useShallow((state: ChatStore) => ({
      isConnected: state.isConnected,
      isLoading: state.isLoading,
      error: state.error,
    })),
  );
}

export function useChatActions() {
  return useChatStore(
    useShallow((state: ChatStore) => ({
      setConversations: state.setConversations,
      setCurrentConversation: state.setCurrentConversation,
      addMessage: state.addMessage,
      updateMessage: state.updateMessage,
      removeMessage: state.removeMessage,
      setMessages: state.setMessages,
      setTypingUsers: state.setTypingUsers,
      addTypingUser: state.addTypingUser,
      removeTypingUser: state.removeTypingUser,
      setConnected: state.setConnected,
      setLoading: state.setLoading,
      setError: state.setError,
      connect: state.connect,
      disconnect: state.disconnect,
      joinConversation: state.joinConversation,
      leaveConversation: state.leaveConversation,
      sendMessage: state.sendMessage,
      startTyping: state.startTyping,
      stopTyping: state.stopTyping,
      addReaction: state.addReaction,
      removeReaction: state.removeReaction,
      fetchConversations: state.fetchConversations,
      createConversation: state.createConversation,
    })),
  );
}

/**
 * FE-STATE-008: Helper function to create custom selectors
 *
 * Use this when you need to select multiple values from a store.
 *
 * @example
 * ```typescript
 * // Instead of:
 * const { user, isAuthenticated } = useAuthStore();
 *
 * // Use:
 * const { user, isAuthenticated } = useStoreSelector(useAuthStore, (state) => ({
 *   user: state.user,
 *   isAuthenticated: state.isAuthenticated,
 * }));
 * ```
 */
export function useStoreSelector<T, U>(
  store: (selector: (state: T) => U) => U,
  selector: (state: T) => U,
): U {
  return store(useShallow(selector));
}
