'use client';
import { useState, useRef, useCallback, useEffect } from 'react';
function createInitialTabState() {
    return { data: null, loading: false, error: null };
}
/**
 * Custom hook for lazy-loading tab data with per-tab caching.
 *
 * - Fetches data only when a tab is explicitly activated via fetchTab().
 * - Caches results so revisiting a loaded tab is instant.
 * - Clears all cached data when featureId changes.
 * - Supports force re-fetch via refreshTab() for SSE-driven updates.
 * - Uses ref-based callbacks to avoid stale closures (matches useArtifactFetch pattern).
 */
export function useTabDataFetch(featureId, fetchers) {
    const tabKeys = Object.keys(fetchers);
    const [tabStates, setTabStates] = useState(() => {
        const initial = {};
        for (const key of tabKeys) {
            initial[key] = createInitialTabState();
        }
        return initial;
    });
    // Ref-based fetchers to avoid stale closures in callbacks.
    const fetchersRef = useRef(fetchers);
    fetchersRef.current = fetchers;
    // Ref-based featureId to use current value in callbacks.
    const featureIdRef = useRef(featureId);
    featureIdRef.current = featureId;
    // Track mounted state to prevent state updates after unmount.
    const mountedRef = useRef(true);
    useEffect(() => {
        mountedRef.current = true;
        return () => {
            mountedRef.current = false;
        };
    }, []);
    // Clear all cached data when featureId changes.
    const prevFeatureIdRef = useRef(featureId);
    useEffect(() => {
        if (prevFeatureIdRef.current !== featureId) {
            prevFeatureIdRef.current = featureId;
            setTabStates((prev) => {
                const cleared = {};
                for (const key of Object.keys(prev)) {
                    cleared[key] = createInitialTabState();
                }
                return cleared;
            });
        }
    }, [featureId]);
    const doFetch = useCallback(async (tab) => {
        const fetcher = fetchersRef.current[tab];
        const currentFeatureId = featureIdRef.current;
        if (!fetcher)
            return;
        // Only show loading spinner when there's no existing data.
        // On refresh (data already present), keep showing stale data while fetching
        // to avoid flickering the entire tab on every poll cycle.
        if (mountedRef.current) {
            setTabStates((prev) => {
                const hasData = prev[tab]?.data !== null;
                if (hasData)
                    return prev; // Keep stale data visible — no loading flash
                return { ...prev, [tab]: { ...prev[tab], loading: true, error: null } };
            });
        }
        try {
            const data = await fetcher(currentFeatureId);
            if (mountedRef.current) {
                setTabStates((prev) => ({
                    ...prev,
                    [tab]: { data, loading: false, error: null },
                }));
            }
        }
        catch (error) {
            if (mountedRef.current) {
                setTabStates((prev) => {
                    const message = error instanceof Error ? error.message : 'Failed to fetch tab data';
                    // On refresh failure, keep existing data instead of clearing it
                    const existingData = prev[tab]?.data ?? null;
                    return {
                        ...prev,
                        [tab]: { data: existingData, loading: false, error: existingData ? null : message },
                    };
                });
            }
        }
    }, []);
    const fetchTab = useCallback(async (tab) => {
        // Check if data is already cached (non-null data means already fetched)
        const current = tabStates[tab];
        if (current && current.data !== null)
            return;
        // Also skip if currently loading
        if (current && current.loading)
            return;
        await doFetch(tab);
    }, [tabStates, doFetch]);
    const refreshTab = useCallback(async (tab) => {
        await doFetch(tab);
    }, [doFetch]);
    return {
        tabs: tabStates,
        fetchTab,
        refreshTab,
    };
}
