import React, { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { Button } from '@/client/components/ui/button';
import { Input } from '@/client/components/ui/input';
import { Card, CardContent, CardHeader, CardTitle } from '@/client/components/ui/card';
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/client/components/ui/dialog';
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/client/components/ui/form';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/client/components/ui/table';
import { Badge } from '@/client/components/ui/badge';
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from '@/client/components/ui/alert-dialog';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { toast } from 'sonner';
import { Eye, Download, Edit, Trash2, Search, FileText, Upload } from 'lucide-react';
import { fileClient } from '@/client/api';
import type { InferResponseType, InferRequestType } from 'hono/client';
import dayjs from 'dayjs';
import MinioUploader from '@/client/admin/components/MinioUploader';
import { UpdateFileDto } from '@/server/modules/files/file.schema';
import * as z from 'zod';

// 定义类型
type FileItem = InferResponseType<typeof fileClient.$get, 200>['data'][0];
type FileListResponse = InferResponseType<typeof fileClient.$get, 200>;
type UpdateFileRequest = InferRequestType<typeof fileClient[':id']['$put']>['json'];
type FileFormData = z.infer<typeof UpdateFileDto>;

export const FilesPage: React.FC = () => {
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [isUploadModalOpen, setIsUploadModalOpen] = useState(false);
  const [editingFile, setEditingFile] = useState<FileItem | null>(null);
  const [searchText, setSearchText] = useState('');
  const [pagination, setPagination] = useState({
    current: 1,
    pageSize: 10,
    total: 0,
  });
  const [deleteFileId, setDeleteFileId] = useState<number | null>(null);
  const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);

  const queryClient = useQueryClient();
  
  // 表单初始化
  const form = useForm<FileFormData>({
    resolver: zodResolver(UpdateFileDto),
    defaultValues: {
      name: '',
      description: '',
    },
  });

  // 获取文件列表数据
  const fetchFiles = async ({ page, pageSize }: { page: number; pageSize: number }): Promise<FileListResponse> => {
    const response = await fileClient.$get({ query: { page, pageSize, keyword: searchText } });
    if (!response.ok) throw new Error('Failed to fetch files');
    return await response.json() as FileListResponse;
  };

  const { data, isLoading, error } = useQuery({
    queryKey: ['files', pagination.current, pagination.pageSize, searchText],
    queryFn: () => fetchFiles({ page: pagination.current, pageSize: pagination.pageSize }),
  });

  // 更新文件记录
  const updateFile = useMutation({
    mutationFn: ({ id, data }: { id: number; data: UpdateFileRequest }) =>
      fileClient[':id'].$put({ param: { id: Number(id) }, json: data }),
    onSuccess: () => {
      toast.success('文件记录更新成功');
      queryClient.invalidateQueries({ queryKey: ['files'] });
      setIsModalOpen(false);
      setEditingFile(null);
    },
    onError: (error: Error) => {
      toast.error(`操作失败: ${error.message}`);
    }
  });

  // 删除文件记录
  const deleteFile = useMutation({
    mutationFn: (id: number) => fileClient[':id'].$delete({ param: { id: Number(id) } }),
    onSuccess: () => {
      toast.success('文件记录删除成功');
      queryClient.invalidateQueries({ queryKey: ['files'] });
    },
    onError: (error: Error) => {
      toast.error(`删除失败: ${error.message}`);
    }
  });

  // 处理文件下载
  const handleDownload = (record: FileItem) => {
    const a = document.createElement('a');
    a.href = record.fullUrl;
    a.download = record.name;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  };

  // 处理文件预览
  const handlePreview = (record: FileItem) => {
    if (isPreviewable(record.type)) {
      window.open(record.fullUrl, '_blank');
    } else {
      toast.warning('该文件类型不支持预览');
    }
  };

  // 检查是否为可预览的文件类型
  const isPreviewable = (fileType: string | null) => {
    if (!fileType) return false;
    return fileType.startsWith('image/') || fileType.startsWith('video/');
  };

  // 处理上传成功回调
  const handleUploadSuccess = () => {
    toast.success('文件上传成功');
    queryClient.invalidateQueries({ queryKey: ['files'] });
  };

  // 处理上传失败回调
  const handleUploadError = (error: Error) => {
    toast.error(`上传失败: ${error instanceof Error ? error.message : '未知错误'}`);
  };

  // 显示编辑弹窗
  const showEditModal = (record: FileItem) => {
    setEditingFile(record);
    setIsModalOpen(true);
    form.reset({
      name: record.name,
      description: record.description || '',
    });
  };

  // 处理表单提交
  const handleFormSubmit = async (data: FileFormData) => {
    if (editingFile) {
      await updateFile.mutateAsync({ 
        id: editingFile.id, 
        data: {
          name: data.name,
          description: data.description,
        }
      });
    }
  };

  // 处理删除确认
  const handleDeleteConfirm = () => {
    if (deleteFileId) {
      deleteFile.mutate(deleteFileId);
      setIsDeleteDialogOpen(false);
      setDeleteFileId(null);
    }
  };

  const handleSearch = () => {
    setPagination({ ...pagination, current: 1 });
  };

  // 格式化文件大小
  const formatFileSize = (bytes: number | null) => {
    if (!bytes || 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 tablePagination = data?.pagination || pagination;

  if (error) {
    return (
      <div className="p-6">
        <Card>
          <CardContent className="text-center py-8">
            <FileText className="h-12 w-12 mx-auto text-gray-400 mb-4" />
            <p className="text-gray-600">获取文件列表失败</p>
          </CardContent>
        </Card>
      </div>
    );
  }

  return (
    <div className="p-6 space-y-6">
      <div className="flex justify-between items-center">
        <h1 className="text-3xl font-bold">文件管理</h1>
        <Button onClick={() => setIsUploadModalOpen(true)}>
          <Upload className="h-4 w-4 mr-2" />
          上传文件
        </Button>
      </div>
      
      <Card>
        <CardHeader>
          <CardTitle>文件列表</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="mb-4 flex gap-4">
            <div className="flex-1">
              <Input
                placeholder="搜索文件名称或类型"
                value={searchText}
                onChange={(e) => setSearchText(e.target.value)}
                onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
                className="max-w-sm"
              />
            </div>
            <Button onClick={handleSearch}>
              <Search className="h-4 w-4 mr-2" />
              搜索
            </Button>
          </div>

          <div className="overflow-x-auto">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="w-16">ID</TableHead>
                  <TableHead>预览</TableHead>
                  <TableHead>文件名称</TableHead>
                  <TableHead>文件类型</TableHead>
                  <TableHead>文件大小</TableHead>
                  <TableHead>上传时间</TableHead>
                  <TableHead>上传用户</TableHead>
                  <TableHead className="text-right">操作</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {isLoading ? (
                  <TableRow>
                    <TableCell colSpan={7} className="text-center">
                      <div className="flex justify-center items-center py-8">
                        <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
                      </div>
                    </TableCell>
                  </TableRow>
                ) : data?.data?.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={7} className="text-center py-8">
                      <FileText className="h-12 w-12 mx-auto text-gray-400 mb-4" />
                      <p className="text-gray-600">暂无文件</p>
                    </TableCell>
                  </TableRow>
                ) : (
                  data?.data?.map((file) => (
                    <TableRow key={file.id}>
                      <TableCell className="font-medium">{file.id}</TableCell>
                      <TableCell>
                        {isPreviewable(file.type) ? (
                          <img
                            src={file.fullUrl}
                            alt={file.name}
                            className="w-12 h-12 object-cover rounded border cursor-pointer hover:opacity-80 transition-opacity"
                            onClick={() => handlePreview(file)}
                            title="点击查看大图"
                          />
                        ) : (
                          <div className="w-12 h-12 flex items-center justify-center bg-gray-100 rounded border">
                            <FileText className="h-6 w-6 text-gray-400" />
                          </div>
                        )}
                      </TableCell>
                      <TableCell>
                        <div className="max-w-xs truncate" title={file.name}>
                          {file.name}
                        </div>
                      </TableCell>
                      <TableCell>
                        <Badge variant="secondary">{file.type}</Badge>
                      </TableCell>
                      <TableCell>{formatFileSize(file.size)}</TableCell>
                      <TableCell>
                        {file.uploadTime ? dayjs(file.uploadTime).format('YYYY-MM-DD HH:mm:ss') : '-'}
                      </TableCell>
                      <TableCell>
                        {file.uploadUser ? (file.uploadUser.nickname || file.uploadUser.username) : '-'}
                      </TableCell>
                      <TableCell className="text-right">
                        <div className="flex justify-end gap-2">
                          <Button
                            variant="ghost"
                            size="sm"
                            onClick={() => handlePreview(file)}
                            disabled={!isPreviewable(file.type)}
                            title={isPreviewable(file.type) ? '预览文件' : '该文件类型不支持预览'}
                          >
                            <Eye className="h-4 w-4" />
                          </Button>
                          <Button
                            variant="ghost"
                            size="sm"
                            onClick={() => handleDownload(file)}
                            title="下载文件"
                          >
                            <Download className="h-4 w-4" />
                          </Button>
                          <Button
                            variant="ghost"
                            size="sm"
                            onClick={() => showEditModal(file)}
                            title="编辑文件信息"
                          >
                            <Edit className="h-4 w-4" />
                          </Button>
                          <Button
                            variant="ghost"
                            size="sm"
                            onClick={() => {
                              setDeleteFileId(file.id);
                              setIsDeleteDialogOpen(true);
                            }}
                            className="text-red-600 hover:text-red-700"
                            title="删除文件"
                          >
                            <Trash2 className="h-4 w-4" />
                          </Button>
                        </div>
                      </TableCell>
                    </TableRow>
                  ))
                )}
              </TableBody>
            </Table>
          </div>

          {/* 分页 */}
          {tablePagination.total > 0 && (
            <div className="flex justify-between items-center mt-4">
              <div className="text-sm text-gray-600">
                显示 {((tablePagination.current - 1) * tablePagination.pageSize + 1)}-
                {Math.min(tablePagination.current * tablePagination.pageSize, tablePagination.total)} 条，
                共 {tablePagination.total} 条
              </div>
              <div className="flex gap-2">
                <Button
                  variant="outline"
                  size="sm"
                  disabled={tablePagination.current <= 1}
                  onClick={() => setPagination({ ...pagination, current: tablePagination.current - 1 })}
                >
                  上一页
                </Button>
                <span className="px-3 py-1 text-sm">
                  第 {tablePagination.current} 页
                </span>
                <Button
                  variant="outline"
                  size="sm"
                  disabled={tablePagination.current >= Math.ceil(tablePagination.total / tablePagination.pageSize)}
                  onClick={() => setPagination({ ...pagination, current: tablePagination.current + 1 })}
                >
                  下一页
                </Button>
              </div>
            </div>
          )}
        </CardContent>
      </Card>

      {/* 上传文件对话框 */}
      <Dialog open={isUploadModalOpen} onOpenChange={setIsUploadModalOpen}>
        <DialogContent className="sm:max-w-[600px]">
          <DialogHeader>
            <DialogTitle>上传文件</DialogTitle>
            <DialogDescription>
              选择要上传的文件，支持拖拽上传
            </DialogDescription>
          </DialogHeader>
          
          <div className="py-4">
            <MinioUploader
              uploadPath="/files"
              maxSize={500}
              multiple={false}
              onUploadSuccess={() => {
                handleUploadSuccess();
                setIsUploadModalOpen(false);
              }}
              onUploadError={handleUploadError}
              buttonText="点击或拖拽上传文件"
              tipText="支持单文件上传，单个文件大小不超过500MB"
              size="default"
            />
          </div>
          
          <DialogFooter>
            <Button variant="outline" onClick={() => setIsUploadModalOpen(false)}>
              取消
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* 编辑对话框 */}
      <Dialog open={isModalOpen} onOpenChange={setIsModalOpen}>
        <DialogContent className="sm:max-w-[500px]">
          <DialogHeader>
            <DialogTitle>编辑文件信息</DialogTitle>
            <DialogDescription>
              修改文件的基本信息
            </DialogDescription>
          </DialogHeader>
          <Form {...form}>
            <form onSubmit={form.handleSubmit(handleFormSubmit)} className="space-y-4">
              <FormField
                control={form.control}
                name="name"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>文件名称</FormLabel>
                    <FormControl>
                      <Input placeholder="请输入文件名称" {...field} />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
              <FormField
                control={form.control}
                name="description"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>文件描述</FormLabel>
                    <FormControl>
                      <Input placeholder="请输入文件描述" {...field} />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
              <DialogFooter>
                <Button type="button" variant="outline" onClick={() => setIsModalOpen(false)}>
                  取消
                </Button>
                <Button type="submit" disabled={updateFile.isPending}>
                  {updateFile.isPending ? '保存中...' : '保存'}
                </Button>
              </DialogFooter>
            </form>
          </Form>
        </DialogContent>
      </Dialog>

      {/* 删除确认对话框 */}
      <AlertDialog open={isDeleteDialogOpen} onOpenChange={setIsDeleteDialogOpen}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>确认删除</AlertDialogTitle>
            <AlertDialogDescription>
              确定要删除这个文件记录吗？此操作不可恢复。
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>取消</AlertDialogCancel>
            <AlertDialogAction onClick={handleDeleteConfirm} className="bg-red-600 hover:bg-red-700">
              确认删除
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
};