"use client";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { buildFileTree } from "../internal/file-tree";
import { toError } from "../internal/toError";
const EMPTY_TREE = [];
/**
 * Module-level cache shared across all component instances. This ensures
 * that switching between tabs (e.g., Workspace tab unmount/remount) doesn't
 * re-fetch file listings that were already loaded. Entries are keyed by
 * the workspace entry's stable ID.
 */
const sharedCache = new Map();
/**
 * Behavior hook that fetches and caches a file listing for a single
 * workspace entry, converting it into a {@link TreeNode} hierarchy.
 *
 * - Calls the platform-injected `lister` when the entry changes.
 * - Caches results per `entry.id` so tab switches and re-expands
 *   are instant without re-fetching.
 * - Returns an empty tree and skips the call when `lister` is
 *   `undefined` (graceful degradation — DD-011 opt-in).
 * - Memoizes the return value for referential stability (DD-010).
 *
 * @example
 * ```tsx
 * const { tree, isLoading, error, refresh } = useWorkspaceFiles({
 *   entry: selectedEntry,
 *   lister: workspaceFileLister,
 * });
 * ```
 */
export function useWorkspaceFiles({ entry, lister, }) {
    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState(null);
    const [tree, setTree] = useState(EMPTY_TREE);
    const fetchIdRef = useRef(0);
    const fetchFiles = useCallback(async (target, bustCache) => {
        if (!lister)
            return;
        if (!bustCache) {
            const cached = sharedCache.get(target.id);
            if (cached) {
                setTree(cached.tree);
                setError(null);
                setIsLoading(false);
                return;
            }
        }
        const id = ++fetchIdRef.current;
        setIsLoading(true);
        setError(null);
        try {
            const files = await lister(target);
            if (fetchIdRef.current !== id)
                return;
            if (files === null) {
                setTree(EMPTY_TREE);
                setIsLoading(false);
                return;
            }
            const built = buildFileTree(files.filter((f) => !f.isDirectory));
            sharedCache.set(target.id, { files, tree: built });
            setTree(built);
            setIsLoading(false);
        }
        catch (err) {
            if (fetchIdRef.current !== id)
                return;
            setError(toError(err));
            setTree(EMPTY_TREE);
            setIsLoading(false);
        }
    }, [lister]);
    useEffect(() => {
        if (!entry || !lister) {
            setTree(EMPTY_TREE);
            setIsLoading(false);
            setError(null);
            return;
        }
        fetchFiles(entry, false);
    }, [entry, lister, fetchFiles]);
    const refresh = useCallback(() => {
        if (entry && lister) {
            fetchFiles(entry, true);
        }
    }, [entry, lister, fetchFiles]);
    return useMemo(() => ({ tree, isLoading, error, refresh }), [tree, isLoading, error, refresh]);
}
//# sourceMappingURL=useWorkspaceFiles.js.map