import React, { useState } from 'react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { Button } from '@/client/components/ui/button';
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/client/components/ui/dialog';
import { Card, CardContent } from '@/client/components/ui/card';
import { Badge } from '@/client/components/ui/badge';
import { toast } from 'sonner';
import { fileClient } from '@/client/api';
import type { FileType } from '@/server/modules/files/file.schema';
import MinioUploader from '@/client/admin-shadcn/components/MinioUploader';
import { Check, Upload } from 'lucide-react';

// 定义重载的 props 类型
interface SingleFileSelectorProps {
  visible: boolean;
  onCancel: () => void;
  onSelect: (file: FileType) => void;
  accept?: string;
  maxSize?: number;
  uploadPath?: string;
  uploadButtonText?: string;
  multiple?: false;
}

interface MultipleFileSelectorProps {
  visible: boolean;
  onCancel: () => void;
  onSelect: (files: FileType[]) => void;
  accept?: string;
  maxSize?: number;
  uploadPath?: string;
  uploadButtonText?: string;
  multiple: true;
}

type FileSelectorProps = SingleFileSelectorProps | MultipleFileSelectorProps;

const FileSelector: React.FC<FileSelectorProps> = ({
  visible,
  onCancel,
  onSelect,
  accept = 'image/*',
  maxSize = 5,
  uploadPath = '/uploads',
  uploadButtonText = '上传新文件',
  multiple = false,
  ...props
}) => {
  const queryClient = useQueryClient();
  const [selectedFiles, setSelectedFiles] = useState<FileType[]>([]);
  
  // 获取文件列表
  const { data: filesData, isLoading } = useQuery({
    queryKey: ['files-for-selection', accept] as const,
    queryFn: async () => {
      const response = await fileClient.$get({
        query: {
          page: 1,
          pageSize: 50,
          keyword: accept.startsWith('image/') ? 'image' : undefined
        }
      });
      if (response.status !== 200) throw new Error('获取文件列表失败');
      return response.json();
    },
    enabled: visible
  });

  // 重置选择状态
  React.useEffect(() => {
    if (!visible) {
      setSelectedFiles([]);
    }
  }, [visible]);

  const handleSelectFile = (file: FileType) => {
    if (!file) {
      console.error('No file provided to handleSelectFile');
      return;
    }

    if (multiple) {
      // 多选模式
      const newSelection = selectedFiles.some(f => f.id === file.id)
        ? selectedFiles.filter(f => f.id !== file.id)
        : [...selectedFiles, file];
      
      setSelectedFiles(newSelection);
    } else {
      // 单选模式
      setSelectedFiles([file]);
    }
  };

  const handleConfirm = () => {
    if (selectedFiles.length === 0) {
      toast.warning('请先选择文件');
      return;
    }

    if (multiple) {
      // 多选模式
      (onSelect as MultipleFileSelectorProps['onSelect'])(selectedFiles);
    } else {
      // 单选模式
      (onSelect as SingleFileSelectorProps['onSelect'])(selectedFiles[0]);
    }
    
    onCancel();
  };

  const handleUploadSuccess = (fileKey: string, fileUrl: string, file: any) => {
    toast.success('文件上传成功！请从列表中选择新上传的文件');
    // 刷新文件列表
    queryClient.invalidateQueries({ queryKey: ['files-for-selection', accept] });
  };

  const filteredFiles = Array.isArray(filesData?.data)
    ? filesData.data.filter((f: any) => !accept || f?.type?.startsWith(accept.replace('*', '')))
    : [];

  const isFileSelected = (file: FileType) => {
    return selectedFiles.some(f => f.id === file.id);
  };

  const getSelectionText = () => {
    if (multiple) {
      return selectedFiles.length > 0 ? `已选择 ${selectedFiles.length} 个文件` : '请选择文件';
    }
    return selectedFiles.length > 0 ? `已选择: ${selectedFiles[0].name}` : '请选择文件';
  };

  // 格式化文件大小
  const formatFileSize = (bytes: number) => {
    if (bytes === 0) return '0 Bytes';
    const k = 1024;
    const sizes = ['Bytes', '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 getFileTypeBadge = (type: string) => {
    if (type.startsWith('image/')) {
      return { text: '图片', color: 'bg-blue-100 text-blue-800' };
    } else if (type.startsWith('video/')) {
      return { text: '视频', color: 'bg-red-100 text-red-800' };
    } else if (type.startsWith('audio/')) {
      return { text: '音频', color: 'bg-purple-100 text-purple-800' };
    } else if (type.includes('pdf')) {
      return { text: 'PDF', color: 'bg-red-100 text-red-800' };
    } else if (type.includes('word')) {
      return { text: '文档', color: 'bg-blue-100 text-blue-800' };
    } else if (type.includes('excel') || type.includes('sheet')) {
      return { text: '表格', color: 'bg-green-100 text-green-800' };
    } else {
      return { text: '文件', color: 'bg-gray-100 text-gray-800' };
    }
  };

  return (
    <Dialog open={visible} onOpenChange={onCancel}>
      <DialogContent className="max-w-4xl max-h-[80vh]">
        <DialogHeader>
          <DialogTitle>选择文件</DialogTitle>
          <DialogDescription>
            从已有文件中选择，或上传新文件
          </DialogDescription>
        </DialogHeader>
        
        <div className="space-y-4">
          {/* 上传区域 */}
          <Card>
            <CardContent className="pt-6">
              <MinioUploader
                uploadPath={uploadPath}
                accept={accept}
                maxSize={maxSize}
                onUploadSuccess={handleUploadSuccess}
                buttonText={uploadButtonText}
              />
              <p className="text-sm text-gray-500 mt-2">
                上传后请从下方列表中选择文件
              </p>
            </CardContent>
          </Card>

          {/* 选择状态显示 */}
          <Card>
            <CardContent className="pt-6">
              <div className="bg-green-50 border border-green-200 rounded-md p-3">
                <p className="text-sm text-green-700">{getSelectionText()}</p>
              </div>
            </CardContent>
          </Card>

          {/* 文件列表 */}
          <div className="space-y-2 max-h-96 overflow-y-auto">
            {isLoading ? (
              <Card>
                <CardContent className="text-center py-8">
                  <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary mx-auto"></div>
                  <p className="text-gray-500 mt-2">加载中...</p>
                </CardContent>
              </Card>
            ) : filteredFiles.length > 0 ? (
              <div className="grid gap-3">
                {filteredFiles.map((file) => {
                  const typeBadge = getFileTypeBadge(file.type);
                  const isSelected = isFileSelected(file);
                  
                  return (
                    <Card
                      key={file.id}
                      className={`cursor-pointer transition-all hover:shadow-md ${
                        isSelected ? 'ring-2 ring-primary' : ''
                      }`}
                      onClick={() => handleSelectFile(file)}
                    >
                      <CardContent className="p-4">
                        <div className="flex items-center space-x-4">
                          {/* 文件预览图 */}
                          <div className="relative">
                            {file.type.startsWith('image/') ? (
                              <img
                                src={file.fullUrl}
                                alt={file.name}
                                className="w-16 h-16 object-cover rounded-md"
                              />
                            ) : (
                              <div className="w-16 h-16 bg-gray-100 rounded-md flex items-center justify-center">
                                <Upload className="h-8 w-8 text-gray-400" />
                              </div>
                            )}
                            {isSelected && (
                              <div className="absolute -top-2 -right-2 bg-primary text-white rounded-full p-1">
                                <Check className="h-3 w-3" />
                              </div>
                            )}
                          </div>

                          {/* 文件信息 */}
                          <div className="flex-1 min-w-0">
                            <h4 className="text-sm font-medium truncate">{file.name}</h4>
                            <div className="flex items-center space-x-2 mt-1">
                              <Badge className={`${typeBadge.color} text-xs`}>
                                {typeBadge.text}
                              </Badge>
                              <span className="text-xs text-gray-500">ID: {file.id}</span>
                              <span className="text-xs text-gray-500">
                                {formatFileSize(file.size || 0)}
                              </span>
                            </div>
                          </div>

                          {/* 选择按钮 */}
                          <Button
                            type="button"
                            variant={isSelected ? "default" : "outline"}
                            size="sm"
                            onClick={(e) => {
                              e.stopPropagation();
                              handleSelectFile(file);
                            }}
                          >
                            {isSelected ? '已选择' : '选择'}
                          </Button>
                        </div>
                      </CardContent>
                    </Card>
                  );
                })}
              </div>
            ) : (
              <Card>
                <CardContent className="text-center py-8">
                  <Upload className="h-12 w-12 mx-auto text-gray-400 mb-4" />
                  <p className="text-gray-600">暂无符合条件的文件</p>
                  <p className="text-sm text-gray-500 mt-2">请先上传文件或调整筛选条件</p>
                </CardContent>
              </Card>
            )}
          </div>
        </div>

        <DialogFooter>
          <Button type="button" variant="outline" onClick={onCancel}>
            取消
          </Button>
          <Button 
            type="button" 
            onClick={handleConfirm}
            disabled={selectedFiles.length === 0}
          >
            确认选择
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
};

// 类型守卫函数
function isMultipleSelector(props: FileSelectorProps): props is MultipleFileSelectorProps {
  return props.multiple === true;
}

function isSingleSelector(props: FileSelectorProps): props is SingleFileSelectorProps {
  return props.multiple === false || props.multiple === undefined;
}

export default FileSelector;