"use client"

import * as React from "react"
import { type Table } from "@tanstack/react-table"
import { Download, RefreshCcw, Upload, FileText, Loader2, ChevronDown, X, Play, Pause, RotateCcw, Trash } from "lucide-react"

import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog"
import { Progress } from "@/components/ui/progress"
import { Badge } from "@/components/ui/badge"
import { toast } from "sonner"
import { OcrRow } from "@/db/schema"
import { exportTableToExcel } from "@/lib/export_all"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import {
  Dropzone,
  DropzoneDescription,
  DropzoneInput,
  DropzoneTitle,
  DropzoneUploadIcon,
  DropzoneZone,
} from "@/components/ui/dropzone"
import {
  FileList,
  FileListAction,
  FileListDescription,
  FileListHeader,
  FileListIcon,
  FileListInfo,
  FileListItem,
  FileListName,
  FileListSize,
} from "@/components/ui/file-list"
import { getOcrAllRows } from "../service"
import { exportOcrDataToExcel } from "./exporft-ocr-data"
import { DeleteOcrRowsDialog } from "./delete-ocr-rows-dialog"

interface OcrTableToolbarActionsProps {
  table: Table<OcrRow>
}

interface UploadProgress {
  stage: string
  progress: number
  message: string
}

interface FileUploadItem {
  id: string
  file: File
  status: 'pending' | 'processing' | 'completed' | 'failed'
  progress?: UploadProgress
  error?: string
  result?: {
    totalTables: number
    totalRows: number
    sessionId: string
  }
}

interface BatchProgress {
  total: number
  completed: number
  failed: number
  current?: string // 현재 처리 중인 파일명
}

