/**
 * 文件上传面板 - 异步上传 + 轮询方案
 */
import React, { useState, useRef, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import { Progress } from '@/components/ui/progress';
import { Input } from '@/components/ui/input';
import {
    AlertDialog,
    AlertDialogAction,
    AlertDialogCancel,
    AlertDialogContent,
    AlertDialogDescription,
    AlertDialogFooter,
    AlertDialogHeader,
    AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { Upload, X, File as FileIcon, CheckCircle, AlertCircle } from 'lucide-react';
import { submitAsyncUpload, getUploadTaskStatus, cancelUploadTask, pathUtils, browseDirectory } from '@/services/fileService';
import type { UploadTaskStatus } from '@/services/fileService';
import { message } from 'antd';
import type { UploadPanelProps } from './types';

// 本地扩展的上传文件项类型
interface UploadFileItem {
    file: File;
    id: string;
    status: 'pending' | 'uploading' | 'success' | 'error';
    progress: number;
    taskId?: string;  // 异步上传任务ID
    errorMessage?: string;
}

export const UploadPanel: React.FC<UploadPanelProps> = ({
    serverId,
    currentPath,
    onUploadComplete,
}) => {
    const [uploadFiles, setUploadFiles] = useState<UploadFileItem[]>([]);
    const [isDragging, setIsDragging] = useState(false);
    const [confirmDialogOpen, setConfirmDialogOpen] = useState(false);
    const [pendingOverwriteItem, setPendingOverwriteItem] = useState<UploadFileItem | null>(null);
    const [renameFileName, setRenameFileName] = useState<string>(''); // 重命名的新文件名
    const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false);
    const [pendingDeleteId, setPendingDeleteId] = useState<string | null>(null);
    const [clearConfirmOpen, setClearConfirmOpen] = useState(false);
    const fileInputRef = useRef<HTMLInputElement>(null);
    const pollIntervalsRef = useRef<Map<string, NodeJS.Timeout>>(new Map()); // 保存所有轮询定时器

    // 组件卸载时清理所有定时器
    useEffect(() => {
        return () => {
            pollIntervalsRef.current.forEach(interval => clearInterval(interval));
            pollIntervalsRef.current.clear();
        };
    }, []);

    // 格式化文件大小
    const formatFileSize = (bytes: number): string => {
        if (bytes === 0) return '0 B';
        const k = 1024;
        const sizes = ['B', 'KB', 'MB', 'GB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return (bytes / Math.pow(k, i)).toFixed(2) + ' ' + sizes[i];
    };

    // 添加文件到上传列表
    const addFiles = (files: FileList | null) => {
        if (!files || files.length === 0) return;

        const newFiles: UploadFileItem[] = Array.from(files).map(file => ({
            file,
            id: `${file.name}-${Date.now()}-${Math.random()}`,
            status: 'pending',
            progress: 0,
        }));

        setUploadFiles(prev => [...prev, ...newFiles]);
    };

    // 请求删除文件（弹出确认框）
    const requestRemoveFile = (id: string) => {
        const item = uploadFiles.find(f => f.id === id);
        // 正在上传的需要确认
        if (item?.status === 'uploading') {
            setPendingDeleteId(id);
            setDeleteConfirmOpen(true);
        } else {
            // 其他状态直接删除
            doRemoveFile(id);
        }
    };

    // 实际执行删除文件或取消上传
    const doRemoveFile = async (id: string) => {
        const item = uploadFiles.find(f => f.id === id);
        
        // 如果正在上传，先取消任务
        if (item?.status === 'uploading' && item.taskId) {
            try {
                const cancelled = await cancelUploadTask(serverId, item.taskId);
                if (cancelled) {
                    message.success('上传已取消');
                } else {
                    message.error('取消上传失败：任务未能成功取消');
                    return; // 取消失败，不移除文件
                }
            } catch (error: any) {
                console.error('取消上传失败:', error);
                message.error(error.response?.data?.message || '取消上传失败');
                return; // 出错，不移除文件
            }
        }
        
        // 停止轮询
        const interval = pollIntervalsRef.current.get(id);
        if (interval) {
            clearInterval(interval);
            pollIntervalsRef.current.delete(id);
        }
        
        // 移除文件
        setUploadFiles(prev => prev.filter(f => f.id !== id));
    };

    // 确认删除
    const handleConfirmDelete = async () => {
        setDeleteConfirmOpen(false);
        if (pendingDeleteId) {
            await doRemoveFile(pendingDeleteId);
            setPendingDeleteId(null);
        }
    };

    // 取消删除
    const handleCancelDelete = () => {
        setDeleteConfirmOpen(false);
        setPendingDeleteId(null);
    };

    // 生成重命名文件名（自动添加(1), (2), (3)等）
    const generateRenamedFileName = async (originalName: string): Promise<string> => {
        try {
            const files = await browseDirectory(serverId, currentPath);
            const existingNames = new Set(files.map(f => f.name));
            
            // 解析文件名和扩展名
            const lastDotIndex = originalName.lastIndexOf('.');
            const baseName = lastDotIndex > 0 ? originalName.substring(0, lastDotIndex) : originalName;
            const extension = lastDotIndex > 0 ? originalName.substring(lastDotIndex) : '';
            
            // 尝试生成不冲突的文件名
            let counter = 1;
            let newName = `${baseName}(${counter})${extension}`;
            
            while (existingNames.has(newName) && counter < 100) {
                counter++;
                newName = `${baseName}(${counter})${extension}`;
            }
            
            return newName;
        } catch (error) {
            console.error('生成重命名文件名失败:', error);
            // 如果失败，默认返回(1)
            const lastDotIndex = originalName.lastIndexOf('.');
            const baseName = lastDotIndex > 0 ? originalName.substring(0, lastDotIndex) : originalName;
            const extension = lastDotIndex > 0 ? originalName.substring(lastDotIndex) : '';
            return `${baseName}(1)${extension}`;
        }
    };

    // 上传单个文件（异步上传+轮询）
    const uploadSingleFile = async (item: UploadFileItem, overwrite: boolean = false, skipCheck: boolean = false) => {
        const remotePath = pathUtils.join(currentPath, item.file.name);

        // 如果不是覆盖模式且未跳过检查，先检查文件是否已存在
        if (!overwrite && !skipCheck) {
            try {
                // 使用browseDirectory API检查文件是否存在
                const files = await browseDirectory(serverId, currentPath);
                const fileExists = files.some(f => f.name === item.file.name && !f.isDirectory);
                
                if (fileExists) {
                    // 文件已存在，生成建议的重命名文件名
                    const suggestedName = await generateRenamedFileName(item.file.name);
                    setRenameFileName(suggestedName);
                    setPendingOverwriteItem(item);
                    setConfirmDialogOpen(true);
                    return; // 暂停上传，等待用户决定
                }
            } catch (error) {
                console.log('检查文件是否存在时出错:', error);
                // 检查失败，继续上传
            }
        }

        try {
            // 1. 提交异步上传任务
            setUploadFiles(prev =>
                prev.map(f =>
                    f.id === item.id
                        ? { ...f, status: 'uploading', progress: 0 }
                        : f
                )
            );

            const result = await submitAsyncUpload(serverId, item.file, remotePath, overwrite);
            const taskId = result.taskId;

            // 2. 保存taskId
            setUploadFiles(prev =>
                prev.map(f =>
                    f.id === item.id ? { ...f, taskId } : f
                )
            );

            // 3. 开始轮询查询状态
            startPolling(item.id, taskId);
        } catch (error: any) {
            const errorMsg = error.response?.data?.message || '提交上传任务失败';
            
            // 直接显示后端返回的错误信息
            setUploadFiles(prev =>
                prev.map(f =>
                    f.id === item.id
                        ? { ...f, status: 'error', errorMessage: errorMsg }
                        : f
                )
            );
            message.error(`${item.file.name}: ${errorMsg}`);
        }
    };

    // 处理用户确认覆盖
    const handleConfirmOverwrite = async () => {
        setConfirmDialogOpen(false);
        if (pendingOverwriteItem) {
            // 以覆盖模式重新上传，跳过检查
            await uploadSingleFile(pendingOverwriteItem, true, true);
            setPendingOverwriteItem(null);
            setRenameFileName('');
        }
    };

    // 处理用户重命名上传
    const handleRename = async () => {
        setConfirmDialogOpen(false);
        if (pendingOverwriteItem && renameFileName.trim()) {
            // 创建新的文件项，使用重命名后的文件名
            const renamedFile = new File([pendingOverwriteItem.file], renameFileName, {
                type: pendingOverwriteItem.file.type,
            });
            
            const renamedItem: UploadFileItem = {
                ...pendingOverwriteItem,
                file: renamedFile,
            };
            
            // 更新文件列表中的文件名
            setUploadFiles(prev =>
                prev.map(f =>
                    f.id === pendingOverwriteItem.id
                        ? renamedItem
                        : f
                )
            );
            
            // 使用新文件名上传，跳过检查
            await uploadSingleFile(renamedItem, false, true);
            setPendingOverwriteItem(null);
            setRenameFileName('');
        }
    };

    // 处理用户取消覆盖
    const handleCancelOverwrite = () => {
        setConfirmDialogOpen(false);
        if (pendingOverwriteItem) {
            // 标记为错误状态
            setUploadFiles(prev =>
                prev.map(f =>
                    f.id === pendingOverwriteItem.id
                        ? { ...f, status: 'error', errorMessage: '用户取消上传' }
                        : f
                )
            );
            setPendingOverwriteItem(null);
            setRenameFileName('');
        }
    };

    // 轮询查询上传状态
    const startPolling = (fileId: string, taskId: string) => {
        const pollInterval = setInterval(async () => {
            try {
                const taskInfo = await getUploadTaskStatus(serverId, taskId);
                
                // 更新进度
                setUploadFiles(prev =>
                    prev.map(f =>
                        f.id === fileId
                            ? { ...f, progress: taskInfo.progress }
                            : f
                    )
                );

                // 检查是否完成
                if (taskInfo.status === 'SUCCESS') {
                    clearInterval(pollInterval);
                    pollIntervalsRef.current.delete(fileId);
                    setUploadFiles(prev =>
                        prev.map(f =>
                            f.id === fileId
                                ? { ...f, status: 'success', progress: 100 }
                                : f
                        )
                    );
                    onUploadComplete();
                } else if (taskInfo.status === 'FAILED') {
                    clearInterval(pollInterval);
                    pollIntervalsRef.current.delete(fileId);
                    const errorMsg = taskInfo.errorMessage || '上传失败';
                    
                    // 直接显示后端返回的错误信息
                    setUploadFiles(prev =>
                        prev.map(f =>
                            f.id === fileId
                                ? { ...f, status: 'error', errorMessage: errorMsg }
                                : f
                        )
                    );
                    message.error(`上传失败: ${errorMsg}`);
                } else if (taskInfo.status === 'CANCELLED') {
                    clearInterval(pollInterval);
                    pollIntervalsRef.current.delete(fileId);
                    setUploadFiles(prev =>
                        prev.map(f =>
                            f.id === fileId
                                ? { ...f, status: 'error', errorMessage: '已取消' }
                                : f
                        )
                    );
                }
            } catch (error) {
                // 查询失败，继续轮询（可能是网络问题）
                console.error('轮询查询失败:', error);
            }
        }, 2000); // 每2秒查询一次

        // 保存定时器到ref
        pollIntervalsRef.current.set(fileId, pollInterval);
    };

    // 上传所有待上传文件
    const handleUploadAll = async () => {
        const pendingFiles = uploadFiles.filter(f => f.status === 'pending');
        
        for (const file of pendingFiles) {
            await uploadSingleFile(file);
        }
    };

    // 请求清空列表（弹出确认框）
    const handleClearList = () => {
        setClearConfirmOpen(true);
    };

    // 确认清空列表
    const handleConfirmClear = () => {
        setClearConfirmOpen(false);
        setUploadFiles([]);
        message.success('列表已清空');
    };

    // 取消清空
    const handleCancelClear = () => {
        setClearConfirmOpen(false);
    };

    // 拖拽事件处理
    const handleDragEnter = (e: React.DragEvent) => {
        e.preventDefault();
        e.stopPropagation();
        setIsDragging(true);
    };

    const handleDragLeave = (e: React.DragEvent) => {
        e.preventDefault();
        e.stopPropagation();
        setIsDragging(false);
    };

    const handleDragOver = (e: React.DragEvent) => {
        e.preventDefault();
        e.stopPropagation();
    };

    const handleDrop = (e: React.DragEvent) => {
        e.preventDefault();
        e.stopPropagation();
        setIsDragging(false);

        const files = e.dataTransfer.files;
        addFiles(files);
    };

    // 文件选择
    const handleFileSelect = () => {
        fileInputRef.current?.click();
    };

    const handleFileInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        addFiles(e.target.files);
        // 重置input，允许选择相同文件
        e.target.value = '';
    };

    const pendingCount = uploadFiles.filter(f => f.status === 'pending').length;
    const uploadingCount = uploadFiles.filter(f => f.status === 'uploading').length;

    return (
        <div className="flex-1 flex flex-col overflow-hidden">
            {/* 工具栏 */}
            <div className="flex items-center gap-2 p-2 border-b">
                <Button
                    size="sm"
                    onClick={handleFileSelect}
                    disabled={uploadingCount > 0}
                >
                    <Upload className="h-4 w-4 mr-1" />
                    选择文件
                </Button>
                <Button
                    size="sm"
                    onClick={handleUploadAll}
                    disabled={pendingCount === 0 || uploadingCount > 0}
                >
                    上传全部 ({pendingCount})
                </Button>
                <Button
                    size="sm"
                    variant="ghost"
                    onClick={handleClearList}
                    disabled={uploadFiles.length === 0 || uploadingCount > 0}
                >
                    清空列表
                </Button>
            </div>

            {/* 隐藏的文件输入 */}
            <input
                ref={fileInputRef}
                type="file"
                multiple
                className="hidden"
                onChange={handleFileInputChange}
            />

            {/* 拖拽上传区域 */}
            <div
                className={`flex-1 overflow-y-auto ${
                    uploadFiles.length === 0 ? 'flex items-center justify-center' : 'p-2'
                }`}
                onDragEnter={handleDragEnter}
                onDragOver={handleDragOver}
                onDragLeave={handleDragLeave}
                onDrop={handleDrop}
            >
                {uploadFiles.length === 0 ? (
                    <div
                        className={`w-full max-w-md p-12 border-2 border-dashed rounded-lg text-center transition-colors ${
                            isDragging
                                ? 'border-blue-500 bg-blue-50 dark:bg-blue-900/20'
                                : 'border-gray-300 dark:border-gray-700'
                        }`}
                    >
                        <Upload className="h-12 w-12 mx-auto mb-4 text-gray-400" />
                        <p className="text-lg font-medium mb-2">拖拽文件到此处</p>
                        <p className="text-sm text-gray-500 mb-4">或点击选择文件按钮</p>
                        <p className="text-xs text-gray-400">
                            上传目标: {currentPath}
                        </p>
                    </div>
                ) : (
                    <div className="space-y-2">
                        {uploadFiles.map(item => (
                            <div
                                key={item.id}
                                className="p-3 border rounded-lg bg-white dark:bg-gray-900"
                            >
                                <div className="flex items-start gap-2">
                                    <FileIcon className="h-5 w-5 text-gray-500 flex-shrink-0 mt-0.5" />
                                    <div className="flex-1 min-w-0">
                                        <div className="flex items-center justify-between gap-2">
                                            <span className="text-sm font-medium truncate">
                                                {item.file.name}
                                            </span>
                                            <div className="flex items-center gap-2 flex-shrink-0">
                                                {item.status === 'success' && (
                                                    <CheckCircle className="h-4 w-4 text-green-500" />
                                                )}
                                                {item.status === 'error' && (
                                                    <AlertCircle className="h-4 w-4 text-red-500" />
                                                )}
                                                {/* 所有状态都显示X按钮 */}
                                                <Button
                                                    size="sm"
                                                    variant="ghost"
                                                    className="h-6 w-6 p-0"
                                                    onClick={() => requestRemoveFile(item.id)}
                                                    title={
                                                        item.status === 'uploading' 
                                                            ? '取消上传' 
                                                            : item.status === 'pending'
                                                            ? '删除' 
                                                            : '删除记录'
                                                    }
                                                >
                                                    <X className="h-4 w-4" />
                                                </Button>
                                            </div>
                                        </div>
                                        <div className="flex items-center gap-2 mt-1">
                                            <span className="text-xs text-gray-500 w-20 flex-shrink-0">
                                                {formatFileSize(item.file.size)}
                                            </span>
                                            {item.status === 'uploading' && (
                                                <span className="text-xs text-blue-600">
                                                    {item.progress}%
                                                </span>
                                            )}
                                            {item.status === 'success' && (
                                                <span className="text-xs text-green-600">
                                                    上传成功
                                                </span>
                                            )}
                                            {item.status === 'error' && (
                                                <span className="text-xs text-red-600">
                                                    {item.errorMessage}
                                                </span>
                                            )}
                                        </div>
                                        {item.status === 'uploading' && (
                                            <Progress value={item.progress} className="mt-2 h-1" />
                                        )}
                                    </div>
                                </div>
                            </div>
                        ))}
                    </div>
                )}
            </div>

            {/* 覆盖确认对话框 */}
            <AlertDialog open={confirmDialogOpen} onOpenChange={setConfirmDialogOpen}>
                <AlertDialogContent>
                    <AlertDialogHeader>
                        <AlertDialogTitle>文件已存在</AlertDialogTitle>
                        <AlertDialogDescription className="space-y-3">
                            <div>
                                文件 <span className="font-semibold text-foreground">{pendingOverwriteItem?.file.name}</span> 已存在
                            </div>
                            <div className="space-y-2">
                                <label className="text-sm font-medium text-foreground">
                                    重命名为：
                                </label>
                                <Input
                                    value={renameFileName}
                                    onChange={(e) => setRenameFileName(e.target.value)}
                                    placeholder="输入新文件名"
                                    className="w-full"
                                    onKeyDown={(e) => {
                                        if (e.key === 'Enter' && renameFileName.trim()) {
                                            handleRename();
                                        }
                                    }}
                                />
                            </div>
                        </AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                        <AlertDialogCancel onClick={handleCancelOverwrite}>
                            取消
                        </AlertDialogCancel>
                        <Button
                            onClick={handleRename}
                            disabled={!renameFileName.trim()}
                            variant="outline"
                        >
                            重命名
                        </Button>
                        <AlertDialogAction onClick={handleConfirmOverwrite}>
                            覆盖
                        </AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>

            {/* 删除确认对话框 */}
            <AlertDialog open={deleteConfirmOpen} onOpenChange={setDeleteConfirmOpen}>
                <AlertDialogContent>
                    <AlertDialogHeader>
                        <AlertDialogTitle>取消上传</AlertDialogTitle>
                        <AlertDialogDescription>
                            确定要取消正在上传的文件吗？
                        </AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                        <AlertDialogCancel onClick={handleCancelDelete}>
                            取消
                        </AlertDialogCancel>
                        <AlertDialogAction onClick={handleConfirmDelete}>
                            确定
                        </AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>

            {/* 清空列表确认对话框 */}
            <AlertDialog open={clearConfirmOpen} onOpenChange={setClearConfirmOpen}>
                <AlertDialogContent>
                    <AlertDialogHeader>
                        <AlertDialogTitle>清空列表</AlertDialogTitle>
                        <AlertDialogDescription>
                            确定要清空所有上传记录吗？此操作不可恢复。
                        </AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                        <AlertDialogCancel onClick={handleCancelClear}>
                            取消
                        </AlertDialogCancel>
                        <AlertDialogAction onClick={handleConfirmClear}>
                            确定清空
                        </AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>
        </div>
    );
};
