import React, { useEffect, useState, useCallback, useMemo } from 'react'
import { ArrowLeft, Plus, MessageSquare, BookOpen, Trash2, Eye, FileText, FileType, Image as ImageIcon, Search, RefreshCw } from 'lucide-react'
import { KnowledgeGroup, KnowledgeFile } from '../../types'
import { knowledgeBaseService } from '../../services/knowledgeBaseService'
import { modelConfigService } from '../../services/modelConfigService'
import { uploadService } from '../../services/uploadService'
import { knowledgeGroupService } from '../../services/knowledgeGroupService'
import { useToast } from '../../contexts/ToastContext'
import { useConfirm } from '../../contexts/ConfirmContext'
import { RawFile, IndexingConfig, ModelConfig } from '../../types'
import IndexingModalWithMode from '../IndexingModalWithMode'
import { PDFPreview } from '../PDFPreview'
import { NotebookGlobalDragDropOverlay } from '../NotebookGlobalDragDropOverlay'
import { useLanguage } from '../../contexts/LanguageContext'
import { readFile, formatBytes } from '../../utils/fileUtils'
import { isExtensionAllowed, isFormatSupportedForPreview } from '../../constants/fileSupport'
import { motion, AnimatePresence } from 'framer-motion'

interface NotebookDetailViewProps {
    authToken: string;
    notebook: KnowledgeGroup;
    onBack: () => void;
    onChatWithContext?: (context: { selectedGroups?: string[], selectedFiles?: string[] }) => void;
    isAdmin?: boolean;
}

