import React, { useState, useEffect, useCallback, useRef } from 'react';
import { Loader2 } from 'lucide-react';
import { useAuth } from '@/hooks/useAuth';
import ImageLightbox from '@/components/ImageLightbox';
import LightboxText from '@/modules/storage/views/LightboxText';
import LightboxIframe from '@/modules/storage/views/LightboxIframe';
import { renderFileViewer } from '@/modules/storage/FileViewerRegistry';
import { ResizablePanelGroup, ResizablePanel, ResizableHandle } from '@/components/ui/resizable';

import type { INode, SortKey } from '@/modules/storage/types';
import { getMimeCategory, vfsUrl, formatSize } from '@/modules/storage/helpers';
import FileBrowserToolbar from '@/modules/storage/FileBrowserToolbar';
import FileListView from '@/modules/storage/FileListView';
import FileGridView from '@/modules/storage/FileGridView';
import FileDetailPanel from '@/modules/storage/FileDetailPanel';
import MarkdownRenderer from '@/components/MarkdownRenderer';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Switch } from '@/components/ui/switch';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { IMAGE_EXTS, VIDEO_EXTS, CODE_EXTS } from '@/modules/storage/helpers';
import { T } from '@/i18n';

import { useVfsAdapter } from '@/modules/storage/hooks/useVfsAdapter';
import { useSelection } from '@/modules/storage/hooks/useSelection';
import { useFilePreview } from '@/modules/storage/hooks/useFilePreview';
import { useDefaultKeyboardHandler } from '@/modules/storage/hooks/useDefaultKeyboardHandler';
import { useDefaultSelectionHandler } from '@/modules/storage/hooks/useDefaultSelectionHandler';
import { useDefaultActions } from '@/modules/storage/hooks/useDefaultActions';
import { FileTree } from './FileTree';
import SearchDialog from './SearchDialog';

// ── Props ────────────────────────────────────────────────────────

export interface FileBrowserPanelProps {
    mount?: string;
    path?: string;
    glob?: string;
    mode?: 'simple' | 'advanced';
    viewMode?: 'list' | 'thumbs' | 'tree';
    sortBy?: SortKey;
    showToolbar?: boolean;
    canChangeMount?: boolean;
    allowFileViewer?: boolean;
    allowLightbox?: boolean;
    allowPreview?: boolean;
    allowDownload?: boolean;
    jail?: boolean;
    onPathChange?: (path: string) => void;
    onMountChange?: (mount: string) => void;
    /** If set, auto-open this file in lightbox after directory loads */
    initialFile?: string;
    /** If true, automatically loads and renders a readme.md (case-insensitive) in the current directory */
    index?: boolean;
    /** If true, allows the fallback FileBrowserPanel to render when no readme is found. */
    allowFallback?: boolean;
    /** ID for saving user preferences like viewMode locally (e.g. 'pm-filebrowser-left-panel') */
    autoSaveId?: string;
    showFolders?: boolean;
    showExplorer?: boolean;
    showPreview?: boolean;
    showTree?: boolean;
    onToggleExplorer?: () => void;
    onTogglePreview?: () => void;
    onFilterChange?: (glob: string, showFolders: boolean) => void;
    onSelect?: (nodes: INode[] | INode | null) => void;
    searchQuery?: string;
    onSearchQueryChange?: (q: string) => void;
    autoFocus?: boolean;
    includeSize?: boolean;
    splitSizeHorizontal?: number[];
    splitSizeVertical?: number[];
    onLayoutChange?: (sizes: number[], direction: 'horizontal' | 'vertical') => void;
    showStatusBar?: boolean;
}

// ── Main Component ───────────────────────────────────────────────