export function OcrTableToolbarActions({ table }: OcrTableToolbarActionsProps) {
  const [isLoading, setIsLoading] = React.useState(false)
  const [isUploading, setIsUploading] = React.useState(false)
  const [uploadProgress, setUploadProgress] = React.useState<UploadProgress | null>(null)
  const [isUploadDialogOpen, setIsUploadDialogOpen] = React.useState(false)
  const [selectedFile, setSelectedFile] = React.useState<File | null>(null)
  const fileInputRef = React.useRef<HTMLInputElement>(null)
  const [isExporting, setIsExporting] = React.useState(false)

  // 멀티 파일 업로드 관련 상태
  const [isBatchDialogOpen, setIsBatchDialogOpen] = React.useState(false)
  const [fileQueue, setFileQueue] = React.useState<FileUploadItem[]>([])
  const [isBatchProcessing, setIsBatchProcessing] = React.useState(false)
  const [batchProgress, setBatchProgress] = React.useState<BatchProgress>({ total: 0, completed: 0, failed: 0 })
  const [isPaused, setIsPaused] = React.useState(false)
  const batchControllerRef = React.useRef<AbortController | null>(null)

  // 선택된 행들
  const selectedRows = table.getFilteredSelectedRowModel().rows

  // 단일 파일 업로드 다이얼로그 닫기 핸들러
  const handleDialogOpenChange = (open: boolean) => {
    if (!open) {
      if (isUploading && uploadProgress?.stage !== "complete") {
        toast.warning("처리 중에는 창을 닫을 수 없습니다. 완료될 때까지 기다려주세요.", {
          description: "OCR 처리가 진행 중입니다..."
        })
        return
      }
      resetUpload()
    }
    setIsUploadDialogOpen(open)
  }

  // 배치 업로드 다이얼로그 닫기 핸들러
  const handleBatchDialogOpenChange = (open: boolean) => {
    if (!open) {
      if (isBatchProcessing && !isPaused) {
        toast.warning("일괄 처리 중에는 창을 닫을 수 없습니다. 먼저 일시정지하세요.", {
          description: "일괄 OCR 처리가 진행 중입니다..."
        })
        return
      }
      resetBatchUpload()
    }
    setIsBatchDialogOpen(open)
  }

  const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0]
    if (file) {
      setSelectedFile(file)
    }
  }

  // 멀티 파일 선택/드롭 핸들러
  const handleFilesSelect = (files: FileList | File[]) => {
    const newFiles = Array.from(files).map(file => ({
      id: `${file.name}-${Date.now()}-${Math.random()}`,
      file,
      status: 'pending' as const
    }))

    // 파일 검증
    const validFiles = newFiles.filter(item => {
      const error = validateFile(item.file)
      if (error) {
        toast.error(`${item.file.name}: ${error}`)
        return false
      }
      return true
    })

    setFileQueue(prev => [...prev, ...validFiles])
    setBatchProgress(prev => ({ ...prev, total: prev.total + validFiles.length }))

    if (validFiles.length > 0) {
      toast.success(`${validFiles.length}개 파일이 대기열에 추가되었습니다`)
    }
  }

  const validateFile = (file: File): string | null => {
    // 파일 크기 체크 (10MB)
    if (file.size > 10 * 1024 * 1024) {
      return "파일 크기는 10MB 미만이어야 합니다"
    }

    // 파일 타입 체크
    const allowedTypes = [
      'application/pdf',
      'image/jpeg',
      'image/jpg',
      'image/png',
      'image/tiff',
      'image/bmp'
    ]

    if (!allowedTypes.includes(file.type)) {
      return "PDF 및 이미지 파일(JPG, PNG, TIFF, BMP)만 지원됩니다"
    }

    return null
  }

  // 단일 파일 업로드
  const uploadFile = async () => {
    if (!selectedFile) {
      toast.error("먼저 파일을 선택하세요")
      return
    }

    const validationError = validateFile(selectedFile)
    if (validationError) {
      toast.error(validationError)
      return
    }

    try {
      setIsUploading(true)
      setUploadProgress({
        stage: "preparing",
        progress: 10,
        message: "파일 업로드 준비 중..."
      })

      const formData = new FormData()
      formData.append('file', selectedFile)

      setUploadProgress({
        stage: "uploading",
        progress: 30,
        message: "파일 업로드 및 처리 중..."
      })

      const response = await fetch('/api/ocr/enhanced', {
        method: 'POST',
        body: formData,
      })

      setUploadProgress({
        stage: "processing",
        progress: 70,
        message: "OCR을 사용하여 문서 분석 중..."
      })

      if (!response.ok) {
        const errorData = await response.json()
        throw new Error(errorData.error || 'OCR 처리가 실패했습니다')
      }

      const result = await response.json()

      setUploadProgress({
        stage: "saving",
        progress: 90,
        message: "결과를 데이터베이스에 저장 중..."
      })

      if (result.success) {
        setUploadProgress({
          stage: "complete",
          progress: 100,
          message: "OCR 처리가 성공적으로 완료되었습니다!"
        })

        toast.success(
          `OCR 완료! ${result.metadata.totalTables}개 테이블에서 ${result.metadata.totalRows}개 행을 추출했습니다`,
          {
            description: result.warnings?.length
              ? `경고: ${result.warnings.join(', ')}`
              : undefined
          }
        )

        setTimeout(() => {
          setIsUploadDialogOpen(false)
          resetUpload()
          window.location.reload()
        }, 2000)

      } else {
        throw new Error(result.error || '알 수 없는 오류가 발생했습니다')
      }

    } catch (error) {
      console.error('파일 업로드 오류:', error)
      toast.error(
        error instanceof Error
          ? error.message
          : '파일 처리 중 오류가 발생했습니다'
      )
      setUploadProgress(null)
    } finally {
      setIsUploading(false)
    }
  }

  // 배치 처리 시작
  const startBatchProcessing = async () => {
    const pendingFiles = fileQueue.filter(item => item.status === 'pending')
    if (pendingFiles.length === 0) {
      toast.warning("처리할 파일이 없습니다")
      return
    }

    setIsBatchProcessing(true)
    setIsPaused(false)
    batchControllerRef.current = new AbortController()

    let processed = 0

    for (const fileItem of pendingFiles) {
      // 일시정지 체크
      if (isPaused) {
        break
      }

      // 중단 체크
      if (batchControllerRef.current?.signal.aborted) {
        break
      }

      try {
        // 파일 상태를 processing으로 변경
        setFileQueue(prev => prev.map(item => 
          item.id === fileItem.id 
            ? { ...item, status: 'processing' as const }
            : item
        ))

        setBatchProgress(prev => ({ 
          ...prev, 
          current: fileItem.file.name 
        }))

        // 개별 파일 처리
        const result = await processSingleFileInBatch(fileItem)

        // 결과에 따라 상태 업데이트
        if (result.success) {
          setFileQueue(prev => prev.map(item => 
            item.id === fileItem.id 
              ? { 
                  ...item, 
                  status: 'completed' as const,
                  result: {
                    totalTables: result.metadata.totalTables,
                    totalRows: result.metadata.totalRows,
                    sessionId: result.sessionId
                  }
                }
              : item
          ))
          processed++
        } else {
          throw new Error(result.error || '처리가 실패했습니다')
        }

      } catch (error) {
        // 실패 상태로 변경
        setFileQueue(prev => prev.map(item => 
          item.id === fileItem.id 
            ? { 
                ...item, 
                status: 'failed' as const,
                error: error instanceof Error ? error.message : '알 수 없는 오류'
              }
            : item
        ))

        setBatchProgress(prev => ({ 
          ...prev, 
          failed: prev.failed + 1 
        }))
      }

      setBatchProgress(prev => ({ 
        ...prev, 
        completed: prev.completed + 1 
      }))

      // 다음 파일 처리 전 잠시 대기 (API 부하 방지)
      await new Promise(resolve => setTimeout(resolve, 1000))
    }

    setIsBatchProcessing(false)
    setBatchProgress(prev => ({ ...prev, current: undefined }))

    const completedCount = fileQueue.filter(item => item.status === 'completed').length
    const failedCount = fileQueue.filter(item => item.status === 'failed').length

    toast.success(
      `일괄 처리 완료! ${completedCount}개 성공, ${failedCount}개 실패`,
      { description: "이제 테이블을 새로고침하여 새 데이터를 확인할 수 있습니다" }
    )
  }

  // 개별 파일 처리 (배치 내에서)
  const processSingleFileInBatch = async (fileItem: FileUploadItem) => {
    const formData = new FormData()
    formData.append('file', fileItem.file)

    const response = await fetch('/api/ocr/enhanced', {
      method: 'POST',
      body: formData,
      signal: batchControllerRef.current?.signal
    })

    if (!response.ok) {
      const errorData = await response.json()
      throw new Error(errorData.error || 'OCR 처리가 실패했습니다')
    }

    return await response.json()
  }

  // 배치 처리 일시정지/재개
  const toggleBatchPause = () => {
    setIsPaused(prev => !prev)
    if (isPaused) {
      toast.info("일괄 처리가 재개되었습니다")
    } else {
      toast.info("현재 파일 처리 후 일시정지됩니다")
    }
  }

  // 배치 처리 중단
  const stopBatchProcessing = () => {
    batchControllerRef.current?.abort()
    setIsBatchProcessing(false)
    setIsPaused(false)
    setBatchProgress(prev => ({ ...prev, current: undefined }))
    toast.info("일괄 처리가 중단되었습니다")
  }

  // 파일 큐에서 제거
  const removeFileFromQueue = (fileId: string) => {
    setFileQueue(prev => {
      const newQueue = prev.filter(item => item.id !== fileId)
      const removedItem = prev.find(item => item.id === fileId)
      
      if (removedItem?.status === 'pending') {
        setBatchProgress(prevProgress => ({ 
          ...prevProgress, 
          total: prevProgress.total - 1 
        }))
      }
      
      return newQueue
    })
  }

  // 실패한 파일들 재시도
  const retryFailedFiles = () => {
    setFileQueue(prev => prev.map(item => 
      item.status === 'failed' 
        ? { ...item, status: 'pending' as const, error: undefined }
        : item
    ))
    
    const failedCount = fileQueue.filter(item => item.status === 'failed').length
    setBatchProgress(prev => ({ 
      ...prev, 
      failed: 0,
      total: prev.total + failedCount
    }))
    
    toast.success(`${failedCount}개의 실패한 파일이 대기열에 다시 추가되었습니다`)
  }

  // 완료된 파일들 제거
  const clearCompletedFiles = () => {
    const completedCount = fileQueue.filter(item => item.status === 'completed').length
    setFileQueue(prev => prev.filter(item => item.status !== 'completed'))
    setBatchProgress(prev => ({ 
      ...prev, 
      completed: Math.max(0, prev.completed - completedCount)
    }))
    toast.success(`${completedCount}개의 완료된 파일이 대기열에서 제거되었습니다`)
  }

  const resetUpload = () => {
    setSelectedFile(null)
    setUploadProgress(null)
    if (fileInputRef.current) {
      fileInputRef.current.value = ''
    }
  }

  const resetBatchUpload = () => {
    if (isBatchProcessing) {
      stopBatchProcessing()
    }
    setFileQueue([])
    setBatchProgress({ total: 0, completed: 0, failed: 0 })
  }

  const handleCancelClick = () => {
    if (isUploading && uploadProgress?.stage !== "complete") {
      toast.warning("처리 중에는 취소할 수 없습니다. 완료될 때까지 기다려주세요.", {
        description: "OCR 처리를 안전하게 중단할 수 없습니다."
      })
    } else {
      setIsUploadDialogOpen(false)
      resetUpload()
    }
  }

  // 현재 페이지 데이터만 내보내기
  const exportCurrentPage = () => {
    exportTableToExcel(table, {
      filename: "OCR 결과 (현재 페이지)",
      excludeColumns: ["select", "actions"],
    })
  }

  // 전체 데이터 내보내기
  const exportAllData = async () => {
    if (isExporting) return

    setIsExporting(true)

    try {
      toast.loading("전체 데이터를 가져오는 중...", {
        description: "잠시만 기다려주세요."
      })

      const allData = await getOcrAllRows()
      toast.dismiss()

      if (allData.length === 0) {
        toast.warning("내보낼 데이터가 없습니다.")
        return
      }

      await exportOcrDataToExcel(allData, `OCR 결과 (전체 데이터 - ${allData.length}개 행)`)
      toast.success(`전체 데이터 ${allData.length}개 행이 성공적으로 내보내졌습니다.`)

    } catch (error) {
      console.error('전체 데이터 내보내기 오류:', error)
      toast.error('전체 데이터 내보내기 중 오류가 발생했습니다.')
    } finally {
      setIsExporting(false)
    }
  }

  // 삭제 후 콜백 - 테이블 새로고침
  const handleDeleteSuccess = () => {
    // 선택 해제
    table.resetRowSelection()
    // 페이지 새로고침
    window.location.reload()
  }

  const getStatusBadgeVariant = (status: FileUploadItem['status']) => {
    switch (status) {
      case 'pending': return 'secondary'
      case 'processing': return 'default'
      case 'completed': return 'default'
      case 'failed': return 'destructive'
      default: return 'secondary'
    }
  }

  const getStatusIcon = (status: FileUploadItem['status']) => {
    switch (status) {
      case 'pending': return <FileText className="size-4" />
      case 'processing': return <Loader2 className="size-4 animate-spin" />
      case 'completed': return <FileText className="size-4 text-green-600" />
      case 'failed': return <FileText className="size-4 text-red-600" />
      default: return <FileText className="size-4" />
    }
  }

  const getStatusText = (status: FileUploadItem['status']) => {
    switch (status) {
      case 'pending': return '대기 중'
      case 'processing': return '처리 중'
      case 'completed': return '완료'
      case 'failed': return '실패'
      default: return '대기 중'
    }
  }

  return (
    <div className="flex items-center gap-2">
      {/* 선택된 행이 있을 때만 삭제 버튼 표시 */}
      {selectedRows.length > 0 && (
        <DeleteOcrRowsDialog
          ocrRows={selectedRows}
          onSuccess={handleDeleteSuccess}
        />
      )}

      {/* 단일 파일 OCR 업로드 다이얼로그 */}
      <Dialog open={isUploadDialogOpen} onOpenChange={handleDialogOpenChange}>
        <DialogTrigger asChild>
          <Button variant="samsung" size="sm" className="gap-2">
            <Upload className="size-4" aria-hidden="true" />
            <span className="hidden sm:inline">OCR 업로드</span>
          </Button>
        </DialogTrigger>
        <DialogContent
          className="sm:max-w-md"
          onEscapeKeyDown={(e) => {
            if (isUploading && uploadProgress?.stage !== "complete") {
              e.preventDefault()
              toast.warning("처리 중에는 창을 닫을 수 없습니다. 완료될 때까지 기다려주세요.")
            }
          }}
          onInteractOutside={(e) => {
            if (isUploading && uploadProgress?.stage !== "complete") {
              e.preventDefault()
              toast.warning("처리 중에는 창을 닫을 수 없습니다. 완료될 때까지 기다려주세요.")
            }
          }}
        >
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              OCR용 문서 업로드
              {isUploading && uploadProgress?.stage !== "complete" && (
                <Loader2 className="size-4 animate-spin text-muted-foreground" />
              )}
            </DialogTitle>
            <DialogDescription>
              {isUploading && uploadProgress?.stage !== "complete"
                ? "처리가 진행 중입니다. 이 창을 닫지 마세요."
                : "OCR 기술을 사용하여 테이블 데이터를 추출할 PDF 또는 이미지 파일을 업로드하세요."
              }
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-4">
            <div className="space-y-2">
              <Label htmlFor="file-upload">파일 선택</Label>
              <Input
                ref={fileInputRef}
                id="file-upload"
                type="file"
                accept=".pdf,.jpg,.jpeg,.png,.tiff,.bmp"
                onChange={handleFileSelect}
                disabled={isUploading}
              />
              <p className="text-xs text-muted-foreground">
                지원 형식: PDF, JPG, PNG, TIFF, BMP (최대 10MB)
              </p>
            </div>

            {selectedFile && (
              <div className="rounded-lg border p-3 space-y-2">
                <div className="flex items-center gap-2">
                  <FileText className="size-4 text-muted-foreground" />
                  <span className="text-sm font-medium">{selectedFile.name}</span>
                </div>
                <div className="flex items-center gap-4 text-xs text-muted-foreground">
                  <span>크기: {(selectedFile.size / 1024 / 1024).toFixed(2)} MB</span>
                  <span>형식: {selectedFile.type}</span>
                </div>
              </div>
            )}

            {uploadProgress && (
              <div className="space-y-3">
                <div className="flex items-center justify-between">
                  <span className="text-sm font-medium">처리 중...</span>
                  <Badge variant={uploadProgress.stage === "complete" ? "default" : "secondary"}>
                    {uploadProgress.stage === "preparing" && "준비 중"}
                    {uploadProgress.stage === "uploading" && "업로드 중"}
                    {uploadProgress.stage === "processing" && "처리 중"}
                    {uploadProgress.stage === "saving" && "저장 중"}
                    {uploadProgress.stage === "complete" && "완료"}
                  </Badge>
                </div>
                <Progress value={uploadProgress.progress} className="h-2" />
                <p className="text-xs text-muted-foreground">
                  {uploadProgress.message}
                </p>

                {isUploading && uploadProgress.stage !== "complete" && (
                  <div className="flex items-center gap-2 p-2 bg-blue-50 dark:bg-blue-950/20 rounded-md">
                    <Loader2 className="size-3 animate-spin text-blue-600" />
                    <p className="text-xs text-blue-700 dark:text-blue-300">
                      잠시만 기다려주세요... 완료되면 이 창이 자동으로 닫힙니다.
                    </p>
                  </div>
                )}
              </div>
            )}

            <div className="flex justify-end gap-2">
              <Button
                variant="outline"
                size="sm"
                onClick={handleCancelClick}
                disabled={false}
              >
                {isUploading && uploadProgress?.stage !== "complete" ? "닫기" : "취소"}
              </Button>
              <Button
                size="sm"
                onClick={uploadFile}
                disabled={!selectedFile || isUploading}
                className="gap-2"
              >
                {isUploading ? (
                  <Loader2 className="size-4 animate-spin" aria-hidden="true" />
                ) : (
                  <Upload className="size-4" aria-hidden="true" />
                )}
                {isUploading ? "처리 중..." : "OCR 시작"}
              </Button>
            </div>
          </div>
        </DialogContent>
      </Dialog>

      {/* 배치 파일 OCR 업로드 다이얼로그 */}
      <Dialog open={isBatchDialogOpen} onOpenChange={handleBatchDialogOpenChange}>
        <DialogTrigger asChild>
          <Button variant="outline" size="sm" className="gap-2">
            <Upload className="size-4" aria-hidden="true" />
            <span className="hidden sm:inline">일괄 업로드</span>
          </Button>
        </DialogTrigger>
        <DialogContent 
          className="sm:max-w-2xl max-h-[80vh] overflow-hidden flex flex-col"
          onEscapeKeyDown={(e) => {
            if (isBatchProcessing && !isPaused) {
              e.preventDefault()
              toast.warning("일괄 처리 중에는 창을 닫을 수 없습니다. 먼저 일시정지하세요.")
            }
          }}
          onInteractOutside={(e) => {
            if (isBatchProcessing && !isPaused) {
              e.preventDefault()
              toast.warning("일괄 처리 중에는 창을 닫을 수 없습니다. 먼저 일시정지하세요.")
            }
          }}
        >
          <DialogHeader>
            <DialogTitle className="flex items-center justify-between">
              <span className="flex items-center gap-2">
                일괄 OCR 업로드
                {isBatchProcessing && (
                  <Loader2 className="size-4 animate-spin text-muted-foreground" />
                )}
              </span>
              <div className="flex items-center gap-2 text-sm text-muted-foreground">
                <span>전체: {batchProgress.total}</span>
                <span>완료: {batchProgress.completed}</span>
                {batchProgress.failed > 0 && (
                  <span className="text-red-600">실패: {batchProgress.failed}</span>
                )}
              </div>
            </DialogTitle>
            <DialogDescription>
              {isBatchProcessing && !isPaused
                ? `파일 처리 중... 현재: ${batchProgress.current || '시작 중...'}`
                : "여러 파일을 드래그 앤 드롭하거나 선택하여 일괄 처리하세요."
              }
            </DialogDescription>
          </DialogHeader>

          <div className="flex-1 overflow-hidden flex flex-col space-y-4">
            {/* 파일 드롭존 */}
            {fileQueue.length === 0 && (
              <Dropzone onDrop={handleFilesSelect} className="border-2 border-dashed border-gray-300 rounded-lg">
                <DropzoneZone>
                  <DropzoneUploadIcon />
                  <DropzoneTitle>파일을 여기로 드래그하거나 클릭하여 선택</DropzoneTitle>
                  <DropzoneDescription>
                    PDF, JPG, PNG, TIFF, BMP 파일 지원 (각각 최대 10MB)
                  </DropzoneDescription>
                  <DropzoneInput 
                    multiple 
                    accept=".pdf,.jpg,.jpeg,.png,.tiff,.bmp"
                    onChange={(e) => e.target.files && handleFilesSelect(e.target.files)}
                  />
                </DropzoneZone>
              </Dropzone>
            )}

            {/* 배치 진행 상황 */}
            {batchProgress.total > 0 && (
              <div className="space-y-2">
                <div className="flex items-center justify-between text-sm">
                  <span>진행률: {batchProgress.completed + batchProgress.failed} / {batchProgress.total}</span>
                  <span>{Math.round(((batchProgress.completed + batchProgress.failed) / batchProgress.total) * 100)}%</span>
                </div>
                <Progress 
                  value={((batchProgress.completed + batchProgress.failed) / batchProgress.total) * 100} 
                  className="h-2" 
                />
                {batchProgress.current && (
                  <p className="text-xs text-muted-foreground">
                    현재 처리 중: {batchProgress.current}
                  </p>
                )}
              </div>
            )}

            {/* 파일 목록 */}
            {fileQueue.length > 0 && (
              <div className="flex-1  overflow-y-auto">
                <FileList className="h-full overflow-y-auto">
                  <FileListHeader>
                    <div className="flex items-center justify-between">
                      <span>파일 ({fileQueue.length}개)</span>
                      <div className="flex items-center gap-1">
                        <Button
                          variant="ghost"
                          size="sm"
                          onClick={() => {
                            const input = document.createElement('input')
                            input.type = 'file'
                            input.multiple = true
                            input.accept = '.pdf,.jpg,.jpeg,.png,.tiff,.bmp'
                            input.onchange = (e) => {
                              const files = (e.target as HTMLInputElement).files
                              if (files) handleFilesSelect(files)
                            }
                            input.click()
                          }}
                          className="gap-1"
                        >
                          <Upload className="size-3" />
                          추가
                        </Button>
                        {fileQueue.some(item => item.status === 'failed') && (
                          <Button
                            variant="ghost"
                            size="sm"
                            onClick={retryFailedFiles}
                            className="gap-1"
                          >
                            <RotateCcw className="size-3" />
                            실패 재시도
                          </Button>
                        )}
                        {fileQueue.some(item => item.status === 'completed') && (
                          <Button
                            variant="ghost"
                            size="sm"
                            onClick={clearCompletedFiles}
                            className="gap-1"
                          >
                            <X className="size-3" />
                            완료 제거
                          </Button>
                        )}
                      </div>
                    </div>
                  </FileListHeader>

                  {fileQueue.map((fileItem) => (
                    <FileListItem key={fileItem.id} className="flex items-center justify-between gap-3">
                      <FileListIcon>
                        {getStatusIcon(fileItem.status)}
                      </FileListIcon>
                      <FileListInfo>
                        <FileListName>{fileItem.file.name}</FileListName>
                        <FileListDescription>
                          <FileListSize>
                            {fileItem.file.size}
                          </FileListSize>
                          {fileItem.result && (
                            <span className="ml-2 text-green-600">
                              {fileItem.result.totalTables}개 테이블, {fileItem.result.totalRows}개 행
                            </span>
                          )}
                          {fileItem.error && (
                            <span className="ml-2 text-red-600 text-xs">
                              오류: {fileItem.error}
                            </span>
                          )}
                        </FileListDescription>
                      </FileListInfo>
                      <div className="flex items-center gap-2">
                        <Badge variant={getStatusBadgeVariant(fileItem.status)}>
                          {getStatusText(fileItem.status)}
                        </Badge>
                        {fileItem.status !== 'processing' && (
                          <FileListAction
                            onClick={() => removeFileFromQueue(fileItem.id)}
                            disabled={isBatchProcessing && fileItem.status === 'processing'}
                          >
                            <X className="size-4" />
                          </FileListAction>
                        )}
                      </div>
                    </FileListItem>
                  ))}
                </FileList>
              </div>
            )}

            {/* 액션 버튼들 */}
            <div className="flex justify-between">
              <Button
                variant="outline"
                size="sm"
                onClick={() => {
                  if (isBatchProcessing && !isPaused) {
                    toast.warning("먼저 처리를 일시정지하세요")
                  } else {
                    setIsBatchDialogOpen(false)
                    resetBatchUpload()
                  }
                }}
              >
                {isBatchProcessing && !isPaused ? "닫기" : "취소"}
              </Button>

              <div className="flex items-center gap-2">
                {isBatchProcessing && (
                  <>
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={toggleBatchPause}
                      className="gap-2"
                    >
                      {isPaused ? (
                        <Play className="size-4" />
                      ) : (
                        <Pause className="size-4" />
                      )}
                      {isPaused ? "재개" : "일시정지"}
                    </Button>
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={stopBatchProcessing}
                      className="gap-2"
                    >
                      <X className="size-4" />
                      중단
                    </Button>
                  </>
                )}
                <Button
                  size="sm"
                  onClick={startBatchProcessing}
                  disabled={fileQueue.filter(item => item.status === 'pending').length === 0 || isBatchProcessing}
                  className="gap-2"
                >
                  {isBatchProcessing ? (
                    <Loader2 className="size-4 animate-spin" />
                  ) : (
                    <Play className="size-4" />
                  )}
                  {isBatchProcessing ? "처리 중..." : "일괄 시작"}
                </Button>
              </div>
            </div>
          </div>
        </DialogContent>
      </Dialog>

      {/* Export 드롭다운 메뉴 */}
      <DropdownMenu>
        <DropdownMenuTrigger asChild>
          <Button
            variant="outline"
            size="sm"
            className="gap-2"
            disabled={isExporting}
          >
            {isExporting ? (
              <Loader2 className="size-4 animate-spin" aria-hidden="true" />
            ) : (
              <Download className="size-4" aria-hidden="true" />
            )}
            <span className="hidden sm:inline">
              {isExporting ? "내보내는 중..." : "내보내기"}
            </span>
            <ChevronDown className="size-3" aria-hidden="true" />
          </Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent align="end" className="w-[200px]">
          <DropdownMenuItem onClick={exportAllData} disabled={isExporting}>
            <Download className="mr-2 size-4" />
            전체 데이터 내보내기
          </DropdownMenuItem>
          <DropdownMenuSeparator />
          <DropdownMenuItem onClick={exportCurrentPage} disabled={isExporting}>
            <Download className="mr-2 size-4" />
            현재 페이지 내보내기
          </DropdownMenuItem>
        </DropdownMenuContent>
      </DropdownMenu>
    </div>
  )
}