"use client"

import { useState, useCallback } from "react"
import { DashboardLayout } from "@/components/dashboard-layout"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Save, ArrowRight, ArrowLeft, Upload, FileText, X, Check } from "lucide-react"
import { useRouter } from "next/navigation"
import { useDropzone } from "react-dropzone"
import { toast } from "@/lib/toast"
import { LoadingSpinner } from "@/components/loading-spinner"

interface UploadedFile {
  id: string
  name: string
  size: number
  type: string
  category: string
  uploaded: boolean
}

export default function UploadsPage() {
  const router = useRouter()
  const [uploadedFiles, setUploadedFiles] = useState<UploadedFile[]>([])
  const [isSaving, setIsSaving] = useState(false)

  const requiredDocuments = [
    { category: "passport", label: "Passport Photograph", required: true },
    { category: "certificate", label: "Educational Certificate", required: true },
    { category: "transcript", label: "Academic Transcript", required: true },
    { category: "birth_certificate", label: "Birth Certificate", required: true },
    { category: "identification", label: "Valid ID (National ID/Passport)", required: true },
    { category: "medical", label: "Medical Report", required: false },
    { category: "recommendation", label: "Letter of Recommendation", required: false },
  ]

  const onDrop = useCallback((acceptedFiles: File[], rejectedFiles: any[], category: string) => {
    // Handle rejected files
    if (rejectedFiles.length > 0) {
      const errors = rejectedFiles.map(({ file, errors }) => {
        const errorMessages = errors.map((e: any) => {
          switch (e.code) {
            case "file-too-large":
              return `${file.name} is too large (max 5MB)`
            case "file-invalid-type":
              return `${file.name} has invalid file type`
            default:
              return `${file.name} was rejected`
          }
        })
        return errorMessages.join(", ")
      })
      toast.error(`Upload failed: ${errors.join("; ")}`)
      return
    }

    const newFiles = acceptedFiles.map((file) => ({
      id: Date.now().toString() + Math.random().toString(),
      name: file.name,
      size: file.size,
      type: file.type,
      category,
      uploaded: false,
    }))

    setUploadedFiles((prev) => {
      // Remove existing files for this category if any
      const filtered = prev.filter((f) => f.category !== category)
      return [...filtered, ...newFiles]
    })

    // Show upload started message
    toast.info(`Uploading ${newFiles.length} file(s)...`)

    // Simulate upload process
    newFiles.forEach((file) => {
      setTimeout(() => {
        setUploadedFiles((prev) => prev.map((f) => (f.id === file.id ? { ...f, uploaded: true } : f)))
        toast.success(`${file.name} uploaded successfully`)
      }, 2000)
    })
  }, [])

  const removeFile = (fileId: string) => {
    const file = uploadedFiles.find((f) => f.id === fileId)
    setUploadedFiles((prev) => prev.filter((f) => f.id !== fileId))
    if (file) {
      toast.info(`${file.name} removed`)
    }
  }

  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 Number.parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i]
  }

  const getFileForCategory = (category: string) => {
    return uploadedFiles.find((f) => f.category === category)
  }

  const validateForm = () => {
    const missingRequired = requiredDocuments
      .filter((doc) => doc.required)
      .filter((doc) => !getFileForCategory(doc.category))

    if (missingRequired.length > 0) {
      const missingLabels = missingRequired.map((d) => d.label).join(", ")
      toast.error(`Please upload the following required documents: ${missingLabels}`)
      return false
    }
    return true
  }

  const handleSaveDraft = async () => {
    setIsSaving(true)
    const loadingToast = toast.loading("Saving draft...")

    try {
      // Simulate API call
      await new Promise((resolve) => setTimeout(resolve, 1000))
      toast.dismiss(loadingToast)
      toast.success("Draft saved successfully!")
    } catch (error) {
      toast.dismiss(loadingToast)
      toast.error("Failed to save draft. Please try again.")
    } finally {
      setIsSaving(false)
    }
  }

  const handleNext = () => {
    if (validateForm()) {
      handleSaveDraft()
      router.push("/dashboard/applications/declaration")
    }
  }

  const handlePrevious = () => {
    router.push("/dashboard/applications/referee")
  }

  const FileUploadZone = ({ category, label, required }: { category: string; label: string; required: boolean }) => {
    const { getRootProps, getInputProps, isDragActive } = useDropzone({
      onDrop: (accepted, rejected) => onDrop(accepted, rejected, category),
      accept: {
        "image/*": [".jpeg", ".jpg", ".png"],
        "application/pdf": [".pdf"],
        "application/msword": [".doc"],
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document": [".docx"],
      },
      maxSize: 5 * 1024 * 1024, // 5MB
      multiple: false,
    })

    const existingFile = getFileForCategory(category)

    return (
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            {label}
            {required && (
              <span className="text-red-500" aria-label="required">
                *
              </span>
            )}
            {existingFile?.uploaded && <Check className="h-4 w-4 text-green-600" aria-label="uploaded" />}
          </CardTitle>
          <CardDescription>
            Upload {label.toLowerCase()}. Accepted formats: PDF, DOC, DOCX, JPG, PNG (Max 5MB)
          </CardDescription>
        </CardHeader>
        <CardContent>
          {existingFile ? (
            <div className="flex items-center justify-between p-3 border rounded-lg bg-muted/50">
              <div className="flex items-center gap-3">
                <FileText className="h-5 w-5 text-muted-foreground" aria-hidden="true" />
                <div>
                  <p className="font-medium text-sm">{existingFile.name}</p>
                  <p className="text-xs text-muted-foreground">{formatFileSize(existingFile.size)}</p>
                </div>
              </div>
              <div className="flex items-center gap-2">
                {existingFile.uploaded ? (
                  <span className="text-xs text-green-600 font-medium">Uploaded</span>
                ) : (
                  <span className="text-xs text-orange-600 font-medium flex items-center gap-1">
                    <LoadingSpinner size="sm" />
                    Uploading...
                  </span>
                )}
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={() => removeFile(existingFile.id)}
                  aria-label={`Remove ${existingFile.name}`}
                >
                  <X className="h-4 w-4" />
                </Button>
              </div>
            </div>
          ) : (
            <div
              {...getRootProps()}
              className={`border-2 border-dashed rounded-lg p-6 text-center cursor-pointer transition-colors ${
                isDragActive ? "border-accent bg-accent/10" : "border-muted-foreground/25 hover:border-accent"
              }`}
              role="button"
              tabIndex={0}
              aria-label={`Upload ${label.toLowerCase()}`}
            >
              <input {...getInputProps()} />
              <Upload className="h-8 w-8 text-muted-foreground mx-auto mb-2" aria-hidden="true" />
              {isDragActive ? (
                <p className="text-sm text-accent">Drop the file here...</p>
              ) : (
                <div>
                  <p className="text-sm font-medium">Click to upload or drag and drop</p>
                  <p className="text-xs text-muted-foreground mt-1">PDF, DOC, DOCX, JPG, PNG up to 5MB</p>
                </div>
              )}
            </div>
          )}
        </CardContent>
      </Card>
    )
  }

  return (
    <DashboardLayout>
      <div className="max-w-4xl mx-auto space-y-6">
        <div>
          <h1 className="text-3xl font-bold text-primary">Document Uploads</h1>
          <p className="text-muted-foreground">
            Please upload all required documents. Documents marked with * are mandatory.
          </p>
        </div>

        <div className="space-y-4">
          {requiredDocuments.map((doc) => (
            <FileUploadZone key={doc.category} category={doc.category} label={doc.label} required={doc.required} />
          ))}
        </div>

        {/* Upload Summary */}
        <Card>
          <CardHeader>
            <CardTitle>Upload Summary</CardTitle>
            <CardDescription>Review your uploaded documents</CardDescription>
          </CardHeader>
          <CardContent>
            <div className="space-y-2">
              {requiredDocuments.map((doc) => {
                const file = getFileForCategory(doc.category)
                return (
                  <div key={doc.category} className="flex items-center justify-between py-2">
                    <span className="text-sm">
                      {doc.label}
                      {doc.required && <span className="text-red-500 ml-1">*</span>}
                    </span>
                    <span
                      className={`text-xs px-2 py-1 rounded-full ${
                        file?.uploaded
                          ? "bg-green-100 text-green-700"
                          : file
                            ? "bg-orange-100 text-orange-700"
                            : doc.required
                              ? "bg-red-100 text-red-700"
                              : "bg-gray-100 text-gray-700"
                      }`}
                    >
                      {file?.uploaded ? "Uploaded" : file ? "Uploading" : doc.required ? "Required" : "Optional"}
                    </span>
                  </div>
                )
              })}
            </div>
          </CardContent>
        </Card>

        {/* Action Buttons */}
        <div className="flex justify-between">
          <div className="flex gap-2">
            <Button variant="outline" onClick={handlePrevious}>
              <ArrowLeft className="mr-2 h-4 w-4" />
              Previous
            </Button>
            <Button variant="outline" onClick={handleSaveDraft} disabled={isSaving}>
              {isSaving ? (
                <>
                  <LoadingSpinner size="sm" className="mr-2" />
                  Saving...
                </>
              ) : (
                <>
                  <Save className="mr-2 h-4 w-4" />
                  Save Draft
                </>
              )}
            </Button>
          </div>
          <Button onClick={handleNext} className="bg-accent hover:bg-accent/90">
            Next: Declaration
            <ArrowRight className="ml-2 h-4 w-4" />
          </Button>
        </div>
      </div>
    </DashboardLayout>
  )
}
