"use client"

import React, { useRef, useState } from "react"
import { Button } from "@/components/ui/button"
import { X, FileText, Image, File, Upload, Plus, Music, Video } from "lucide-react"

interface FileUploadProps {
  files: File[]
  onFilesChange: (files: File[]) => void
  maxFiles?: number
  maxSizeMB?: number
  enableMedia?: boolean // Enable audio/video support
  enableDocuments?: boolean // Enable large document support
}

const ALLOWED_TYPES = {
  // Documents
  "application/pdf": [".pdf"],
  "text/plain": [".txt"],
  "text/markdown": [".md"],
  // Images
  "image/png": [".png"],
  "image/jpeg": [".jpg", ".jpeg"],
  "image/gif": [".gif"],
  "image/webp": [".webp"],
}

// Extended document types for WeKnora knowledge base ingestion
const DOCUMENT_TYPES = {
  "application/msword": [".doc"],
  "application/vnd.openxmlformats-officedocument.wordprocessingml.document": [".docx"],
  "application/vnd.ms-excel": [".xls"],
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": [".xlsx"],
  "text/csv": [".csv"],
  "application/json": [".json"],
  "application/rtf": [".rtf"],
  "text/html": [".html", ".htm"],
}

const MEDIA_TYPES = {
  // Audio
  "audio/mpeg": [".mp3"],
  "audio/wav": [".wav"],
  "audio/mp4": [".m4a"],
  "audio/ogg": [".ogg"],
  "audio/flac": [".flac"],
  "audio/aac": [".aac"],
  // Video
  "video/mp4": [".mp4"],
  "video/quicktime": [".mov"],
  "video/x-msvideo": [".avi"],
  "video/x-matroska": [".mkv"],
  "video/webm": [".webm"],
  "video/x-m4v": [".m4v"],
}

