import React, { useCallback, useEffect, useState, useMemo } from 'react'
import IndexingModalWithMode from '../../components/IndexingModalWithMode'
import { PDFPreview } from '../../components/PDFPreview'
import { DragDropUpload } from '../../components/DragDropUpload'
import { GlobalDragDropOverlay } from '../../components/GlobalDragDropOverlay'
import {
    AppSettings,
    DEFAULT_MODELS,
    DEFAULT_SETTINGS,
    IndexingConfig,
    KnowledgeFile,
    ModelConfig,
    ModelType,
    RawFile,
    KnowledgeGroup,
} from '../../types'
import { readFile, formatBytes } from '../../utils/fileUtils'
import { useLanguage } from '../../contexts/LanguageContext'
import { useToast } from '../../contexts/ToastContext'
import { userSettingService } from '../../services/userSettingService'
import { uploadService } from '../../services/uploadService'
import { knowledgeBaseService } from '../../services/knowledgeBaseService'
import { knowledgeGroupService } from '../../services/knowledgeGroupService'
import { useConfirm } from '../../contexts/ConfirmContext'
import { ChunkInfoDrawer } from '../../components/ChunkInfoDrawer'
import {
    Search,
    Plus,
    FileText,
    Image as ImageIcon,
    FileType,
    CheckCircle2,
    CircleDashed,
    RefreshCw,
    Eye,
    Trash2,
    Settings,
    Folder,
    Hash,
    Tag,
    Layers,
    ChevronRight,
    ChevronDown,
    FolderInput,
    Box,
} from 'lucide-react'
import { motion, AnimatePresence } from 'framer-motion'
import { KB_ALLOWED_EXTENSIONS, IMAGE_MIME_TYPES, isExtensionAllowed, isFormatSupportedForPreview } from '../../constants/fileSupport'
import { ImportFolderDrawer } from '../../components/ImportFolderDrawer'
import { ImportTasksDrawer } from '../../components/drawers/ImportTasksDrawer'

interface KnowledgeBaseViewProps {
    authToken: string;
    onLogout: () => void;
    modelConfigs?: ModelConfig[];
    onNavigate: (view: any) => void;
    isAdmin?: boolean;
}

/** Flatten a tree of groups into a flat list (for file counts, filtering, etc.) */
function flattenGroups(groups: KnowledgeGroup[]): (KnowledgeGroup & { depth?: number })[] {
    const result: (KnowledgeGroup & { depth?: number })[] = [];
    function walk(items: KnowledgeGroup[], depth = 0) {
        for (const g of items) {
            result.push({ ...g, depth });
            if (g.children?.length) walk(g.children, depth + 1);
        }
    }
    walk(groups);
    return result;
}

/** Recursively collect all descendant group IDs (including self) */
function collectGroupIds(group: KnowledgeGroup): string[] {
    const ids = [group.id];
    if (group.children?.length) {
        for (const child of group.children) {
            ids.push(...collectGroupIds(child));
        }
    }
    return ids;
}

// ---- Tree node component ----
interface GroupTreeNodeProps {
    group: KnowledgeGroup;
    selectedGroupId?: string;
    onSelect: (groupId: string) => void;
    isAdmin: boolean;
    onEdit: (group: KnowledgeGroup) => void;
    onDelete: (group: KnowledgeGroup) => void;
    depth?: number;
}

const GroupTreeNode: React.FC<GroupTreeNodeProps> = ({
    group,
    selectedGroupId,
    onSelect,
    isAdmin,
    onEdit,
    onDelete,
    depth = 0,
}) => {
    const hasChildren = group.children && group.children.length > 0;
    const isSelected = selectedGroupId === group.id ||
        (hasChildren && group.children!.some(c => collectGroupIds(c).includes(selectedGroupId || '')));
    const [collapsed, setCollapsed] = useState(false);

    // Auto-expand if a child is selected
    useEffect(() => {
        if (selectedGroupId && hasChildren) {
            const allIds = collectGroupIds(group);
            if (allIds.includes(selectedGroupId)) setCollapsed(false);
        }
    }, [selectedGroupId]);

    return (
        <div>
            <div
                className={`group flex items-center justify-between rounded-lg transition-colors ${selectedGroupId === group.id ? 'bg-blue-50 text-blue-700' : 'text-slate-600 hover:bg-slate-50 hover:text-slate-900'}`}
                style={{ paddingLeft: `${depth * 12 + 12}px` }}
            >
                {/* Expand/collapse toggle */}
                <div className="flex items-center flex-1">
                    {hasChildren ? (
                        <button
                            onClick={(e) => { e.stopPropagation(); setCollapsed(c => !c); }}
                            className="p-0.5 mr-1 shrink-0 text-slate-400 hover:text-slate-700"
                        >
                            {collapsed ? <ChevronRight size={12} /> : <ChevronDown size={12} />}
                        </button>
                    ) : (
                        <span className="w-5 shrink-0" />
                    )}
                    <button
                        onClick={() => onSelect(group.id)}
                        className="flex-1 flex items-center gap-1.5 py-1.5 text-sm font-medium text-left whitespace-nowrap"
                    >
                        <Folder size={14} className={selectedGroupId === group.id ? 'text-blue-500 shrink-0' : 'text-slate-400 shrink-0'} />
                        <span>{group.name}</span>
                    </button>
                </div>

                {isAdmin && (
                    <div className="opacity-0 group-hover:opacity-100 flex items-center gap-0.5 pr-2 shrink-0">
                        <button
                            onClick={() => onEdit(group)}
                            className="p-1 text-slate-400 hover:text-blue-600 rounded"
                        >
                            <Settings size={11} />
                        </button>
                        <button
                            onClick={() => onDelete(group)}
                            className="p-1 text-slate-400 hover:text-red-500 rounded"
                        >
                            <Trash2 size={11} />
                        </button>
                    </div>
                )}
            </div>

            {/* Children */}
            {hasChildren && !collapsed && (
                <div>
                    {group.children!.map(child => (
                        <GroupTreeNode
                            key={child.id}
                            group={child}
                            selectedGroupId={selectedGroupId}
                            onSelect={onSelect}
                            isAdmin={isAdmin}
                            onEdit={onEdit}
                            onDelete={onDelete}
                            depth={depth + 1}
                        />
                    ))}
                </div>
            )}
        </div>
    );
};

