/**
 * State Hydration Utilities
 * FE-STATE-003: Hydrate state from server on app load
 *
 * Provides utilities for hydrating Zustand stores with server data on application startup
 */

import { useEffect, useState } from 'react';
import { useAuthStore } from '@/features/auth/store/authStore';
import { useLibraryStore } from '@/stores/library';
// Action 4.5.1.5: Chat store moved to features/chat/store/chatStore.ts
// Chat hydration is disabled by default and not needed (ChatSidebar uses React Query)
import { TokenStorage } from '@/services/tokenStorage';
import { logger } from './logger';

/**
 * Configuration for state hydration
 */
export interface HydrationConfig {
  /** Whether to hydrate auth state */
  hydrateAuth?: boolean;
  /** Whether to hydrate library state */
  hydrateLibrary?: boolean;
  /** Whether to hydrate chat state */
  hydrateChat?: boolean;
  /** Whether to skip hydration if user is not authenticated */
  requireAuth?: boolean;
}

/**
 * Result of state hydration
 */
export interface HydrationResult {
  success: boolean;
  hydrated: string[];
  errors: Array<{ store: string; error: Error }>;
}

/**
 * FE-STATE-003: Hydrate all stores from server
 *
 * This function loads initial state from the server for all configured stores.
 * It should be called once on application startup.
 *
 * @param config Configuration for which stores to hydrate
 * @returns Promise with hydration result
 *
 * @example
 * ```typescript
 * // In App.tsx or main.tsx
 * useEffect(() => {
 *   hydrateState({
 *     hydrateAuth: true,
 *     hydrateLibrary: true,
 *     hydrateChat: true,
 *   }).then((result) => {
 *     if (result.success) {
 *       console.log('State hydrated successfully');
 *     }
 *   });
 * }, []);
 * ```
 */
export async function hydrateState(
  config: HydrationConfig = {},
): Promise<HydrationResult> {
  const {
    hydrateAuth = true,
    hydrateLibrary = false,
    hydrateChat = false,
    requireAuth = true,
  } = config;

  const result: HydrationResult = {
    success: true,
    hydrated: [],
    errors: [],
  };

  try {
    // Check authentication first if required
    if (requireAuth) {
      const { isAuthenticated } = useAuthStore.getState();
      if (!isAuthenticated) {
        logger.debug(
          '[StateHydration] User not authenticated, skipping hydration',
        );
        return result;
      }
    }

    // Hydrate auth state
    if (hydrateAuth) {
      try {
        // Vérifier si on a déjà un user authentifié avec des tokens
        // Si oui, ne pas appeler refreshUser() pour éviter de réinitialiser l'état après login
        // Action 4.1.1.3: User data is now managed by React Query, only check isAuthenticated
        const { isAuthenticated, isLoading } = useAuthStore.getState();
        const hasTokens = TokenStorage.hasTokens();

        // Si on a déjà un user authentifié avec des tokens, ne pas refresh
        // Cela évite les problèmes de timing après le login
        // React Query will handle user data caching automatically
        if (isAuthenticated && hasTokens && !isLoading) {
          logger.debug(
            '[StateHydration] User already authenticated with tokens, skipping auth hydration',
          );
          result.hydrated.push('auth');
        } else {
          await hydrateAuthState();
          result.hydrated.push('auth');
          logger.debug('[StateHydration] Auth state hydrated');
        }
      } catch (error) {
        const err = error instanceof Error ? error : new Error(String(error));
        result.errors.push({ store: 'auth', error: err });
        result.success = false;
        logger.error('[StateHydration] Failed to hydrate auth state', {
          error: err.message,
        });
      }
    }

    // Hydrate library state
    if (hydrateLibrary) {
      try {
        await hydrateLibraryState();
        result.hydrated.push('library');
        logger.debug('[StateHydration] Library state hydrated');
      } catch (error) {
        const err = error instanceof Error ? error : new Error(String(error));
        result.errors.push({ store: 'library', error: err });
        result.success = false;
        logger.error('[StateHydration] Failed to hydrate library state', {
          error: err.message,
        });
      }
    }

    // Hydrate chat state
    if (hydrateChat) {
      try {
        await hydrateChatState();
        result.hydrated.push('chat');
        logger.debug('[StateHydration] Chat state hydrated');
      } catch (error) {
        const err = error instanceof Error ? error : new Error(String(error));
        result.errors.push({ store: 'chat', error: err });
        result.success = false;
        logger.error('[StateHydration] Failed to hydrate chat state', {
          error: err.message,
        });
      }
    }
  } catch (error) {
    const err = error instanceof Error ? error : new Error(String(error));
    logger.error('[StateHydration] Fatal error during hydration', {
      error: err.message,
    });
    result.success = false;
  }

  return result;
}

/**
 * Hydrate auth state from server
 * CRITIQUE: Ne pas appeler refreshUser si l'utilisateur est déjà authentifié
 * pour éviter de réinitialiser l'état après navigation
 * 
 * Action 4.1.1.3: User data is now managed by React Query, only check isAuthenticated
 */
async function hydrateAuthState(): Promise<void> {
  const { refreshUser, isAuthenticated } = useAuthStore.getState();
  const hasTokens = TokenStorage.hasTokens();

  // Si l'utilisateur est déjà authentifié avec des tokens,
  // ne pas appeler refreshUser pour éviter de réinitialiser l'état
  // React Query will handle user data caching automatically
  if (isAuthenticated && hasTokens) {
    logger.debug(
      '[StateHydration] User already authenticated, skipping refreshUser',
    );
    return;
  }

  // Sinon, appeler refreshUser pour vérifier l'état d'authentification
  await refreshUser();
}

/**
 * Hydrate library state from server
 */
async function hydrateLibraryState(): Promise<void> {
  const { fetchFavorites } = useLibraryStore.getState();

  // Fetch favorites to hydrate the library store
  await fetchFavorites();
}

/**
 * Hydrate chat state from server
 * Action 4.5.1.5: Chat hydration removed - ChatSidebar uses React Query to fetch conversations
 * The feature store doesn't have fetchConversations method, and it's not needed
 * since conversations are fetched via React Query in ChatSidebar component
 */
async function hydrateChatState(): Promise<void> {
  // Chat state is hydrated via React Query in ChatSidebar component
  // No need to fetch conversations here
  logger.debug('[StateHydration] Chat state hydration skipped - using React Query');
}

/**
 * FE-STATE-003: React hook for state hydration
 *
 * Use this hook in your root component to automatically hydrate state on mount
 *
 * @example
 * ```typescript
 * function App() {
 *   useStateHydration({
 *     hydrateAuth: true,
 *     hydrateLibrary: true,
 *   });
 *
 *   return <YourApp />;
 * }
 * ```
 */
export function useStateHydration(config: HydrationConfig = {}) {
  const [isHydrating, setIsHydrating] = useState(true);
  const [hydrationResult, setHydrationResult] =
    useState<HydrationResult | null>(null);

  useEffect(() => {
    let mounted = true;

    hydrateState(config)
      .then((result) => {
        if (mounted) {
          setHydrationResult(result);
          setIsHydrating(false);
        }
      })
      .catch((error) => {
        if (mounted) {
          logger.error('[StateHydration] Hook error:', error);
          setHydrationResult({
            success: false,
            hydrated: [],
            errors: [
              {
                store: 'unknown',
                error:
                  error instanceof Error ? error : new Error(String(error)),
              },
            ],
          });
          setIsHydrating(false);
        }
      });

    return () => {
      mounted = false;
    };
  }, []); // Only run once on mount

  return {
    isHydrating,
    hydrationResult,
  };
}