export const NotebookDetailView: React.FC<NotebookDetailViewProps> = ({ authToken, notebook, onBack, onChatWithContext, isAdmin = false }) => {
    const [files, setFiles] = useState<KnowledgeFile[]>([])
    const [isLoading, setIsLoading] = useState(false)
    const { showError, showSuccess } = useToast()
    const { confirm } = useConfirm()
    const { t } = useLanguage()

    const [isIndexingModalOpen, setIsIndexingModalOpen] = useState(false)
    const [pendingFiles, setPendingFiles] = useState<RawFile[]>([])
    const [shouldOpenModal, setShouldOpenModal] = useState(false)
    const [models, setModels] = useState<ModelConfig[]>([])
    const [pdfPreview, setPdfPreview] = useState<{ fileId: string; fileName: string } | null>(null)
    const [filterName, setFilterName] = useState('')

    const fileInputRef = React.useRef<HTMLInputElement>(null)

    useEffect(() => {
        const fetchModels = async () => {
            try {
                const res = await modelConfigService.getAll(authToken)
                setModels(res)
            } catch (error) {
                console.error('Failed to fetch models', error)
            }
        }
        if (authToken) fetchModels()
    }, [authToken])

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

    const loadData = useCallback(async () => {
        setIsLoading(true)
        try {
            const allFiles = await knowledgeBaseService.getAll(authToken)
            const notebookFiles = allFiles.filter(f => f.groups?.some(g => g.id === notebook.id))
            setFiles(notebookFiles)
        } catch (error) {
            console.error(error)
            showError(t('errorLoadData'))
        } finally {
            setIsLoading(false)
        }
    }, [authToken, notebook.id, t, showError])

    useEffect(() => {
        loadData()
    }, [loadData])

    const handleFileUpload = async (fileList: FileList | File[]) => {
        if (!fileList || fileList.length === 0) return
        const errors: string[] = []
        const newPendingFiles: RawFile[] = []

        for (let i = 0; i < fileList.length; i++) {
            const file = fileList[i]
            try {
                if (file.size > 104857600) {
                    errors.push(`${file.name} - ${t('fileSizeLimitExceeded', file.name, formatBytes(file.size), 100)}`)
                    continue
                }
                const extension = file.name.split('.').pop() || ''
                if (!isExtensionAllowed(extension, 'group')) {
                    if (!(await confirm(t('confirmUnsupportedFile', extension || t('unknown'))))) continue
                }
                const rawFile = await readFile(file)
                newPendingFiles.push(rawFile)
            } catch (error: any) {
                errors.push(`${file.name} - ${t('readingFailed')}`)
            }
        }

        if (errors.length > 0) showError(`${t('uploadErrors')}:\n${errors.join('\n')}`)
        if (newPendingFiles.length > 0) {
            setPendingFiles(prev => [...prev, ...newPendingFiles])
            setShouldOpenModal(true)
        }
    }

    const handleConfirmIndexing = async (config: IndexingConfig) => {
        setIsIndexingModalOpen(false)
        try {
            for (const rawFile of pendingFiles) {
                const uploadRes = await uploadService.uploadFileWithConfig(rawFile.file, config, authToken)
                if (uploadRes && uploadRes.id) {
                    await knowledgeGroupService.addFileToGroups(uploadRes.id, [notebook.id])
                }
            }
            showSuccess(t('successUploadFile'))
            loadData()
        } catch (error: any) {
            showError(t('errorUploadFile', error.message || t('unknownError')))
        } finally {
            setPendingFiles([])
        }
    }

    const handleRemoveFile = async (fileId: string, fileName: string) => {
        if (!(await confirm(t('confirmRemoveFileFromGroup', fileName)))) return;
        try {
            await knowledgeGroupService.removeFileFromGroup(fileId, notebook.id);
            setFiles(prev => prev.filter(f => f.id !== fileId));
            showSuccess(t('fileDeleted'));
        } catch (error) {
            showError(t('deleteFailed'));
        }
    }

    const filteredFiles = useMemo(() => {
        return files.filter(file => file.name.toLowerCase().includes(filterName.toLowerCase()));
    }, [files, filterName]);

    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" />;
    };

    return (
        <div className="flex flex-col h-full bg-transparent overflow-hidden">
            <NotebookGlobalDragDropOverlay onFilesSelected={handleFileUpload} isAdmin={isAdmin} />
            <input
                type="file"
                ref={fileInputRef}
                onChange={(e) => e.target.files && handleFileUpload(e.target.files)}
                multiple
                className="hidden"
            />

            {/* Header */}
            <div className="px-8 pt-8 pb-6 flex items-start justify-between shrink-0">
                <div className="flex items-start gap-4 min-w-0">
                    <button
                        onClick={onBack}
                        className="mt-1 p-2 text-slate-400 hover:text-slate-600 hover:bg-slate-100 rounded-lg transition-colors active:scale-90"
                    >
                        <ArrowLeft size={20} />
                    </button>
                    <div className="min-w-0">
                        <div className="flex items-center gap-2">
                            <div className="p-1.5 bg-blue-50 rounded-lg text-blue-600 border border-blue-100/30">
                                <BookOpen size={18} />
                            </div>
                            <h1 className="text-2xl font-bold text-slate-900 truncate leading-tight">
                                {notebook.name}
                            </h1>
                        </div>
                        <p className="text-[15px] text-slate-500 mt-1 truncate max-w-2xl">
                            {notebook.description || t('browseManageFiles')}
                        </p>
                    </div>
                </div>
                <div className="flex items-center gap-3">
                    <button
                        onClick={() => onChatWithContext?.({ selectedGroups: [notebook.id] })}
                        className="flex items-center gap-2 px-5 py-2.5 bg-white border border-slate-200 text-slate-700 rounded-lg font-semibold text-sm hover:bg-slate-50 transition-all shadow-sm"
                    >
                        <MessageSquare size={18} className="text-blue-600" />
                        {t('chatWithGroup')}
                    </button>
                    {isAdmin && (
                        <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="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('filterGroupFiles')}
                        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>
                <button
                    onClick={() => loadData()}
                    className="p-2 text-slate-400 hover:text-blue-600 hover:bg-blue-50 rounded-lg transition-all"
                >
                    <RefreshCw size={18} />
                </button>
            </div>

            {/* Content Area */}
            <div className="flex-1 overflow-y-auto px-8 pb-8">
                {isLoading ? (
                    <div className="flex items-center justify-center py-20">
                        <div className="w-8 h-8 border-2 border-blue-600 border-t-transparent rounded-full animate-spin"></div>
                    </div>
                ) : filteredFiles.length > 0 ? (
                    <div className="flex flex-col gap-3">
                        <AnimatePresence mode="popLayout">
                            {filteredFiles.map((file) => (
                                <motion.div
                                    key={file.id}
                                    layout
                                    initial={{ opacity: 0, y: 10 }}
                                    animate={{ opacity: 1, y: 0 }}
                                    className="bg-white rounded-xl border border-slate-200/80 p-4 shadow-sm hover:shadow-md transition-all group relative overflow-hidden 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>

                                    {/* Main info */}
                                    <div className="flex-1 min-w-0">
                                        <div className="flex items-center gap-3 mb-1">
                                            <h3 className="font-bold text-slate-900 text-[15px] 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.status}
                                            </span>
                                        </div>
                                    </div>

                                    {/* Meta info & 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>{formatBytes(file.size)}</span>
                                            <span className="text-[10px] font-bold text-slate-300 uppercase tracking-widest mt-0.5">
                                                {file.name.split('.').pop()?.toUpperCase() || 'FILE'}
                                            </span>
                                        </div>

                                        <div className="flex items-center gap-1 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">
                                                    <Eye size={16} />
                                                </button>
                                            )}
                                            {isAdmin && (
                                                <button onClick={() => handleRemoveFile(file.id, file.name)} className="p-1.5 text-slate-400 hover:text-red-500 rounded-md bg-slate-50">
                                                    <Plus size={16} className="rotate-45" />
                                                </button>
                                            )}
                                        </div>
                                    </div>
                                </motion.div>
                            ))}
                        </AnimatePresence>
                    </div>
                ) : (
                    <div className="flex flex-col items-center justify-center py-32 border-2 border-dashed border-slate-200 rounded-2xl bg-white/50 text-center">
                        <BookOpen className="w-12 h-12 text-slate-200 mx-auto mb-4" />
                        <h3 className="text-slate-900 font-bold">{t('noFiles')}</h3>
                        <p className="text-slate-500 text-sm mt-1">{t('noFilesDesc')}</p>
                    </div>
                )}
            </div>

            <IndexingModalWithMode
                isOpen={isIndexingModalOpen}
                onClose={() => { setPendingFiles([]); setIsIndexingModalOpen(false); }}
                files={pendingFiles}
                embeddingModels={models.filter(m => m.type === 'embedding')}
                defaultEmbeddingId={models.find(m => m.isDefault)?.id || ''}
                onConfirm={handleConfirmIndexing}
                authToken={authToken}
            />

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