// ---- Pagination component ----
interface PaginationProps {
    currentPage: number;
    totalPages: number;
    totalItems: number;
    pageSize: number;
    onPageChange: (page: number) => void;
    t: (key: string, ...args: any[]) => string;
}

const Pagination: React.FC<PaginationProps> = ({ currentPage, totalPages, totalItems, pageSize, onPageChange, t }) => {
    if (totalItems === 0) return null;
    const start = (currentPage - 1) * pageSize + 1;
    const end = Math.min(currentPage * pageSize, totalItems);
    return (
        <div className="px-8 py-4 border-t border-slate-200/60 bg-white/50 backdrop-blur-md flex items-center justify-center gap-2 shrink-0">
            <button
                onClick={() => onPageChange(Math.max(1, currentPage - 1))}
                disabled={currentPage === 1}
                className="p-2 border border-slate-200 rounded-lg hover:bg-slate-50 disabled:opacity-30 transition-all font-medium text-slate-600 text-sm"
            >
                {t('previous')}
            </button>
            <div className="px-3 py-2 text-sm font-semibold text-slate-700">
                {t('showingRange', start, end, totalItems)}
            </div>
            <button
                onClick={() => onPageChange(Math.min(totalPages, currentPage + 1))}
                disabled={currentPage === totalPages}
                className="p-2 border border-slate-200 rounded-lg hover:bg-slate-50 disabled:opacity-30 transition-all font-medium text-slate-600 text-sm"
            >
                {t('next')}
            </button>
        </div>
    );
};