export function FileUpload({
  files,
  onFilesChange,
  maxFiles = 10,
  maxSizeMB = 50, // Increased for larger documents
  enableMedia = true,
  enableDocuments = true, // Enable extended document types by default
}: FileUploadProps) {
  const fileInputRef = useRef<HTMLInputElement>(null)
  const [dragActive, setDragActive] = useState(false)
  const [imagePreviews, setImagePreviews] = useState<Map<string, string>>(new Map())

  // Combine allowed types based on flags
  const getAllowedTypes = () => {
    let types = { ...ALLOWED_TYPES }
    if (enableDocuments) {
      types = { ...types, ...DOCUMENT_TYPES }
    }
    if (enableMedia) {
      types = { ...types, ...MEDIA_TYPES }
    }
    return types
  }

  const handleFiles = (fileList: FileList | null) => {
    if (!fileList) return

    const newFiles: File[] = []
    const maxSize = maxSizeMB * 1024 * 1024
    const allowedTypes = getAllowedTypes()

    Array.from(fileList).forEach((file) => {
      // Check file count
      if (files.length + newFiles.length >= maxFiles) {
        return
      }

      // Check file size
      if (file.size > maxSize) {
        alert(`File ${file.name} exceeds ${maxSizeMB}MB limit`)
        return
      }

      // Check file type
      const isValidType = Object.keys(allowedTypes).some((mimeType) => {
        const extensions = allowedTypes[mimeType as keyof typeof allowedTypes]
        return extensions.some((ext) => file.name.toLowerCase().endsWith(ext))
      })

      if (!isValidType) {
        alert(`File type not supported: ${file.name}`)
        return
      }

      newFiles.push(file)
    })

    if (newFiles.length > 0) {
      const updatedFiles = [...files, ...newFiles]
      onFilesChange(updatedFiles)
      
      // Generate image previews for new image files
      newFiles.forEach((file) => {
        if (file.type.startsWith("image/")) {
          const fileKey = `${file.name}-${file.size}`
          const reader = new FileReader()
          reader.onload = (e) => {
            if (e.target?.result) {
              setImagePreviews(prev => new Map(prev).set(fileKey, e.target!.result as string))
            }
          }
          reader.readAsDataURL(file)
        }
      })
    }
  }

  const handleDrag = (e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    if (e.type === "dragenter" || e.type === "dragover") {
      setDragActive(true)
    } else if (e.type === "dragleave") {
      setDragActive(false)
    }
  }

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    setDragActive(false)

    if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
      handleFiles(e.dataTransfer.files)
    }
  }

  const removeFile = (index: number) => {
    const fileToRemove = files[index]
    const newFiles = files.filter((_, i) => i !== index)
    onFilesChange(newFiles)
    // Clean up preview for removed file
    if (fileToRemove) {
      const fileKey = `${fileToRemove.name}-${fileToRemove.size}`
      setImagePreviews(prev => {
        const newMap = new Map(prev)
        newMap.delete(fileKey)
        return newMap
      })
    }
  }

  const getFileIcon = (file: File) => {
    if (file.type === "application/pdf") {
      return <FileText className="w-4 h-4" />
    } else if (file.type.startsWith("image/")) {
      return <Image className="w-4 h-4" />
    } else if (file.type.startsWith("audio/")) {
      return <Music className="w-4 h-4 text-blue-400" />
    } else if (file.type.startsWith("video/")) {
      return <Video className="w-4 h-4 text-purple-400" />
    } else {
      return <File className="w-4 h-4" />
    }
  }

  const formatFileSize = (bytes: number) => {
    if (bytes < 1024) return bytes + " B"
    if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + " KB"
    return (bytes / (1024 * 1024)).toFixed(1) + " MB"
  }

  const isImage = (file: File) => file.type.startsWith("image/")
  const canAddMore = files.length < maxFiles

  // Build accept string based on enableMedia
  const getAcceptString = () => {
    let base = ".pdf,.png,.jpg,.jpeg,.gif,.webp,.txt,.md"
    if (enableDocuments) {
      base += ",.doc,.docx,.xls,.xlsx,.csv,.json,.rtf,.html,.htm"
    }
    if (enableMedia) {
      base += ",.mp3,.wav,.m4a,.ogg,.flac,.aac,.mp4,.mov,.avi,.mkv,.webm,.m4v"
    }
    return base
  }

  const getDescriptionText = () => {
    if (enableDocuments && enableMedia) {
      return `Documents, Images, Audio, Video (max ${maxSizeMB}MB, up to ${maxFiles} files)`
    } else if (enableDocuments) {
      return `PDF, DOC, Excel, CSV, Images (max ${maxSizeMB}MB, up to ${maxFiles} files)`
    } else if (enableMedia) {
      return `PDF, Images, Audio, Video (max ${maxSizeMB}MB, up to ${maxFiles} files)`
    }
    return `PDF, Images, Text files (max ${maxSizeMB}MB, up to ${maxFiles} files)`
  }

  return (
    <div className="space-y-2">
      <input
        ref={fileInputRef}
        type="file"
        title="Upload Files"
        multiple
        accept={getAcceptString()}
        onChange={(e) => handleFiles(e.target.files)}
        className="hidden"
      />

      {/* Show upload area only when no files are present */}
      {files.length === 0 && (
        <div
          className={`border-2 border-dashed rounded-lg p-3 md:p-4 transition-colors ${
            dragActive
              ? "border-primary bg-primary/5"
              : "border-muted-foreground/25 hover:border-muted-foreground/50"
          }`}
          onDragEnter={handleDrag}
          onDragLeave={handleDrag}
          onDragOver={handleDrag}
          onDrop={handleDrop}
        >
          <div className="flex flex-col items-center justify-center space-y-2">
            <Upload className="w-5 h-5 md:w-6 md:h-6 text-muted-foreground" />
            <p className="text-xs md:text-sm text-muted-foreground text-center">
              Drag and drop files here, or{" "}
              <button
                type="button"
                onClick={() => fileInputRef.current?.click()}
                className="text-primary hover:underline"
              >
                browse
              </button>
            </p>
            <p className="text-[10px] md:text-xs text-muted-foreground">
              {getDescriptionText()}
            </p>
          </div>
        </div>
      )}

      {/* Show compact file list when files are present */}
      {files.length > 0 && (
        <div className="space-y-2">
          {/* Horizontal scrollable file list */}
          <div className="flex gap-2 overflow-x-auto pb-2 [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]">
            {files.map((file, index) => (
              <div
                key={index}
                className="flex-shrink-0 w-24 md:w-28 bg-muted/50 rounded-lg border border-white/10 overflow-hidden group relative"
              >
                {/* Image preview or icon */}
                {isImage(file) && imagePreviews.get(`${file.name}-${file.size}`) ? (
                  <div className="relative w-full h-20 md:h-24 bg-muted">
                    <img
                      src={imagePreviews.get(`${file.name}-${file.size}`)}
                      alt={file.name}
                      className="w-full h-full object-cover"
                    />
                    <div className="absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors" />
                  </div>
                ) : (
                  <div className="w-full h-20 md:h-24 bg-muted/80 flex items-center justify-center">
                    {getFileIcon(file)}
                  </div>
                )}
                
                {/* File info */}
                <div className="p-1.5 md:p-2 space-y-0.5">
                  <p className="text-[10px] md:text-xs font-medium truncate" title={file.name}>
                    {file.name}
                  </p>
                  <p className="text-[9px] md:text-[10px] text-muted-foreground">
                    {formatFileSize(file.size)}
                  </p>
                </div>

                {/* Remove button */}
                <Button
                  type="button"
                  variant="ghost"
                  size="sm"
                  onClick={() => removeFile(index)}
                  className="absolute top-1 right-1 h-6 w-6 md:h-7 md:w-7 p-0 rounded-full bg-black/50 hover:bg-black/70 text-white opacity-0 group-hover:opacity-100 transition-opacity"
                >
                  <X className="w-3 h-3 md:w-3.5 md:h-3.5" />
                </Button>
              </div>
            ))}

            {/* Add more files button */}
            {canAddMore && (
              <button
                type="button"
                onClick={() => fileInputRef.current?.click()}
                className="flex-shrink-0 w-24 md:w-28 h-full min-h-[120px] md:min-h-[140px] border-2 border-dashed border-muted-foreground/25 hover:border-primary/50 rounded-lg flex flex-col items-center justify-center gap-1.5 md:gap-2 transition-colors bg-muted/30 hover:bg-muted/50"
              >
                <Plus className="w-5 h-5 md:w-6 md:h-6 text-muted-foreground" />
                <span className="text-[10px] md:text-xs text-muted-foreground text-center px-1">
                  Add more
                </span>
              </button>
            )}
          </div>

          {/* File count indicator */}
          <div className="flex items-center justify-between text-[10px] md:text-xs text-muted-foreground px-1">
            <span>
              {files.length} of {maxFiles} files
            </span>
            {files.length >= maxFiles && (
              <span className="text-orange-500">Maximum reached</span>
            )}
          </div>
        </div>
      )}
    </div>
  )
}

