import React, { useState } from 'react';
import { Modal, Button, Image, message } from 'antd';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { fileClient } from '@/client/api';
import type { FileType } from '@/server/modules/files/file.schema';
import MinioUploader from '@/client/admin-shadcn/components/MinioUploader';

// 定义重载的 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) {
      message.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) => {
    message.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}` : '请选择文件';
  };

  return (
    <Modal
      title="选择文件"
      open={visible}
      onCancel={onCancel}
      width={800}
      onOk={handleConfirm}
      okText="确认选择"
      cancelText="取消"
      okButtonProps={{ disabled: selectedFiles.length === 0 }}
    >
      <div style={{ marginBottom: 16 }}>
        <MinioUploader
          uploadPath={uploadPath}
          accept={accept}
          maxSize={maxSize}
          onUploadSuccess={handleUploadSuccess}
          buttonText={uploadButtonText}
        />
        <span style={{ color: '#666', fontSize: '12px', marginLeft: 8 }}>
          上传后请从下方列表中选择文件
        </span>
      </div>

      <div style={{ marginBottom: 16 }}>
        <div style={{
          padding: '8px 12px',
          backgroundColor: '#f6ffed',
          border: '1px solid #b7eb8f',
          borderRadius: '4px',
          color: '#52c41a'
        }}>
          {getSelectionText()}
        </div>
      </div>

      <div style={{ maxHeight: 400, overflowY: 'auto' }}>
        {isLoading ? (
          <div style={{ textAlign: 'center', padding: '40px', color: '#999' }}>
            加载中...
          </div>
        ) : filteredFiles.length > 0 ? (
          filteredFiles.map((file) => (
            <div
              key={file.id}
              style={{
                display: 'flex',
                alignItems: 'center',
                padding: '12px',
                border: `1px solid ${isFileSelected(file) ? '#1890ff' : '#f0f0f0'}`,
                borderRadius: '4px',
                marginBottom: '8px',
                cursor: 'pointer',
                transition: 'all 0.3s',
                backgroundColor: isFileSelected(file) ? '#e6f7ff' : ''
              }}
              onClick={() => handleSelectFile(file)}
              onMouseEnter={(e) => {
                if (!isFileSelected(file)) {
                  e.currentTarget.style.backgroundColor = '#f6ffed';
                  e.currentTarget.style.borderColor = '#b7eb8f';
                }
              }}
              onMouseLeave={(e) => {
                if (!isFileSelected(file)) {
                  e.currentTarget.style.backgroundColor = '';
                  e.currentTarget.style.borderColor = '#f0f0f0';
                }
              }}
            >
              <Image
                src={file.fullUrl}
                alt={file.name}
                style={{ width: 60, height: 60, objectFit: 'cover', borderRadius: 4, marginRight: 12 }}
                preview={false}
              />
              <div style={{ flex: 1 }}>
                <div style={{ fontWeight: 'bold', marginBottom: '4px' }}>{file.name}</div>
                <div style={{ color: '#666', fontSize: '12px' }}>
                  ID: {file.id} | 大小: {((file.size || 0) / 1024 / 1024).toFixed(2)}MB
                </div>
              </div>
              <Button
                type={isFileSelected(file) ? 'primary' : 'default'}
                size="small"
              >
                {isFileSelected(file) ? '已选择' : '选择'}
              </Button>
            </div>
          ))
        ) : (
          <div style={{ textAlign: 'center', padding: '40px', color: '#999' }}>
            暂无符合条件的文件，请先上传
          </div>
        )}
      </div>
    </Modal>
  );
};

// 类型守卫函数
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;