import { useEffect, useState, useCallback, useRef } from 'react';
import { useUser } from '../utilities/auth/useUser';
import { ConfigService } from '../configService';
import { useAxiosGet } from '../utilities/useAxiosGet';
import { useShellStore } from '../stores/shellStore';
// Global cache to store preloaded modules (persists across component re-renders)
// This prevents re-fetching modules when navigating to pages
const preloadedModulesCache = new Map();
/**
 * Custom hook to preload all pages for a product.
 * This eliminates sequential server calls when navigating to /page/<id>
 * by fetching all page metadata in a single API call on mount.
 * After fetching metadata, it preloads the actual widget modules in the background.
 *
 * @param {Function} getWidget - Function to load widget modules
 * @returns {Object} - { pages, loading, error, refetch, preloadingWidgets }
 */
export const usePreloadPages = () => {
    const user = useUser();
    const [preloadingWidgets, setPreloadingWidgets] = useState(false);
    const [preloadedWidgets, setPreloadedWidgets] = useState(new Set());
    const { getWidget } = useShellStore();
    const preloadingRef = useRef(false); // Prevent duplicate preloading
    // Build the query parameters for the pages endpoint
    const queryParams = `page/product/${ConfigService.config.UNITY_PRODUCT_ID}?includeUdpPages=true`;
    // Fetch pages data - manual is true if user is not available
    const [{ data: pages, loading, error }, refetch] = useAxiosGet(ConfigService.tenantV1ApiUrl, queryParams, {}, !!!(user === null || user === void 0 ? void 0 : user.id) || !!!(user === null || user === void 0 ? void 0 : user.currentTenantId), // Skip if user info not available
    false // Don't use cache for fresh data
    );
    // Preload widget modules in the background after pages are fetched
    useEffect(() => {
        if (!pages || pages.length === 0 || !getWidget || preloadingRef.current) {
            return;
        }
        // Background preloading function
        const preloadWidgets = async () => {
            preloadingRef.current = true;
            setPreloadingWidgets(true);
            // Collect all unique widget types from all pages
            const widgetTypes = new Set();
            for (const page of pages) {
                try {
                    // Parse the widgets field which contains JSON string
                    if (page.widgets) {
                        // The widgets field is a JSON object where the key is the pageId
                        // and the value is a JSON string containing an array of widgets
                        const widgetsObj = JSON.parse(page.widgets);
                        const widgetsJson = widgetsObj[page.pageId];
                        if (widgetsJson) {
                            const widgetsList = JSON.parse(widgetsJson);
                            // Extract widget types from the array
                            if (Array.isArray(widgetsList)) {
                                widgetsList.forEach(widget => {
                                    if (widget.widgetType && widget.widgetType !== '0') {
                                        widgetTypes.add(widget.widgetType);
                                    }
                                });
                            }
                        }
                    }
                }
                catch (error) {
                    console.warn(`Failed to parse widgets for page ${page.name || page.pageId}:`, error);
                }
            }
            // Iterate through unique widget types and preload each module
            for (const widgetType of widgetTypes) {
                // Skip if already preloaded or no valid widget type
                if (!widgetType || preloadedWidgets.has(widgetType) || preloadedModulesCache.has(widgetType)) {
                    continue;
                }
                try {
                    // Call getWidget in the background to preload the module
                    const lazyComponent = await getWidget(widgetType);
                    // If it's a React.lazy component, we need to resolve its internal promise
                    // React.lazy components have a _payload that stores the loading state
                    if (lazyComponent && typeof lazyComponent === 'object' && lazyComponent._payload) {
                        const payload = lazyComponent._payload;
                        // Check if the payload is still pending (status: -1 = pending, 0 = error, 1 = success)
                        if (payload._status === undefined || payload._status === -1) {
                            // The module hasn't been loaded yet - trigger the import
                            if (typeof payload._result === 'function') {
                                // _result is the import() function - call it
                                try {
                                    const module = await payload._result();
                                    // Update the lazy component's internal state
                                    payload._status = 1; // Success
                                    payload._result = module;
                                    console.log(widgetType, module);
                                    preloadedModulesCache.set(widgetType, module);
                                    console.log(`✓ Preloaded and cached: ${widgetType}`);
                                }
                                catch (err) {
                                    payload._status = 0; // Error
                                    payload._result = err;
                                    throw err;
                                }
                            }
                        }
                        else if (payload._status === 1) {
                            // Already loaded - just cache it
                            preloadedModulesCache.set(widgetType, payload._result);
                            console.log(`✓ Already loaded: ${widgetType}`);
                        }
                    }
                    // Mark as preloaded
                    setPreloadedWidgets((prev) => new Set([...prev, widgetType]));
                }
                catch (error) {
                    // Silently fail - don't want to block or show errors for background preloading
                    console.warn(`✗ Failed to preload widget: ${widgetType}`, error);
                }
            }
            setPreloadingWidgets(false);
        };
        // Run preloading in background without blocking
        preloadWidgets();
    }, [pages, getWidget, preloadedWidgets]);
    /**
     * Helper function to find a page by ID from the preloaded pages
     * @param {string} pageId - The page ID to search for
     * @returns {Object|undefined} - The page object if found
     */
    const getPageById = useCallback((pageId) => {
        if (!pages || !Array.isArray(pages))
            return undefined;
        return pages.find((page) => page.pageId === pageId || page.id === pageId);
    }, [pages]);
    /**
     * Helper function to check if a page name is valid (exists in preloaded pages)
     * @param {string} pageName - The page name to check
     * @returns {boolean} - True if the page name exists
     */
    const isValidPageName = useCallback((pageName) => {
        if (!pages || !Array.isArray(pages))
            return false;
        return pages.some((page) => page.name === pageName || page.componentName === pageName);
    }, [pages]);
    /**
     * Check if a module has been preloaded and cached
     * @param {string} pageName - The page/widget name
     * @returns {boolean} - True if the module is cached
     */
    const isModulePreloaded = useCallback((pageName) => preloadedModulesCache.has(pageName), []);
    /**
     * Get a preloaded module from cache (if available)
     * @param {string} pageName - The page/widget name
     * @returns {Object|undefined} - The cached module or undefined
     */
    const getPreloadedModule = useCallback((pageName) => preloadedModulesCache.get(pageName), []);
    return {
        pages,
        loading,
        error,
        refetch,
        getPageById,
        isValidPageName,
        preloadingWidgets,
        preloadedCount: preloadedWidgets.size,
        isModulePreloaded,
        getPreloadedModule,
        // Expose the cache for debugging
        _cache: preloadedModulesCache
    };
};
//# sourceMappingURL=usePreloadPages.js.map