/**
 * 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 { apiClient } from '@/services/api/client';
import { useAuthStore } from '@/stores/auth';
import { useLibraryStore } from '@/stores/library';
import { useChatStore } from '@/stores/chat';
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 {
        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:', err);
      }
    }

    // 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:', err);
      }
    }

    // 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:', err);
      }
    }
  } catch (error) {
    const err = error instanceof Error ? error : new Error(String(error));
    logger.error('[StateHydration] Fatal error during hydration:', err);
    result.success = false;
  }

  return result;
}

/**
 * Hydrate auth state from server
 */
async function hydrateAuthState(): Promise<void> {
  const { refreshUser } = useAuthStore.getState();
  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
 */
async function hydrateChatState(): Promise<void> {
  const { fetchConversations } = useChatStore.getState();
  
  // Fetch conversations to hydrate the chat store
  await fetchConversations();
}

/**
 * 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 = {}) {
  // Dynamic import to avoid circular dependencies
  const React = require('react');
  const { useEffect, useState } = React;
  
  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,
  };
}

