"use client"

import { useTranslations } from "next-intl"
import { UploadCloud, X } from "lucide-react"

import { Button } from "@/shared/components/ui/button"
import { Progress } from "@/shared/components/ui/progress"
import { cn } from "@/shared/lib/utils"
import { formatFileSize } from "@/shared/lib/file-storage"

import { FileIcon } from "./file-icon"
import { useFileUpload } from "../hooks/use-file-upload"
import type { FileTargetType, FileUploadResult } from "../types"

interface FileUploadProps {
  targetType?: FileTargetType
  targetId?: string
  onUploaded?: (result: FileUploadResult) => void
  multiple?: boolean
  className?: string
}

export function FileUpload({
  targetType,
  targetId,
  onUploaded,
  multiple = true,
  className,
}: FileUploadProps): React.ReactElement {
  const t = useTranslations("files.upload")
  const {
    tasks,
    isDragging,
    inputRef,
    setIsDragging,
    handleFiles,
    removeTask,
    acceptAttr,
    maxFileSize,
  } = useFileUpload({ targetType, targetId, multiple, onUploaded })

  return (
    <div className={cn("space-y-4", className)}>
      <div
        role="button"
        tabIndex={0}
        aria-describedby="file-upload-hint"
        onClick={() => inputRef.current?.click()}
        onKeyDown={(e) => {
          if (e.key === "Enter" || e.key === " ") {
            e.preventDefault()
            inputRef.current?.click()
          }
        }}
        onDragOver={(e) => {
          e.preventDefault()
          setIsDragging(true)
        }}
        onDragLeave={() => setIsDragging(false)}
        onDrop={(e) => {
          e.preventDefault()
          setIsDragging(false)
          handleFiles(e.dataTransfer.files)
        }}
        className={cn(
          "flex cursor-pointer flex-col items-center justify-center rounded-lg border-2 border-dashed p-8 text-center transition-colors",
          isDragging
            ? "border-primary bg-primary/5"
            : "border-input hover:border-primary/50 hover:bg-accent/50"
        )}
      >
        <UploadCloud className="h-10 w-10 text-muted-foreground" aria-hidden="true" />
        <p className="mt-2 text-sm font-medium">{t("title")}</p>
        <p id="file-upload-hint" className="mt-1 text-xs text-muted-foreground">
          {t("hint", { size: formatFileSize(maxFileSize) })}
        </p>
        <input
          ref={inputRef}
          type="file"
          className="hidden"
          accept={acceptAttr}
          multiple={multiple}
          aria-label={t("title")}
          onChange={(e) => {
            handleFiles(e.target.files)
            e.target.value = ""
          }}
        />
      </div>

      {tasks.length > 0 ? (
        <ul className="space-y-2" aria-live="polite">
          {tasks.map((task, idx) => (
            <li
              key={`${task.file.name}-${idx}`}
              className="flex items-center gap-3 rounded-md border p-3"
            >
              <FileIcon mimeType={task.file.type} />
              <div className="min-w-0 flex-1 space-y-1">
                <div className="flex items-center justify-between gap-2">
                  <span className="truncate text-sm font-medium">
                    {task.file.name}
                  </span>
                  <span className="shrink-0 text-xs text-muted-foreground">
                    {formatFileSize(task.file.size)}
                  </span>
                </div>
                {task.status === "uploading" ? (
                  <Progress
                    value={task.progress}
                    className="h-1.5"
                    aria-label={`Uploading ${task.file.name}`}
                  />
                ) : null}
                {task.status === "error" ? (
                  <p className="text-xs text-destructive">{task.message}</p>
                ) : null}
                {task.status === "success" ? (
                  <p className="text-xs text-green-600">{t("uploaded")}</p>
                ) : null}
              </div>
              <Button
                type="button"
                variant="ghost"
                size="icon"
                className="h-7 w-7"
                onClick={() => removeTask(task)}
                aria-label={t("remove")}
              >
                <X className="h-4 w-4" aria-hidden="true" />
              </Button>
            </li>
          ))}
        </ul>
      ) : null}
    </div>
  )
}