export const KnowledgeBaseView: React.FC<KnowledgeBaseViewProps> = (props) => {
    const { authToken, modelConfigs = DEFAULT_MODELS, isAdmin = false } = props;
    const { showError, showWarning, showSuccess } = useToast()
    const { confirm } = useConfirm()
    const { t } = useLanguage()

    // Data State
    const [files, setFiles] = useState<KnowledgeFile[]>([])
    // groups is now a tree; flatGroups is the flattened version for lookups
    const [groups, setGroups] = useState<KnowledgeGroup[]>([])
    const flatGroups = useMemo(() => flattenGroups(groups), [groups])
    const [settings, setSettings] = useState<AppSettings>(DEFAULT_SETTINGS)
    const [isLoadingSettings, setIsLoadingSettings] = useState(true)
    const [isLoadingFiles, setIsLoadingFiles] = useState(true)

    // UI State
    const [pdfPreview, setPdfPreview] = useState<{ fileId: string; fileName: string } | null>(null)
    const [isIndexingModalOpen, setIsIndexingModalOpen] = useState(false)
    const [pendingFiles, setPendingFiles] = useState<RawFile[]>([])
    const [fileInputRef] = useState<React.RefObject<HTMLInputElement>>(React.createRef())
    const [shouldOpenModal, setShouldOpenModal] = useState(false)

    // Filter & Pagination State
    const [filterName, setFilterName] = useState('')
    const [filterStatus, setFilterStatus] = useState<'all' | 'ready' | 'indexing' | 'failed'>('all')
    const [currentPage, setCurrentPage] = useState(1)
    const pageSize = 12
    const [chunkDrawer, setChunkDrawer] = useState<{ isOpen: boolean; fileId: string; fileName: string } | null>(null)

    const [isAutoRefreshEnabled] = useState(true)
    const [autoRefreshInterval] = useState<number>(5000)

    // Sidebar State
    const [selectedSidebarFilter, setSelectedSidebarFilter] = useState<{ type: 'all' | 'uncategorized' | 'group'; groupId?: string }>({ type: 'all' })
    const [isGroupModalOpen, setIsGroupModalOpen] = useState(false)
    const [isImportDrawerOpen, setIsImportDrawerOpen] = useState(false);
    const [isImportTasksDrawerOpen, setIsImportTasksDrawerOpen] = useState(false);
    const [editingGroup, setEditingGroup] = useState<KnowledgeGroup | null>(null)
    const [newGroupName, setNewGroupName] = useState('')
    const [newGroupParentId, setNewGroupParentId] = useState<string | null>(null)

    const fetchAndSetSettings = useCallback(async () => {
        if (!authToken) return
        try {
            const settingsData = await userSettingService.get(authToken);
            setSettings({ ...DEFAULT_SETTINGS, ...settingsData })
        } catch (error) {
            console.error('Failed to fetch settings:', error)
        } finally {
            setIsLoadingSettings(false)
        }
    }, [authToken, isAdmin])

    const fetchAndSetFiles = useCallback(async () => {
        if (!authToken) return
        try {
            const remoteFiles = await knowledgeBaseService.getAll(authToken)
            setFiles(remoteFiles)
        } catch (error) {
            console.error('Failed to fetch files:', error)
        } finally {
            setIsLoadingFiles(false)
        }
    }, [authToken])

    const fetchAndSetGroups = useCallback(async () => {
        if (!authToken) return
        try {
            const remoteGroups = await knowledgeGroupService.getGroups()
            setGroups(remoteGroups)
        } catch (error) {
            console.error('Failed to fetch groups:', error)
        }
    }, [authToken])

    useEffect(() => {
        if (authToken) {
            fetchAndSetSettings()
            fetchAndSetFiles()
            fetchAndSetGroups()
        }
    }, [authToken, fetchAndSetSettings, fetchAndSetFiles, fetchAndSetGroups])

    useEffect(() => {
        if (shouldOpenModal && pendingFiles.length > 0) {
            setIsIndexingModalOpen(true);
            setShouldOpenModal(false);
        }
    }, [shouldOpenModal, pendingFiles.length]);

    const handleFileUpload = async (fileList: FileList) => {
        if (!authToken) {
            showWarning(t('loginRequired'))
            return
        }

        const MAX_FILE_SIZE = 104857600;
        const rawFiles: RawFile[] = []
        const errors: string[] = []

        const filesArray = Array.from(fileList);
        for (const file of filesArray) {
            const extension = file.name.split('.').pop() || ''
            if (!isExtensionAllowed(extension, 'kb')) {
                errors.push(t('unsupportedFileType', file.name, extension))
                continue
            }
            if (file.size > MAX_FILE_SIZE) {
                errors.push(t('fileSizeLimitExceeded', file.name, formatBytes(file.size), 100))
                continue;
            }
            try {
                const rawFile = await readFile(file)
                rawFiles.push(rawFile)
            } catch (error) {
                errors.push(`${file.name} - ${t('readingFailed')}`);
            }
        }

        if (errors.length > 0) showError(`${t('uploadErrors')}:\n${errors.join('\n')}`);
        if (rawFiles.length === 0) return;

        setPendingFiles(rawFiles);
        setShouldOpenModal(true);
    }

    const handleConfirmIndexing = async (config: IndexingConfig) => {
        if (!authToken) return
        let hasSuccess = false

        for (const rawFile of pendingFiles) {
            try {
                const indexingConfig = {
                    ...config,
                    groupIds: selectedSidebarFilter.type === 'group' ? [selectedSidebarFilter.groupId!] : []
                };
                await uploadService.uploadFileWithConfig(rawFile.file, indexingConfig, authToken)
                hasSuccess = true
            } catch (error: any) {
                showError(`${t('uploadFailed')}: ${rawFile.name} - ${error.message}`)
            }
        }
        if (hasSuccess) await fetchAndSetFiles()
        setPendingFiles([])
        setIsIndexingModalOpen(false)
    }

    const handleRemoveFile = async (id: string) => {
        if (!(await confirm(t('confirmDeleteFile')))) return
        if (!authToken) return
        try {
            await knowledgeBaseService.deleteFile(id, authToken)
            setFiles(prev => prev.filter(f => f.id !== id))
            showSuccess(t('fileDeleted'))
        } catch (error: any) {
            showError(`${t('deleteFailed')}: ` + error.message)
        }
    }

    const handleToggleFileCategory = async (file: KnowledgeFile, groupId: string) => {
        try {
            const currentGroupIds = file.groups?.map(g => g.id) || [];
            const isAssigned = currentGroupIds.includes(groupId);

            let newGroupIds: string[];
            if (isAssigned) {
                newGroupIds = currentGroupIds.filter(id => id !== groupId);
            } else {
                newGroupIds = [...currentGroupIds, groupId];
            }

            await knowledgeGroupService.addFileToGroups(file.id, newGroupIds);
            await fetchAndSetFiles();
        } catch (error: any) {
            console.error('Failed to toggle category:', error);
            showError(t('actionFailed') + ': ' + error.message);
        }
    }

    const handleClearAll = async () => {
        if (!(await confirm(t('confirmClearKB')))) return
        if (!authToken) return
        try {
            await knowledgeBaseService.clearAll(authToken)
            setFiles([])
            showSuccess(t('kbCleared'))
        } catch (error: any) {
            showError(`${t('clearFailed')}: ` + error.message)
        }
    }

    // Filtering: when a group is selected, include files in that group AND all descendant groups
    const filteredFiles = useMemo(() => {
        return files.filter(file => {
            const matchName = file.name.toLowerCase().includes(filterName.toLowerCase());

            let matchGroup = true;
            if (selectedSidebarFilter.type === 'uncategorized') {
                matchGroup = !file.groups || file.groups.length === 0;
            } else if (selectedSidebarFilter.type === 'group' && selectedSidebarFilter.groupId) {
                // Find the selected group in the tree to collect all descendant IDs
                const selectedGroup = flatGroups.find(g => g.id === selectedSidebarFilter.groupId);
                const allIds = selectedGroup ? collectGroupIds(selectedGroup) : [selectedSidebarFilter.groupId];
                matchGroup = file.groups?.some(g => allIds.includes(g.id)) || false;
            }

            const matchStatus = filterStatus === 'all' ||
                (filterStatus === 'ready' && (file.status === 'ready' || file.status === 'vectorized')) ||
                (filterStatus === 'indexing' && (file.status === 'indexing' || file.status === 'pending' || file.status === 'extracted')) ||
                (filterStatus === 'failed' && (file.status === 'failed' || file.status === 'error'));
            return matchName && matchGroup && matchStatus;
        });
    }, [files, filterName, selectedSidebarFilter, filterStatus, flatGroups]);

    const totalPages = Math.ceil(filteredFiles.length / pageSize);
    const paginatedFiles = useMemo(() => {
        const start = (currentPage - 1) * pageSize;
        return filteredFiles.slice(start, start + pageSize);
    }, [filteredFiles, currentPage, pageSize]);

    useEffect(() => {
        setCurrentPage(1);
    }, [filterName, filterStatus, selectedSidebarFilter]);

    useEffect(() => {
        let intervalId: NodeJS.Timeout | null = null;
        const hasIndexingFiles = files.some(file => ['pending', 'indexing', 'extracted', 'vectorized'].includes(file.status));

        if (isAutoRefreshEnabled && hasIndexingFiles) {
            intervalId = setInterval(() => {
                fetchAndSetFiles();
            }, autoRefreshInterval);
        }

        return () => { if (intervalId) clearInterval(intervalId); };
    }, [isAutoRefreshEnabled, files, autoRefreshInterval, fetchAndSetFiles]);

    const getFileIcon = (file: KnowledgeFile) => {
        if (file.type.startsWith('image/')) return <ImageIcon size={20} className="text-slate-500" />;
        if (file.type === 'application/pdf') return <FileType size={20} className="text-blue-500" />;
        return <FileText size={20} className="text-blue-500" />;
    };

    const handleCreateOrUpdateGroup = async () => {
        if (!newGroupName.trim()) return
        try {
            if (editingGroup) {
                await knowledgeGroupService.updateGroup(editingGroup.id, { name: newGroupName, parentId: newGroupParentId })
                showSuccess(t('groupUpdated'))
            } else {
                await knowledgeGroupService.createGroup({ name: newGroupName, parentId: newGroupParentId })
                showSuccess(t('groupCreated'))
            }
            fetchAndSetGroups()
            setIsGroupModalOpen(false)
            setEditingGroup(null)
            setNewGroupName('')
            setNewGroupParentId(null)
        } catch (error: any) {
            showError(t('actionFailed') + ': ' + error.message)
        }
    }

    const handleDeleteGroup = async (group: KnowledgeGroup) => {
        if (!(await confirm(t('confirmDeleteGroup').replace('$1', group.name)))) return
        try {
            await knowledgeGroupService.deleteGroup(group.id)
            showSuccess(t('groupDeleted'))
            if (selectedSidebarFilter.groupId === group.id) {
                setSelectedSidebarFilter({ type: 'all' })
            }
            fetchAndSetGroups()
        } catch (error: any) {
            showError(t('deleteFailed') + ': ' + error.message)
        }
    }

    const openCreateGroup = (parentId?: string | null) => {
        setEditingGroup(null);
        setNewGroupName('');
        setNewGroupParentId(parentId ?? null);
        setIsGroupModalOpen(true);
    }

    const openEditGroup = (group: KnowledgeGroup) => {
        setEditingGroup(group);
        setNewGroupName(group.name);
        setNewGroupParentId(group.parentId ?? null);
        setIsGroupModalOpen(true);
    }

    const selectedGroupObj = selectedSidebarFilter.type === 'group'
        ? flatGroups.find(g => g.id === selectedSidebarFilter.groupId)
        : null;

    if (isLoadingSettings) {
        return (
            <div className='flex items-center justify-center min-h-[400px] w-full'>
                <div className='text-blue-600 animate-spin rounded-full h-8 w-8 border-2 border-t-transparent border-blue-600'></div>
            </div>
        )
    }

    return (
        <div className='flex flex-row h-full w-full bg-slate-50 overflow-hidden'>
            {/* Sidebar */}
            <div className="w-64 bg-white border-r border-slate-200 flex flex-col shrink-0">
                <div className="p-6 flex flex-col min-h-0">
                    <h2 className="text-sm font-semibold text-slate-400 uppercase tracking-wider mb-4">{t('navCatalog')}</h2>
                    <nav className="space-y-1">
                        <button
                            onClick={() => setSelectedSidebarFilter({ type: 'all' })}
                            className={`w-full flex items-center justify-between px-3 py-2 rounded-lg text-sm font-medium transition-colors ${selectedSidebarFilter.type === 'all' ? 'bg-blue-50 text-blue-700' : 'text-slate-600 hover:bg-slate-50 hover:text-slate-900'}`}
                        >
                            <div className="flex items-center gap-2">
                                <Layers size={16} />
                                <span>{t('allDocuments')}</span>
                            </div>
                            <span className="text-xs bg-slate-100 text-slate-500 px-1.5 py-0.5 rounded-full">{files.length}</span>
                        </button>
                        <button
                            onClick={() => setSelectedSidebarFilter({ type: 'uncategorized' })}
                            className={`w-full flex items-center justify-between px-3 py-2 rounded-lg text-sm font-medium transition-colors ${selectedSidebarFilter.type === 'uncategorized' ? 'bg-blue-50 text-blue-700' : 'text-slate-600 hover:bg-slate-50 hover:text-slate-900'}`}
                        >
                            <div className="flex items-center gap-2">
                                <FileText size={16} />
                                <span>{t('uncategorized')}</span>
                            </div>
                            <span className="text-xs bg-slate-100 text-slate-500 px-1.5 py-0.5 rounded-full">
                                {files.filter(f => !f.groups || f.groups.length === 0).length}
                            </span>
                        </button>
                    </nav>

                    <div className="mt-6 flex items-center justify-between mb-3">
                        <h2 className="text-sm font-semibold text-slate-400 uppercase tracking-wider">{t('categories')}</h2>
                        {isAdmin && (
                            <button
                                onClick={() => openCreateGroup(null)}
                                className="p-1 text-slate-400 hover:text-blue-600 hover:bg-blue-50 rounded transition-all"
                                title={t('createCategory') as string}
                            >
                                <Plus size={14} />
                            </button>
                        )}
                    </div>

                    <div className="space-y-0.5 overflow-y-auto overflow-x-auto flex-1 pr-1 pb-4">
                        {groups.map(group => (
                            <GroupTreeNode
                                key={group.id}
                                group={group}
                                selectedGroupId={selectedSidebarFilter.type === 'group' ? selectedSidebarFilter.groupId : undefined}
                                onSelect={(gId) => setSelectedSidebarFilter({ type: 'group', groupId: gId })}
                                isAdmin={isAdmin}
                                onEdit={openEditGroup}
                                onDelete={handleDeleteGroup}
                                depth={0}
                            />
                        ))}
                    </div>
                </div>
            </div>

            {/* Main Content Area */}
            <div className='flex flex-col flex-1 h-full w-full bg-transparent overflow-hidden'>
                <input
                    type="file"
                    ref={fileInputRef}
                    onChange={(e) => {
                        if (e.target.files && e.target.files.length > 0) handleFileUpload(e.target.files)
                    }}
                    multiple
                    className="hidden"
                    accept={KB_ALLOWED_EXTENSIONS.map(ext => `.${ext}`).join(',') + ',' + IMAGE_MIME_TYPES.join(',')}
                />

                <GlobalDragDropOverlay onFilesSelected={handleFileUpload} isAdmin={isAdmin} />

                {/* Header Section */}
                <div className="px-8 pt-8 pb-6 flex items-start justify-between shrink-0">
                    <div>
                        <h1 className="text-2xl font-bold text-slate-900 leading-tight">
                            {selectedSidebarFilter.type === 'all' ? t('kbManagement') :
                                selectedSidebarFilter.type === 'uncategorized' ? t('uncategorizedFiles') :
                                    selectedGroupObj?.name || t('category')}
                        </h1>
                        <p className="text-[15px] text-slate-500 mt-1">
                            {selectedSidebarFilter.type === 'group'
                                ? selectedGroupObj?.description || t('kbManagementDesc')
                                : t('kbManagementDesc')}
                        </p>
                    </div>
                    <div className="flex items-center gap-3">
                        {isAdmin && (
                            <>
                                {selectedSidebarFilter.type === 'group' && (
                                    <button
                                        onClick={() => openCreateGroup(selectedSidebarFilter.groupId)}
                                        className="flex items-center gap-2 px-4 py-2.5 bg-white border border-slate-200 text-slate-700 rounded-lg shadow-sm transition-all font-semibold text-sm active:scale-95 hover:bg-slate-50"
                                    >
                                        <Plus size={16} />
                                        {t('addSubcategory')}
                                    </button>
                                )}
                                <button
                                    onClick={() => setIsImportTasksDrawerOpen(true)}
                                    className="flex items-center gap-2 px-4 py-2.5 bg-white border border-slate-200 text-slate-700 rounded-lg shadow-sm transition-all font-semibold text-sm active:scale-95 hover:bg-slate-50"
                                >
                                    <Box size={18} className="text-indigo-600" />
                                    {t('importTasksTitle')}
                                </button>
                                <button
                                    onClick={() => setIsImportDrawerOpen(true)}
                                    className="flex items-center gap-2 px-4 py-2.5 bg-white border border-slate-200 text-slate-700 rounded-lg shadow-sm transition-all font-semibold text-sm active:scale-95 hover:bg-slate-50"
                                >
                                    <FolderInput size={18} className="text-blue-600" />
                                    {t('importFolder')}
                                </button>
                                <button
                                    onClick={() => fileInputRef.current?.click()}
                                    className="flex items-center gap-2 px-5 py-2.5 bg-blue-600 hover:bg-blue-700 text-white rounded-lg shadow-sm shadow-blue-100 transition-all font-semibold text-sm active:scale-95"
                                >
                                    <Plus size={18} />
                                    {t('addFile')}
                                </button>
                            </>
                        )}
                    </div>
                </div>

                {/* Filter Bar */}
                <div className="px-8 pb-6 flex items-center justify-between gap-4 shrink-0">
                    <div className="flex items-center gap-3 flex-1">
                        <div className="relative max-w-xs w-full">
                            <Search className="absolute left-3 top-1/2 -translate-y-1/2 text-slate-400" size={16} />
                            <input
                                type="text"
                                placeholder={t('searchPlaceholder')}
                                value={filterName}
                                onChange={(e) => setFilterName(e.target.value)}
                                className="w-full h-9 pl-9 pr-4 bg-white border border-slate-200 rounded-lg text-sm transition-all focus:ring-1 focus:ring-blue-500 focus:border-blue-500 outline-none"
                            />
                        </div>
                    </div>
                    <div className="flex items-center gap-3">
                        <button
                            onClick={() => fetchAndSetFiles()}
                            className="p-2 text-slate-400 hover:text-blue-600 hover:bg-blue-50 rounded-lg transition-all"
                            title="Refresh"
                        >
                            <RefreshCw size={18} />
                        </button>
                    </div>
                </div>

                {/* File List */}
                <div className="flex-1 overflow-y-auto px-8 pb-4">
                    {isLoadingFiles ? (
                        <div className="flex flex-col items-center justify-center py-20 gap-4">
                            <div className="w-10 h-10 border-2 border-blue-600 border-t-transparent rounded-full animate-spin"></div>
                        </div>
                    ) : paginatedFiles.length > 0 ? (
                        <div className="flex flex-col gap-3">
                            <AnimatePresence mode="popLayout">
                                {paginatedFiles.map((file) => (
                                    <motion.div
                                        key={file.id}
                                        layout
                                        initial={{ opacity: 0, y: 10 }}
                                        animate={{ opacity: 1, y: 0 }}
                                        exit={{ opacity: 0, scale: 0.95 }}
                                        className="bg-white rounded-xl border border-slate-200/80 p-4 shadow-sm hover:shadow-md transition-all group relative flex items-center gap-4"
                                    >
                                        {/* Icon */}
                                        <div className="p-2.5 bg-blue-50 rounded-lg text-blue-600 shadow-sm border border-blue-100/30 shrink-0">
                                            {getFileIcon(file)}
                                        </div>

                                        {/* Name & Desc */}
                                        <div className="flex-1 min-w-0">
                                            <div className="flex items-center gap-3 mb-1">
                                                <h3
                                                    onClick={() => setChunkDrawer({ isOpen: true, fileId: file.id, fileName: file.name })}
                                                    className="font-bold text-slate-900 text-[15px] cursor-pointer hover:text-blue-600 transition-colors truncate"
                                                >
                                                    {file.name}
                                                </h3>
                                                <span className="px-2 py-0.5 bg-slate-100 text-slate-500 rounded text-[10px] font-bold tracking-wider uppercase shrink-0">
                                                    {file.name.split('.').pop()?.toUpperCase() || 'FILE'}
                                                </span>
                                            </div>
                                            <div className="flex items-center gap-2">
                                                <p className="text-[13px] text-slate-500 truncate">
                                                    {file.status === 'ready' || file.status === 'vectorized'
                                                        ? t('statusReadyDesc')
                                                        : t('statusIndexingDesc', file.status)
                                                    }
                                                </p>
                                                {file.groups && file.groups.length > 0 && (
                                                    <div className="flex gap-1 ml-2">
                                                        {file.groups.map(g => (
                                                            <span key={g.id} className="text-[10px] px-1.5 py-0.5 bg-blue-50 text-blue-600 rounded-full border border-blue-100">
                                                                {g.name}
                                                            </span>
                                                        ))}
                                                    </div>
                                                )}
                                            </div>
                                        </div>

                                        {/* Meta & Actions */}
                                        <div className="flex items-center gap-6 shrink-0">
                                            <div className="text-[12px] font-medium text-slate-400 flex flex-col items-end">
                                                <span>{new Date(file.createdAt || Date.now()).toLocaleDateString()}</span>
                                                <span>{formatBytes(file.size)}</span>
                                            </div>

                                            <div className="flex items-center gap-2">
                                                {file.status !== 'ready' && file.status !== 'vectorized' ? (
                                                    <CircleDashed size={16} className="text-blue-400 animate-spin mr-2" />
                                                ) : null}
                                            </div>

                                            <div className="flex items-center gap-1 opacity-100 md:opacity-0 group-hover:opacity-100 transition-opacity">
                                                {isFormatSupportedForPreview(file.name) && (
                                                    <button onClick={() => setPdfPreview({ fileId: file.id, fileName: file.name })} className="p-1.5 text-slate-400 hover:text-blue-600 rounded-md bg-slate-50" title={t('preview') as string || 'Preview'}>
                                                        <Eye size={16} />
                                                    </button>
                                                )}
                                                <div className="relative group/tag">
                                                    <button className="p-1.5 text-slate-400 hover:text-blue-600 rounded-md bg-slate-50" title={t('groups') as string || 'Groups'}>
                                                        <Tag size={16} />
                                                    </button>
                                                    <div className="absolute right-0 top-full mt-1 w-52 bg-white border border-slate-200 rounded-lg shadow-lg opacity-0 invisible group-hover/tag:opacity-100 group-hover/tag:visible transition-all z-20 overflow-hidden">
                                                        <div className="p-2 border-b border-slate-100 bg-slate-50 text-[10px] font-bold text-slate-400 uppercase tracking-wider">
                                                            {t('selectCategory')}
                                                        </div>
                                                        <div className="max-h-48 overflow-y-auto">
                                                            <button
                                                                onClick={() => knowledgeGroupService.addFileToGroups(file.id, []).then(fetchAndSetFiles)}
                                                                className="w-full text-left px-3 py-2 text-xs text-slate-600 hover:bg-slate-50 flex items-center gap-2"
                                                            >
                                                                <Layers size={12} />
                                                                {t('noneUncategorized')}
                                                            </button>
                                                            {flatGroups.map(g => (
                                                                <button
                                                                    key={g.id}
                                                                    onClick={() => handleToggleFileCategory(file, g.id)}
                                                                    style={{ paddingLeft: `${(g.depth || 0) * 12 + 12}px` }}
                                                                    className="w-full text-left pr-3 py-2 text-xs text-slate-600 hover:bg-slate-50 border-t border-slate-50 flex items-center justify-between"
                                                                >
                                                                    <div className="flex items-center gap-1.5 truncate">
                                                                        <Hash size={12} className={file.groups?.some(fg => fg.id === g.id) ? 'text-blue-500 shrink-0' : 'text-slate-400 shrink-0'} />
                                                                        <span className={file.groups?.some(fg => fg.id === g.id) ? 'text-blue-600 font-medium truncate' : 'truncate'}>{g.name}</span>
                                                                    </div>
                                                                    {file.groups?.some(fg => fg.id === g.id) && <CheckCircle2 size={12} className="text-blue-600 shrink-0 ml-2" />}
                                                                </button>
                                                            ))}
                                                        </div>
                                                    </div>
                                                </div>
                                                {isAdmin && (
                                                    <button onClick={() => handleRemoveFile(file.id)} className="p-1.5 text-slate-400 hover:text-red-500 rounded-md bg-slate-50" title={t('delete') as string || 'Delete'}>
                                                        <Trash2 size={16} />
                                                    </button>
                                                )}
                                            </div>
                                        </div>
                                    </motion.div>
                                ))}
                            </AnimatePresence>
                        </div>
                    ) : (
                        <div className="max-w-4xl mx-auto w-full pt-12">
                            <DragDropUpload onFilesSelected={handleFileUpload} isAdmin={isAdmin} />
                        </div>
                    )}
                </div>

                {/* Pagination */}
                <Pagination
                    currentPage={currentPage}
                    totalPages={totalPages}
                    totalItems={filteredFiles.length}
                    pageSize={pageSize}
                    onPageChange={setCurrentPage}
                    t={t}
                />
            </div>

            <IndexingModalWithMode
                isOpen={isIndexingModalOpen}
                onClose={() => { setPendingFiles([]); setIsIndexingModalOpen(false); }}
                files={pendingFiles}
                embeddingModels={modelConfigs.filter(m => m.type === ModelType.EMBEDDING)}
                defaultEmbeddingId={settings.selectedEmbeddingId}
                onConfirm={handleConfirmIndexing}
                authToken={authToken}
            />

            {/* Group Create/Edit Modal */}
            <AnimatePresence>
                {isGroupModalOpen && (
                    <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-slate-900/40 backdrop-blur-sm">
                        <motion.div
                            initial={{ opacity: 0, scale: 0.95 }}
                            animate={{ opacity: 1, scale: 1 }}
                            exit={{ opacity: 0, scale: 0.95 }}
                            className="bg-white rounded-2xl shadow-xl w-full max-w-md overflow-hidden"
                        >
                            <div className="p-6">
                                <h2 className="text-xl font-bold text-slate-900 mb-2">
                                    {editingGroup ? t('editCategory') : t('createCategory')}
                                </h2>
                                <p className="text-slate-500 text-sm mb-6">
                                    {t('categoryDesc')}
                                </p>

                                <div className="space-y-4">
                                    <div>
                                        <label className="block text-sm font-medium text-slate-700 mb-1">{t('categoryName')}</label>
                                        <input
                                            type="text"
                                            value={newGroupName}
                                            onChange={(e) => setNewGroupName(e.target.value)}
                                            placeholder={t('exampleResearch')}
                                            className="w-full h-11 px-4 bg-slate-50 border border-slate-200 rounded-xl outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all"
                                            autoFocus
                                            onKeyDown={(e) => e.key === 'Enter' && handleCreateOrUpdateGroup()}
                                        />
                                    </div>

                                    {/* Parent category selector */}
                                    <div>
                                        <label className="block text-sm font-medium text-slate-700 mb-1">{t('parentCategory')}</label>
                                        <select
                                            value={newGroupParentId ?? ''}
                                            onChange={(e) => setNewGroupParentId(e.target.value || null)}
                                            className="w-full h-11 px-4 bg-slate-50 border border-slate-200 rounded-xl outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all text-sm"
                                        >
                                            <option value="">{t('noParentTopLevel')}</option>
                                            {flatGroups
                                                .filter(g => g.id !== editingGroup?.id) // don't allow self as parent
                                                .map(g => (
                                                    <option key={g.id} value={g.id}>
                                                        {'\u00A0'.repeat((g.depth || 0) * 4)}{g.name}
                                                    </option>
                                                ))}
                                        </select>
                                    </div>
                                </div>
                            </div>

                            <div className="px-6 py-4 bg-slate-50 border-t border-slate-100 flex justify-end gap-3">
                                <button
                                    onClick={() => { setIsGroupModalOpen(false); setEditingGroup(null); setNewGroupParentId(null); }}
                                    className="px-4 py-2 text-slate-600 font-medium hover:bg-slate-200/50 rounded-lg transition-all"
                                >
                                    {t('cancel')}
                                </button>
                                <button
                                    onClick={handleCreateOrUpdateGroup}
                                    className="px-6 py-2 bg-blue-600 hover:bg-blue-700 text-white font-bold rounded-lg shadow-sm transition-all active:scale-95"
                                >
                                    {editingGroup ? t('saveChanges') : t('createCategoryBtn')}
                                </button>
                            </div>
                        </motion.div>
                    </div>
                )}
            </AnimatePresence>

            {pdfPreview && (
                <PDFPreview
                    fileId={pdfPreview.fileId}
                    fileName={pdfPreview.fileName}
                    authToken={authToken}
                    onClose={() => setPdfPreview(null)}
                />
            )}

            {chunkDrawer && (
                <ChunkInfoDrawer
                    isOpen={chunkDrawer.isOpen}
                    onClose={() => setChunkDrawer(null)}
                    fileId={chunkDrawer.fileId}
                    fileName={chunkDrawer.fileName}
                    authToken={authToken}
                />
            )}

            <ImportFolderDrawer
                isOpen={isImportDrawerOpen}
                onClose={() => setIsImportDrawerOpen(false)}
                authToken={authToken}
                onImportSuccess={() => fetchAndSetFiles()}
            />

            <ImportTasksDrawer
                isOpen={isImportTasksDrawerOpen}
                onClose={() => setIsImportTasksDrawerOpen(false)}
                authToken={authToken}
            />
        </div>
    )
}
