'use client';

import React, { useState, useRef, useCallback, useEffect } from 'react';
import { UploadMetadata } from '@/hooks/use-tus-upload';
import { cn } from '@nice/ui/lib/utils';
import { Upload, X, Play, Pause, Check, AlertCircle, File, Copy } from 'lucide-react';
import { toast } from '@nice/ui/components/sonner';
import { Button } from '@nice/ui/components/button';
import { Progress } from '@nice/ui/components/progress';
import { useAuth } from '@/components/providers/auth-provider';
import * as tus from 'tus-js-client';

export interface FileUploadItem {
    id: string;
    file: File;
    progress: number;
    status: 'waiting' | 'uploading' | 'success' | 'error' | 'paused';
    error?: string;
    uploadUrl?: string;
    tusUpload?: tus.Upload;
}

export interface FileUploadProps {
    className?: string;
    accept?: string;
    maxSize?: number;
    maxFiles?: number;
    multiple?: boolean;
    disabled?: boolean;
    placeholder?: string;
    description?: string;
    metadata?: UploadMetadata;
    maxConcurrentUploads?: number; // 最大并发上传数量
    onUploadComplete?: (files: Array<{ file: File; uploadUrl: string }>) => void;
    onUploadError?: (error: string) => void;
}

export function FileUpload({
    className,
    accept = '*/*',
    maxSize = 100 * 1024 * 1024, // 100MB
    maxFiles = 10,
    multiple = false,
    disabled = false,
    placeholder = '点击上传文件或拖拽文件到此处',
    description = `支持所有文件类型，单个文件最大 ${Math.round(maxSize / (1024 * 1024))}MB`,
    metadata = {},
    onUploadComplete,
    onUploadError,
}: FileUploadProps) {
    const [uploadItems, setUploadItems] = useState<FileUploadItem[]>([]);
    const [isDragOver, setIsDragOver] = useState(false);
    const fileInputRef = useRef<HTMLInputElement>(null);
    const { user } = useAuth();
    const retryDelays = [1000, 3000, 5000];

    const validateFile = useCallback((file: File): string | null => {
        if (file.size > maxSize) {
            return `文件大小不能超过 ${Math.round(maxSize / (1024 * 1024))}MB`;
        }
        return null;
    }, [maxSize]);

    const validateFiles = useCallback((files: File[]): { valid: File[]; errors: string[] } => {
        const valid: File[] = [];
        const errors: string[] = [];

        if (!multiple && files.length > 1) {
            errors.push('只能选择一个文件');
            return { valid: [], errors };
        }

        if (files.length > maxFiles) {
            errors.push(`最多只能选择 ${maxFiles} 个文件`);
            return { valid: [], errors };
        }

        files.forEach(file => {
            const error = validateFile(file);
            if (error) {
                errors.push(`${file.name}: ${error}`);
            } else {
                valid.push(file);
            }
        });

        return { valid, errors };
    }, [multiple, maxFiles, validateFile]);

    // 构建TUS元数据
    const buildTusMetadata = useCallback((file: File, customMetadata: UploadMetadata = {}) => {
        const metadata: Record<string, string> = {
            filename: file.name,
            filetype: file.type || 'application/octet-stream',
            filesize: file.size.toString(),
        };

        // 添加用户信息
        if (user?.id) {
            metadata.authorId = user.id;
        }
        if (user?.organizationId) {
            metadata.organizationId = user.organizationId;
        }

        // 添加自定义元数据
        Object.entries(customMetadata).forEach(([key, value]) => {
            if (value !== undefined && value !== null) {
                if (typeof value === 'object') {
                    metadata[key] = JSON.stringify(value);
                } else {
                    metadata[key] = String(value);
                }
            }
        });

        return metadata;
    }, [user]);

    const createUploadItem = useCallback((file: File): FileUploadItem => {
        return {
            id: `${file.name}-${Date.now()}-${Math.random()}`,
            file,
            progress: 0,
            status: 'waiting',
        };
    }, []);

    const updateUploadItem = useCallback((id: string, updates: Partial<FileUploadItem>) => {
        setUploadItems(prev => prev.map(item =>
            item.id === id ? { ...item, ...updates } : item
        ));
    }, []);

    const removeUploadItem = useCallback((id: string) => {
        setUploadItems(prev => {
            const itemToRemove = prev.find(item => item.id === id);
            if (itemToRemove?.tusUpload && (itemToRemove.status === 'uploading' || itemToRemove.status === 'paused')) {
                itemToRemove.tusUpload.abort();
            }
            return prev.filter(item => item.id !== id);
        });
    }, []);

    // 创建TUS上传实例
    const createTusUpload = useCallback((file: File, itemId: string) => {
        console.log('🔍 createTusUpload 被调用，文件:', file.name, 'itemId:', itemId);
        const tusMetadata = buildTusMetadata(file, metadata);

        const upload = new tus.Upload(file, {
            endpoint: `${process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000'}/files/`,
            retryDelays,
            metadata: tusMetadata,
            chunkSize: 1024 * 1024, // 1MB 分块大小
            onError: (error: Error) => {
                console.error('上传失败:', error);
                updateUploadItem(itemId, {
                    status: 'error',
                    error: error.message,
                });
                onUploadError?.(error.message);
                toast.error(`${file.name} 上传失败: ${error.message}`);
            },
            onProgress: (bytesUploaded: number, bytesTotal: number) => {
                const progress = Math.round((bytesUploaded / bytesTotal) * 100);
                updateUploadItem(itemId, { progress });
            },
            onSuccess: () => {
                console.log('🔍 TUS上传成功，文件:', file.name, 'itemId:', itemId, 'uploadUrl:', upload.url);
                updateUploadItem(itemId, {
                    status: 'success',
                    uploadUrl: upload.url || undefined,
                    progress: 100,
                });
            },
            onShouldRetry: (err: Error, retryAttempt: number) => {
                const tusError = err as any;
                const status = tusError.originalResponse ? tusError.originalResponse.getStatus() : 0;

                if (status === 401 || status === 403 || status === 413) {
                    return false;
                }

                if (retryAttempt >= retryDelays.length) {
                    return false;
                }

                return true;
            },
        });

        console.log('🔍 TUS上传实例创建完成，准备开始上传:', file.name);
        return upload;
    }, [buildTusMetadata, metadata, retryDelays, updateUploadItem, onUploadError]);

    // 移除旧的队列管理逻辑，现在直接在handleFiles中处理上传

    // 检查是否所有文件都完成了
    const [hasNotifiedCompletion, setHasNotifiedCompletion] = useState(false);

    useEffect(() => {
        const allCompleted = uploadItems.length > 0 && uploadItems.every(item =>
            item.status === 'success' || item.status === 'error'
        );

        if (allCompleted && !hasNotifiedCompletion) {
            const successfulFiles = uploadItems
                .filter(item => item.status === 'success' && item.uploadUrl)
                .map(item => ({
                    file: item.file,
                    uploadUrl: item.uploadUrl!
                }));

            if (successfulFiles.length > 0) {
                onUploadComplete?.(successfulFiles);
                toast.success('所有文件上传完成');
                setHasNotifiedCompletion(true);
            }
        }

        // 当有新的上传开始时，重置通知状态
        if (uploadItems.some(item => item.status === 'waiting' || item.status === 'uploading')) {
            setHasNotifiedCompletion(false);
        }
    }, [uploadItems, onUploadComplete, hasNotifiedCompletion]);

    // 移除旧的队列管理useEffect，现在直接在handleFiles中处理上传

    const handleFiles = useCallback(async (files: File[]) => {
        console.log('🔍 handleFiles 被调用，文件数量:', files.length, '文件名:', files.map(f => f.name));

        const { valid, errors } = validateFiles(files);

        if (errors.length > 0) {
            errors.forEach(error => toast.error(error));
            return;
        }

        if (valid.length === 0) return;

        // 如果是单选模式，清除之前的上传项
        if (!multiple) {
            setUploadItems(prev => {
                // 取消所有正在进行的上传
                prev.forEach(item => {
                    if (item.tusUpload && (item.status === 'uploading' || item.status === 'paused')) {
                        item.tusUpload.abort();
                    }
                });
                return [];
            });
        }

        // 创建上传项并立即开始上传
        const newItems = valid.map(file => {
            const item = createUploadItem(file);
            console.log('🔍 创建新的上传项:', { id: item.id, fileName: item.file.name });

            // 立即创建并开始上传，避免队列管理的复杂性
            setTimeout(() => {
                console.log('🔍 立即开始上传文件:', file.name);
                const tusUpload = createTusUpload(file, item.id);

                // 更新状态为上传中
                setUploadItems(prev => prev.map(prevItem =>
                    prevItem.id === item.id
                        ? { ...prevItem, status: 'uploading' as const, tusUpload }
                        : prevItem
                ));

                tusUpload.start();
            }, 0);

            return item;
        });

        setUploadItems(prev => multiple ? [...newItems, ...prev] : newItems);
    }, [validateFiles, multiple, createUploadItem, createTusUpload]);

    const handleInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
        const files = Array.from(e.target.files || []);
        if (files.length > 0) {
            handleFiles(files);
        }
        // 清空input值，允许重复选择同一文件
        e.target.value = '';
    }, [handleFiles]);

    const handleClick = useCallback(() => {
        if (!disabled) {
            fileInputRef.current?.click();
        }
    }, [disabled]);

    const handleDragOver = useCallback((e: React.DragEvent) => {
        e.preventDefault();
        if (!disabled) {
            setIsDragOver(true);
        }
    }, [disabled]);

    const handleDragLeave = useCallback((e: React.DragEvent) => {
        e.preventDefault();
        setIsDragOver(false);
    }, []);

    const handleDrop = useCallback((e: React.DragEvent) => {
        e.preventDefault();
        setIsDragOver(false);

        if (disabled) return;

        const files = Array.from(e.dataTransfer.files);
        if (files.length > 0) {
            handleFiles(files);
        }
    }, [disabled, handleFiles]);

    const pauseUpload = useCallback((itemId: string) => {
        const item = uploadItems.find(item => item.id === itemId);
        if (item && item.tusUpload && item.status === 'uploading') {
            item.tusUpload.abort();
            updateUploadItem(itemId, { status: 'paused' });
        }
    }, [uploadItems, updateUploadItem]);

    const resumeUpload = useCallback((itemId: string) => {
        const item = uploadItems.find(item => item.id === itemId);
        if (item && item.status === 'paused') {
            // 重新创建上传实例并开始上传
            const tusUpload = createTusUpload(item.file, item.id);
            tusUpload.start();
            updateUploadItem(itemId, { status: 'uploading', tusUpload });
        }
    }, [uploadItems, updateUploadItem, createTusUpload]);

    const formatFileSize = useCallback((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 parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    }, []);

    const copyDownloadLink = useCallback(async (uploadUrl: string) => {
        try {
            await navigator.clipboard.writeText(uploadUrl);
            toast.success('下载链接已复制到剪贴板');
        } catch (error) {
            console.error('复制失败:', error);
            toast.error('复制失败，请手动复制链接');
        }
    }, []);

    return (
        <div className={cn('w-full', className)}>
            <input
                ref={fileInputRef}
                type="file"
                accept={accept}
                multiple={multiple}
                onChange={handleInputChange}
                className="hidden"
                disabled={disabled}
            />

            {/* 上传区域 */}
            <div
                onClick={handleClick}
                onDragOver={handleDragOver}
                onDragLeave={handleDragLeave}
                onDrop={handleDrop}
                className={cn(
                    'relative border-2 border-dashed rounded-lg p-8 transition-all',
                    'flex flex-col items-center justify-center min-h-[120px]',
                    {
                        'border-gray-300 hover:border-gray-400': !disabled && !isDragOver,
                        'border-blue-400 bg-blue-50': isDragOver && !disabled,
                        'border-gray-200 bg-gray-50 cursor-not-allowed': disabled,
                        'cursor-pointer': !disabled,
                    }
                )}
            >
                <Upload className={cn('w-8 h-8 mb-3', {
                    'text-gray-400': disabled,
                    'text-gray-500': !disabled && !isDragOver,
                    'text-blue-500': isDragOver && !disabled,
                })} />

                <p className={cn('text-sm font-medium mb-1', {
                    'text-gray-400': disabled,
                    'text-gray-700': !disabled,
                })}>
                    {placeholder}
                </p>

                <p className={cn('text-xs', {
                    'text-gray-300': disabled,
                    'text-gray-500': !disabled,
                })}>
                    {description}
                </p>
            </div>

            {/* 上传列表 */}
            {uploadItems.length > 0 && (
                <div className="mt-4 space-y-3 max-h-[140px] overflow-y-auto">
                    <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
                        {uploadItems.map((item) => (
                            <div key={item.id} className="border rounded-lg p-3 bg-white shadow-sm">
                                {/* 文件信息头部 */}
                                <div className="flex items-start justify-between mb-2">
                                    <div className="flex items-center space-x-2 flex-1 min-w-0">
                                        <File className="w-4 h-4 text-gray-400 flex-shrink-0 mt-0.5" />
                                        <div className="flex-1 min-w-0">
                                            <div className="text-sm font-medium text-gray-900 truncate mb-1" title={item.file.name}>
                                                {item.file.name}
                                            </div>
                                            <div className="text-xs text-gray-500">
                                                {formatFileSize(item.file.size)}
                                            </div>
                                        </div>
                                    </div>

                                    {/* 状态图标和操作按钮 */}
                                    <div className="flex items-center space-x-1 flex-shrink-0">
                                        {item.status === 'uploading' && (
                                            <Button
                                                size="sm"
                                                variant="ghost"
                                                className="h-6 w-6 p-0"
                                                onClick={() => pauseUpload(item.id)}
                                            >
                                                <Pause className="w-3 h-3" />
                                            </Button>
                                        )}

                                        {item.status === 'paused' && (
                                            <Button
                                                size="sm"
                                                variant="ghost"
                                                className="h-6 w-6 p-0"
                                                onClick={() => resumeUpload(item.id)}
                                            >
                                                <Play className="w-3 h-3" />
                                            </Button>
                                        )}

                                        {item.status === 'success' && (
                                            <>
                                                <Check className="w-3.5 h-3.5 text-green-500" />
                                                {item.uploadUrl && (
                                                    <Button
                                                        size="sm"
                                                        variant="ghost"
                                                        className="h-6 w-6 p-0"
                                                        onClick={() => copyDownloadLink(item.uploadUrl!)}
                                                        title="复制下载链接"
                                                    >
                                                        <Copy className="w-3 h-3" />
                                                    </Button>
                                                )}
                                            </>
                                        )}

                                        {item.status === 'error' && (
                                            <AlertCircle className="w-3.5 h-3.5 text-red-500" />
                                        )}

                                        <Button
                                            size="sm"
                                            variant="ghost"
                                            className="h-6 w-6 p-0"
                                            onClick={() => removeUploadItem(item.id)}
                                        >
                                            <X className="w-3 h-3" />
                                        </Button>
                                    </div>
                                </div>

                                {/* 进度条 */}
                                <div className="space-y-1.5">
                                    <Progress value={item.progress} className="h-1.5" />
                                    <div className="flex justify-between items-center text-xs">
                                        <span className={`font-medium ${item.status === 'success' ? 'text-green-600' :
                                            item.status === 'error' ? 'text-red-600' :
                                                item.status === 'uploading' ? 'text-blue-600' :
                                                    'text-gray-500'
                                            }`}>
                                            {item.status === 'success' && '完成'}
                                            {item.status === 'uploading' && '上传中'}
                                            {item.status === 'paused' && '已暂停'}
                                            {item.status === 'error' && `错误: ${item.error}`}
                                        </span>
                                        <span className="text-gray-500 font-mono">{item.progress}%</span>
                                    </div>
                                </div>

                                {/* 下载链接 */}
                                {item.uploadUrl && item.status === 'success' && (
                                    <div className="mt-2 pt-2 border-t border-gray-100">
                                        <div className="text-xs text-blue-600 truncate font-mono" title={item.uploadUrl}>
                                            <span className='text-gray-900'>下载链接：</span>
                                            <span>{item.uploadUrl}</span>
                                        </div>
                                    </div>
                                )}
                            </div>
                        ))}
                    </div>
                </div>
            )}
        </div>
    );
}

export default FileUpload;