const FileBrowserPanel: React.FC<FileBrowserPanelProps> = ({
    mount: mountProp = 'machines',
    path: pathProp = '/',
    glob = '*.*',
    mode = 'simple',
    viewMode: initialViewMode = 'list',
    sortBy: initialSort = 'name',
    showToolbar = true,
    canChangeMount = false,
    allowFileViewer = true,
    allowLightbox = true,
    allowPreview = true,
    allowDownload = true,
    jail = false,
    initialFile,
    allowFallback = true,
    autoFocus = true,
    includeSize = false,
    index = true,
    autoSaveId,
    showFolders: showFoldersProp,
    showExplorer = true,
    showPreview = true,
    showTree = true,
    onToggleExplorer,
    onTogglePreview,
    onPathChange,
    onMountChange,
    onSelect,
    onFilterChange,
    searchQuery,
    onSearchQueryChange,
    splitSizeHorizontal,
    splitSizeVertical,
    onLayoutChange,
    showStatusBar = true
}) => {

    const { session } = useAuth();
    const accessToken = session?.access_token;

    const [readmeContent, setReadmeContent] = useState<string | null>(null);
    const [selectedReadmeContent, setSelectedReadmeContent] = useState<string | null>(null);

    // ── Controlled / uncontrolled mode ────────────────────────────

    const [internalMount, setInternalMount] = useState(mountProp);
    const mount = onMountChange ? mountProp : internalMount;

    const [internalGlob, setInternalGlob] = useState(glob);
    const [internalShowFolders, setInternalShowFolders] = useState(true);
    const actualCurrentGlob = onFilterChange ? glob : internalGlob;
    const showFolders = onFilterChange ? (showFoldersProp ?? true) : internalShowFolders;

    const updateFilter = useCallback((newGlob: string, newShowFolders: boolean) => {
        if (onFilterChange) onFilterChange(newGlob, newShowFolders);
        else {
            setInternalGlob(newGlob);
            setInternalShowFolders(newShowFolders);
        }
    }, [onFilterChange]);

    // ── Available mounts ─────────────────────────────────────────

    const [availableMounts, setAvailableMounts] = useState<string[]>([]);
    useEffect(() => {
        const headers: Record<string, string> = {};
        if (accessToken) headers['Authorization'] = `Bearer ${accessToken}`;
        fetch('/api/vfs/mounts', { headers })
            .then(r => r.ok ? r.json() : [])
            .then((mounts: { name: string }[]) => setAvailableMounts(mounts.map(m => m.name)))
            .catch(() => { });
    }, [accessToken]);

    // ── VFS Adapter ───────────────────────────────────────────────

    const {
        nodes,
        sorted,
        loading,
        error,
        currentPath,
        currentGlob,
        updatePath,
        updateMount,
        fetchDir,
        canGoUp,
        goUp: rawGoUp,
        breadcrumbs,
        jailRoot,
        isSearchMode
    } = useVfsAdapter({
        mount,
        pathProp,
        glob: actualCurrentGlob,
        showFolders,
        accessToken,
        index,
        jail,
        jailPath: pathProp,
        sortBy: initialSort,
        sortAsc: true,
        includeSize,
        searchQuery,
        onPathChange,
        onMountChange: (m) => {
            setInternalMount(m);
            if (onMountChange) onMountChange(m);
        },
        onFetched: async (fetchedNodes, isSearch) => {
            setReadmeContent(null);
            if (index && !isSearch) {
                const readmeNode = fetchedNodes.find(n => n.name.toLowerCase() === 'readme.md');
                if (readmeNode) {
                    const tokenParam = accessToken ? `token=${encodeURIComponent(accessToken)}` : '';
                    const base = vfsUrl('get', mount, readmeNode.path);
                    const fileUrl = tokenParam ? `${base}?${tokenParam}` : base;
                    const fileRes = await fetch(fileUrl, { cache: 'no-cache' });
                    if (fileRes.ok) {
                        const content = await fileRes.text();
                        setReadmeContent(content);
                    }
                }
            }
        }
    });

    // ── View Mode & Zoom ─────────────────────────────────────────

    const [internalViewMode, setInternalViewMode] = useState<'list' | 'thumbs' | 'tree'>(() => {
        if (autoSaveId) {
            const saved = localStorage.getItem(`${autoSaveId}-viewMode`);
            if (saved === 'list' || saved === 'thumbs' || saved === 'tree') return saved;
        }
        return initialViewMode;
    });

    const [internalMode, setInternalMode] = useState<'simple' | 'advanced'>(() => {
        if (autoSaveId) {
            const saved = localStorage.getItem(`${autoSaveId}-mode`);
            if (saved === 'simple' || saved === 'advanced') return saved;
        }
        return mode;
    });

    const setViewMode = useCallback((m: 'list' | 'thumbs' | 'tree') => {
        setInternalViewMode(m);
        if (autoSaveId) localStorage.setItem(`${autoSaveId}-viewMode`, m);
    }, [autoSaveId]);

    const setDisplayMode = useCallback((m: 'simple' | 'advanced') => {
        setInternalMode(m);
        if (autoSaveId) localStorage.setItem(`${autoSaveId}-mode`, m);
    }, [autoSaveId]);

    const [splitDirection, setSplitDirectionState] = useState<'horizontal' | 'vertical'>(() => {
        if (autoSaveId) {
            const saved = localStorage.getItem(`${autoSaveId}-splitDir`);
            if (saved === 'horizontal' || saved === 'vertical') return saved;
        }
        return typeof window !== 'undefined' && window.innerWidth < 768 ? 'vertical' : 'horizontal';
    });

    const setSplitDirection = useCallback((m: 'horizontal' | 'vertical') => {
        setSplitDirectionState(m);
        if (autoSaveId) localStorage.setItem(`${autoSaveId}-splitDir`, m);
    }, [autoSaveId]);

    const viewMode = internalViewMode;
    const currentMode = internalMode;
    const activeSplitSize = splitDirection === 'horizontal' ? splitSizeHorizontal : splitSizeVertical;

    const [thumbSize, setThumbSize] = useState(() => {
        const v = localStorage.getItem('fb-thumb-size');
        return v ? Math.max(60, Math.min(200, Number(v))) : 80;
    });
    const [fontSize, setFontSize] = useState(() => {
        const v = localStorage.getItem('fb-font-size');
        return v ? Math.max(10, Math.min(18, Number(v))) : 14;
    });

    const zoomIn = () => {
        if (viewMode === 'thumbs') setThumbSize(s => { const n = Math.min(200, s + 20); localStorage.setItem('fb-thumb-size', String(n)); return n; });
        else setFontSize(s => { const n = Math.min(18, s + 1); localStorage.setItem('fb-font-size', String(n)); return n; });
    };
    const zoomOut = () => {
        if (viewMode === 'thumbs') setThumbSize(s => { const n = Math.max(60, s - 20); localStorage.setItem('fb-thumb-size', String(n)); return n; });
        else setFontSize(s => { const n = Math.max(10, s - 1); localStorage.setItem('fb-font-size', String(n)); return n; });
    };

    // ── Selection & Refs ─────────────────────────────────────────

    const listRef = useRef<HTMLDivElement>(null);
    const containerRef = useRef<HTMLDivElement>(null);

    const {
        focusIdx,
        setFocusIdx,
        selected,
        setSelected,
        itemCount,
        getNode,
        handleItemClick,
        clearSelection
    } = useSelection({
        sorted,
        canGoUp,
        onSelect
    });

    // Dummy Sort controls for now since useVfsAdapter uses static sortBy
    const [sortBy, setSortBy] = useState<SortKey>(initialSort);
    const [sortAsc, setSortAsc] = useState(true);
    const cycleSort = () => {
        const keys: SortKey[] = ['name', 'ext', 'date', 'type'];
        const i = keys.indexOf(sortBy);
        if (sortAsc) { setSortAsc(false); } else { setSortBy(keys[(i + 1) % keys.length]); setSortAsc(true); }
    };

    // ── Previews ─────────────────────────────────────────────────

    const {
        lightboxNode,
        setLightboxNode,
        textLightboxNode,
        setTextLightboxNode,
        iframeLightboxNode,
        setIframeLightboxNode,
        openPreview,
        closeAllPreviews
    } = useFilePreview({ allowLightbox, allowFileViewer });

    // ── Filter Dialog State ────────────────────────────────────────

    const [filterDialogOpen, setFilterDialogOpen] = useState(false);
    const [tempGlob, setTempGlob] = useState(currentGlob);
    const [tempShowFolders, setTempShowFolders] = useState(showFolders);

    const applyTempFilter = () => {
        updateFilter(tempGlob, tempShowFolders);
        setFilterDialogOpen(false);
        setTimeout(() => containerRef.current?.focus(), 0);
    };

    const mediaGlob = Array.from(new Set([...IMAGE_EXTS, ...VIDEO_EXTS])).map(ext => `*.${ext}`).join(',');
    const codeGlob = Array.from(CODE_EXTS).map(ext => `*.${ext}`).join(',');

    const tokenParam = accessToken ? `token=${encodeURIComponent(accessToken)}` : '';

    // ── Standalone scroll & grid helpers (shared by keyboard + selection hooks) ──

    const scrollItemIntoView = useCallback((idx: number) => {
        if (!listRef.current) return;
        const items = listRef.current.querySelectorAll('[data-fb-idx]');
        const el = items[idx] as HTMLElement | undefined;
        el?.scrollIntoView({ block: 'nearest' });
    }, []);

    const getGridCols = useCallback((): number => {
        if (viewMode !== 'thumbs' || !listRef.current) return 1;
        const style = getComputedStyle(listRef.current);
        const cols = style.gridTemplateColumns.split(' ').length;
        return Math.max(1, cols);
    }, [viewMode]);

    // ── Default Selection Handler (first so we get wrapped goUp) ──

    const [pendingFileSelect, setPendingFileSelect] = useState<string | null>(null);

    const { goUp } = useDefaultSelectionHandler({
        sorted,
        canGoUp,
        rawGoUp,
        currentPath,
        loading,
        viewMode,
        autoFocus,
        index,
        isSearchMode,
        initialFile,
        allowFallback,
        setFocusIdx,
        setSelected,
        onSelect,
        pendingFileSelect,
        setPendingFileSelect,
        scrollItemIntoView,
        containerRef,
        listRef,
    });

    // ── Default Keyboard Handler (uses wrapped goUp) ─────────────

    const {
        searchOpen,
        setSearchOpen,
        searchDisplay,
        searchBufferRef,
        pendingSearchSelection,
        setPendingSearchSelection,
        handleKeyDown
    } = useDefaultKeyboardHandler({
        focusIdx,
        setFocusIdx,
        selected,
        setSelected,
        itemCount,
        getNode,
        clearSelection,
        canGoUp,
        goUp,
        updatePath,
        openPreview,
        viewMode,
        setViewMode,
        setDisplayMode,
        currentGlob,
        showFolders,
        cycleSort,
        setTempGlob,
        setTempShowFolders,
        setFilterDialogOpen,
        containerRef,
        scrollItemIntoView,
        getGridCols,
        autoFocus,
        allowFallback,
        currentPath,
        onSearchQueryChange,
        searchQuery,
        isSearchMode,
        onSelect,
        sorted,
    });

    // ── Default Actions ──────────────────────────────────────────

    const {
        selectedFile,
        getFileUrl,
        handleView,
        handleDownload,
        handleDownloadDir,
        mediaNodes,
        lightboxIdx,
        lightboxPrev,
        lightboxNext,
        closeLightbox,
        closeTextLightbox,
        closeIframeLightbox,
        handleDoubleClick,
        handleLinkClick
    } = useDefaultActions({
        mount,
        mountProp,
        pathProp,
        accessToken,
        selected,
        sorted,
        canGoUp,
        setFocusIdx,
        setSelected,
        lightboxNode,
        setLightboxNode,
        textLightboxNode,
        setTextLightboxNode,
        iframeLightboxNode,
        setIframeLightboxNode,
        openPreview,
        updatePath,
        setPendingFileSelect,
        containerRef,
        getNode,
        goUp,
    });

    return (
        <div
            ref={containerRef}
            data-testid="file-browser-panel"
            tabIndex={viewMode === 'tree' ? undefined : 0}
            className="fb-panel-container"
            onKeyDown={handleKeyDown}
            style={{
                display: 'flex', flexDirection: 'column', height: '100%', minHeight: 0,
                border: '1px solid var(--border, #334155)', borderRadius: 6, overflow: 'hidden',

                fontFamily: 'var(--font-sans, system-ui, sans-serif)', outline: 'none',
            }}
        >
            <style>{`
        @media (max-width: 767px) { 
          .fb-detail-pane { display: none !important; }
        }
      `}</style>

            {/* ═══ Toolbar ═══════════════════════════════════ */}
            {showToolbar && (
                <FileBrowserToolbar
                    canGoUp={canGoUp}
                    goUp={goUp}
                    canChangeMount={!jail && canChangeMount}
                    availableMounts={availableMounts}
                    mount={mount}
                    updateMount={updateMount}
                    mountProp={mountProp}
                    pathProp={pathProp}
                    updatePath={updatePath}
                    breadcrumbs={breadcrumbs}
                    selectedNode={selected.length === 1 ? selected[0] : null}
                    selectedNodes={selected}
                    selectedFile={selectedFile}
                    handleView={handleView}
                    handleDownload={handleDownload}
                    allowDownload={allowDownload && selected.length > 0}
                    handleDownloadDir={handleDownloadDir}
                    allowDownloadDir={allowDownload}
                    sortBy={sortBy}
                    sortAsc={sortAsc}
                    cycleSort={cycleSort}
                    zoomIn={zoomIn}
                    zoomOut={zoomOut}
                    viewMode={viewMode}
                    setViewMode={setViewMode}
                    displayMode={currentMode}
                    setDisplayMode={setDisplayMode}
                    splitDirection={splitDirection}
                    setSplitDirection={setSplitDirection}
                    showExplorer={showExplorer}
                    onToggleExplorer={onToggleExplorer}
                    showPreview={showPreview}
                    onTogglePreview={onTogglePreview}
                    onFilterOpen={() => {
                        setTempGlob(currentGlob);
                        setTempShowFolders(showFolders);
                        setFilterDialogOpen(true);
                    }}
                    onSearchOpen={() => setSearchOpen(true)}
                    fontSize={fontSize}
                    isSearchMode={isSearchMode}
                    onClearSearch={() => onSearchQueryChange && onSearchQueryChange('')}
                />
            )}

            {/* ═══ Content ═══════════════════════════════════ */}
            {loading ? (
                <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, opacity: 0.6 }}>
                    <Loader2 size={16} className="animate-spin" />
                    <span style={{ fontSize: 14 }}><T>Loading…</T></span>
                </div>
            ) : error ? (
                <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 20, fontSize: 14, color: '#ef4444' }}>
                    <T>{error}</T>
                </div>
            ) : itemCount === 0 ? (
                <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 20, fontSize: 14, opacity: 0.5 }}>
                    <T>Empty directory</T>
                </div>
            ) : (
                <div style={{ display: 'flex', flex: 1, overflow: 'hidden', minHeight: 0 }}>

                    <ResizablePanelGroup
                        direction={splitDirection}
                        onLayout={(sizes) => {
                            if (onLayoutChange) onLayoutChange(sizes, splitDirection);
                        }}
                        {...(activeSplitSize && activeSplitSize.length > 0 ? {} : { autoSaveId: autoSaveId ? `${autoSaveId}-split-${splitDirection}` : `pm-filebrowser-panel-layout-${splitDirection}` })}
                        className={`flex-1 flex overflow-hidden ${splitDirection === 'vertical' ? 'flex-col min-h-0' : 'flex-row min-w-0'}`}
                    >
                        {showExplorer && (
                            <ResizablePanel defaultSize={activeSplitSize ? activeSplitSize[0] : 60} minSize={15} className="relative min-w-0 bg-white dark:bg-slate-800/50">
                                <div className="w-full h-full flex flex-col min-h-[50px] min-w-0">
                                    {viewMode === 'tree' ? (
                                        <div className="flex-1 min-h-0 overflow-hidden pt-1">
                                            <FileTree
                                                data={sorted}
                                                canGoUp={canGoUp}
                                                onGoUp={goUp}
                                                selectedId={selected.length === 1 ? selected[0].path : undefined}
                                                fontSize={fontSize}
                                                fetchChildren={async (node: INode) => {
                                                    const clean = node.path.replace(/^\/+/, '');
                                                    const base = vfsUrl('ls', mount, clean);
                                                    const url = `${base}?includeSize=true`;
                                                    const headers: Record<string, string> = {};
                                                    if (accessToken) headers['Authorization'] = `Bearer ${accessToken}`;
                                                    const res = await fetch(url, { headers });
                                                    if (!res.ok) throw new Error(`HTTP ${res.status}`);
                                                    return res.json();
                                                }}
                                                onSelectionChange={(nodes) => {
                                                    setSelected(nodes);
                                                }}
                                                onSelect={(n) => {
                                                    setSelected([n]);
                                                }}
                                                onActivate={(n) => {
                                                    if (getMimeCategory(n) === 'dir') {
                                                        updatePath(n.path || n.name);
                                                    } else {
                                                        openPreview(n);
                                                    }
                                                }}
                                            />
                                        </div>
                                    ) : viewMode === 'list' ? (
                                        <div className="flex-1 min-h-0 overflow-hidden pt-1 flex flex-col w-full h-full">
                                            <FileListView
                                                listRef={listRef}
                                                sorted={sorted}
                                                canGoUp={canGoUp}
                                                goUp={goUp}
                                                focusIdx={focusIdx}
                                                setFocusIdx={setFocusIdx}
                                                selected={selected}
                                                onItemClick={handleItemClick}
                                                onItemDoubleClick={handleDoubleClick}
                                                fontSize={fontSize}
                                                mode={currentMode}
                                                searchBuffer={isSearchMode ? (searchQuery || searchDisplay) : searchDisplay}
                                                isSearchMode={isSearchMode}
                                            />
                                        </div>
                                    ) : (
                                        <div className="flex-1 flex flex-col min-h-0 overflow-hidden w-full h-full pt-1">
                                            <FileGridView
                                                listRef={listRef}
                                                sorted={sorted}
                                                canGoUp={canGoUp}
                                                goUp={goUp}
                                                focusIdx={focusIdx}
                                                setFocusIdx={setFocusIdx}
                                                selected={selected}
                                                onItemClick={handleItemClick}
                                                onItemDoubleClick={handleDoubleClick}
                                                thumbSize={thumbSize}
                                                mount={mount}
                                                tokenParam={tokenParam}
                                                fontSize={fontSize}
                                                isSearchMode={isSearchMode}
                                            />
                                        </div>
                                    )}
                                </div>
                            </ResizablePanel>
                        )}

                        {/* Right Pane conditionally renders if preview or fallback exists */}
                        {showPreview && ((!showExplorer && selected.length === 1) || (allowPreview && selected.length === 1 && getMimeCategory(selected[0]) !== 'dir') || (selected.length === 0 && readmeContent) || (allowPreview && selectedReadmeContent) || (allowPreview && allowFallback && selected.length === 1 && getMimeCategory(selected[0]) === 'dir')) && (
                            <>
                                {showExplorer && <ResizableHandle withHandle />}
                                <ResizablePanel defaultSize={activeSplitSize && activeSplitSize.length > 1 ? activeSplitSize[1] : (showExplorer ? 40 : 100)} minSize={15} className="relative min-w-0 bg-card/30">
                                    <div className="w-full h-full flex flex-col min-h-[50px] min-w-0">
                                        {((!showExplorer && selected.length === 1 && getMimeCategory(selected[0]) !== 'dir') || (allowPreview && selected.length === 1 && getMimeCategory(selected[0]) !== 'dir')) ? (
                                            <div className="fb-readme-pane shrink-0 border-t md:border-t-0 border-border overflow-hidden w-full h-full relative flex flex-1 flex-col min-h-0">
                                                {renderFileViewer({
                                                    selected: selected[0],
                                                    url: getFileUrl(selected[0]),
                                                    fileName: selected[0].name,
                                                    inline: true,
                                                    isOpen: true,
                                                    onClose: () => { },
                                                    onLinkClick: (href, e) => handleLinkClick(href, e, selected[0].parent || '/')
                                                })}
                                            </div>
                                        ) : ((selected.length === 0 && readmeContent) || (allowPreview && selectedReadmeContent)) ? (
                                            <div className="fb-readme-pane shrink-0 p-6 border-t md:border-t-0 border-border overflow-y-auto flex-1 w-full h-full">
                                                <MarkdownRenderer
                                                    content={selectedReadmeContent || readmeContent || ''}
                                                    baseUrl={
                                                        selectedReadmeContent && selected.length === 1
                                                            ? vfsUrl('get', mount, selected[0].path) + '/'
                                                            : vfsUrl('get', mount, currentPath) + '/'
                                                    }
                                                    onLinkClick={(href, e) => {
                                                        const basePath = (selectedReadmeContent && selected.length === 1)
                                                            ? (selected[0].parent || '/')
                                                            : currentPath;
                                                        handleLinkClick(href, e, basePath);
                                                    }}
                                                />
                                            </div>
                                        ) : (allowPreview && allowFallback && selected.length === 1 && getMimeCategory(selected[0]) === 'dir') ? (
                                            <div className="fb-readme-pane flex shrink-0 border-t md:border-t-0 border-border flex-1 flex-col min-h-0 overflow-hidden relative w-full h-full">
                                                <FileBrowserPanel
                                                    mount={mount}
                                                    path={selected[0].path}
                                                    viewMode="thumbs"
                                                    showToolbar={false}
                                                    mode="simple"
                                                    jail={true}
                                                    allowFallback={false}
                                                    index={false}
                                                    autoFocus={false}
                                                    showStatusBar={false}
                                                />
                                            </div>
                                        ) : null}
                                    </div>
                                </ResizablePanel>
                            </>
                        )}
                    </ResizablePanelGroup>

                    {/* Detail panel (advanced, desktop only) */}


                    {/* Detail panel (advanced, desktop only) */}
                    {mode === 'advanced' && (
                        <FileDetailPanel file={selected.length === 1 ? selected[0] : null} fileUrl={selected.length === 1 ? getFileUrl(selected[0]) : ''} />
                    )}
                </div>
            )}

            {showStatusBar && <div style={{
                padding: '4px 10px', fontSize: 13, borderTop: '2px solid var(--border)',
                color: 'var(--muted-foreground)', display: 'flex', justifyContent: 'space-between',
                background: 'var(--muted)', width: '100%', overflow: 'hidden', gap: '8px'
            }}>
                <span
                    title={`${sorted.length} ${sorted.length !== 1 ? 'items' : 'item'} · ${formatSize(sorted.reduce((sum, n) => sum + (n.size || 0), 0))}${selectedFile ? ` · ${selectedFile.name} (${formatSize(selectedFile.size)})` : ''}`}
                    style={{ flex: 1, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}
                >
                    {sorted.length} <T>{sorted.length !== 1 ? 'items' : 'item'}</T>
                    {' · '}{formatSize(sorted.reduce((sum, n) => sum + (n.size || 0), 0))}
                    {selectedFile ? ` · ${selectedFile.name} (${formatSize(selectedFile.size)})` : ''}
                </span>
                <span
                    title={`${mount}:${currentPath || '/'}`}
                    style={{
                        whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
                        flexShrink: 1, textAlign: 'right', minWidth: 50, maxWidth: '50%'
                    }}
                >
                    {mount}:{currentPath || '/'}
                </span>
            </div>}

            {/* ═══ Lightboxes ════════════════════════════════ */}
            <ImageLightbox
                isOpen={!!lightboxNode}
                onClose={closeLightbox}
                imageUrl={lightboxNode ? getFileUrl(lightboxNode) : ''}
                imageTitle={lightboxNode?.name || ''}
                currentIndex={lightboxIdx}
                totalCount={mediaNodes.length}
                onNavigate={(dir) => dir === 'prev' ? lightboxPrev() : lightboxNext()}
                showPrompt={false}
            />
            <LightboxText
                isOpen={!!textLightboxNode}
                onClose={closeTextLightbox}
                url={textLightboxNode ? getFileUrl(textLightboxNode) : ''}
                fileName={textLightboxNode?.name || ''}
            />
            <LightboxIframe
                isOpen={!!iframeLightboxNode}
                onClose={closeIframeLightbox}
                url={iframeLightboxNode ? getFileUrl(iframeLightboxNode) : ''}
                fileName={iframeLightboxNode?.name || ''}
            />

            {/* ── Dialogs ───────────────────────────────────────────── */}
            {filterDialogOpen && (
                <Dialog open={filterDialogOpen} onOpenChange={(open) => {
                    if (!open) {
                        setFilterDialogOpen(false);
                        setTimeout(() => containerRef.current?.focus(), 0);
                    }
                }}>
                    <DialogContent className="sm:max-w-md">
                        <DialogHeader>
                            <DialogTitle><T>Filter Current View</T></DialogTitle>
                            <DialogDescription>
                                <T>Enter a list of comma-separated wildcard matcher expressions (e.g., *.jpg, *.png) or use a preset below.</T>
                            </DialogDescription>
                        </DialogHeader>
                        <div className="grid gap-4 py-4">
                            <div className="flex items-center justify-between">
                                <Label htmlFor="showFolders" className="flex flex-col gap-1">
                                    <span><T>Show Folders</T></span>
                                    <span className="font-normal text-xs text-muted-foreground"><T>Keep subdirectories visible alongside matched files</T></span>
                                </Label>
                                <Switch
                                    id="showFolders"
                                    checked={tempShowFolders}
                                    onCheckedChange={setTempShowFolders}
                                />
                            </div>
                            <div className="grid gap-2">
                                <Label htmlFor="globPattern">Glob Pattern</Label>
                                <Input
                                    id="globPattern"
                                    value={tempGlob}
                                    onChange={(e) => setTempGlob(e.target.value)}
                                    onKeyDown={(e) => {
                                        if (e.key === 'Enter') {
                                            e.preventDefault();
                                            applyTempFilter();
                                        }
                                    }}
                                    autoFocus
                                    placeholder="*.*"
                                />
                            </div>
                            <div className="flex flex-wrap gap-2 mt-2">
                                <Badge variant="outline" className="cursor-pointer hover:bg-muted" onClick={() => setTempGlob('*.*')}>
                                    All Files (*.*)
                                </Badge>
                                <Badge variant="outline" className="cursor-pointer hover:bg-muted" onClick={() => setTempGlob(mediaGlob)}>
                                    Media
                                </Badge>
                                <Badge variant="outline" className="cursor-pointer hover:bg-muted" onClick={() => setTempGlob(codeGlob)}>
                                    Code
                                </Badge>
                            </div>
                        </div>
                        <div className="flex justify-end gap-3 w-full">
                            <Button variant="outline" onClick={() => {
                                setFilterDialogOpen(false);
                                setTimeout(() => containerRef.current?.focus(), 0);
                            }}>
                                Cancel
                            </Button>
                            <Button onClick={applyTempFilter}>
                                Apply Filter
                            </Button>
                        </div>
                    </DialogContent>
                </Dialog>
            )}

            {/* Search dialog */}
            {searchOpen && (
                <SearchDialog
                    mount={mount}
                    currentPath={currentPath}
                    accessToken={accessToken}
                    onNavigate={(node: INode) => {
                        const isDir = getMimeCategory(node) === 'dir';

                        if (isDir) {
                            updatePath(node.path.startsWith('/') ? node.path : `/${node.path}`);
                        } else {
                            const parentPath = node.parent || '/';

                            const currentTarget = parentPath.startsWith('/') ? parentPath : `/${parentPath}`;
                            const normalizedCurrent = currentPath.replace(/\/+$/, '') || '/';
                            const normalizedTarget = currentTarget.replace(/\/+$/, '') || '/';

                            if (normalizedTarget !== normalizedCurrent) {
                                setPendingSearchSelection(node.name);
                                updatePath(currentTarget);
                            } else {
                                const idx = sorted.findIndex(n => n.name === node.name);
                                if (idx >= 0) {
                                    const focusIndex = canGoUp ? idx + 1 : idx;
                                    setFocusIdx(focusIndex);
                                    const itemNode = sorted[idx];
                                    if (itemNode) {
                                        const newlySelected = [itemNode];
                                        setSelected(newlySelected);
                                        if (onSelect) {
                                            onSelect(newlySelected);
                                        }
                                        requestAnimationFrame(() => scrollItemIntoView(focusIndex));
                                    }
                                }
                            }
                        }
                    }}
                    onClose={() => {
                        setSearchOpen(false);
                        setTimeout(() => {
                            if (viewMode === 'tree') {
                                listRef.current?.focus();
                            } else {
                                containerRef.current?.focus();
                            }
                        }, 0);
                    }}
                />
            )}
        </div>
    );
};

export { FileBrowserPanel };
export default FileBrowserPanel;
