"use client"

import { useState, useTransition, type ChangeEvent } from "react"
import Image from "next/image"
import { useTranslations } from "next-intl"
import { toast } from "sonner"
import { Upload, X, Loader2, ImageIcon } from "lucide-react"

import { Button } from "@/shared/components/ui/button"
import { cn } from "@/shared/lib/utils"

export interface ScanImage {
  fileId: string
  url: string
  filename: string
  originalName?: string
  /** 页码(从 1 开始) */
  page: number
}

interface ScanUploaderProps {
  /** 已上传的扫描图列表 */
  images: ScanImage[]
  /** 图片列表变化回调(增删/排序后触发) */
  onChange: (images: ScanImage[]) => void
  /** 删除单张扫描图时的服务端回调(可选,用于删除 fileAttachments 记录) */
  onDeleteScan?: (fileId: string) => Promise<void>
  /** 关联的提交 ID(用于权限校验) */
  submissionId: string
  /** 是否禁用(如已提交) */
  disabled?: boolean
  className?: string
}

/**
 * 扫描图上传组件 —— 学生在纸上作答后,按页拍摄上传。
 * 调用 /api/upload 上传图片,返回 fileId + url。
 * 上传后将 fileId 列表通过 onChange 暴露给父组件。
 */
export function ScanUploader({
  images,
  onChange,
  onDeleteScan,
  submissionId,
  disabled = false,
  className,
}: ScanUploaderProps) {
  const [isUploading, startUpload] = useTransition()
  const [dragOver, setDragOver] = useState(false)
  const t = useTranslations("examHomework")

  const uploadFiles = (files: FileList | File[]) => {
    if (disabled) return
    const fileArray = Array.from(files).filter(
      (f) => f.type.startsWith("image/") || f.type === "application/pdf"
    )
    if (fileArray.length === 0) {
      toast.error(t("homework.take.selectImageFiles"))
      return
    }

    startUpload(async () => {
      const uploaded: ScanImage[] = []
      const basePage = images.length
      for (let i = 0; i < fileArray.length; i++) {
        const file = fileArray[i]
        if (!file) continue
        const formData = new FormData()
        formData.append("file", file)
        formData.append("targetType", "homework")
        formData.append("targetId", submissionId)
        try {
          const res = await fetch("/api/upload", { method: "POST", body: formData })
          const data = await res.json()
          if (data?.success && data?.url && data?.id) {
            uploaded.push({
              fileId: data.id,
              url: data.url,
              filename: data.originalName || data.filename || `page-${basePage + i + 1}`,
              page: basePage + i + 1,
            })
          } else {
            toast.error(`${t("homework.take.uploadFailed")}: ${data?.message || ""}`)
          }
        } catch (e) {
          console.error("[ScanUploader] upload failed", e)
          toast.error(`${t("homework.take.uploadFailed")}: ${file.name}`)
        }
      }
      if (uploaded.length > 0) {
        const next = [...images, ...uploaded]
        onChange(next)
        toast.success(t("homework.take.uploadSuccess", { count: uploaded.length }))
      }
    })
  }

  const handleFileInput = (e: ChangeEvent<HTMLInputElement>) => {
    if (e.target.files && e.target.files.length > 0) {
      uploadFiles(e.target.files)
      e.target.value = ""
    }
  }

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault()
    setDragOver(false)
    if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
      uploadFiles(e.dataTransfer.files)
    }
  }

  const handleRemove = (page: number) => {
    if (disabled) return
    const target = images.find((img) => img.page === page)
    const next = images.filter((img) => img.page !== page)
    // 重新编号
    const renumbered = next.map((img, idx) => ({ ...img, page: idx + 1 }))
    onChange(renumbered)
    // 服务端删除(不阻塞 UI)
    if (target && onDeleteScan) {
      void onDeleteScan(target.fileId).catch((e) => {
        console.error("[ScanUploader] delete failed", e)
      })
    }
  }

  const handleMove = (page: number, direction: "up" | "down") => {
    if (disabled) return
    const idx = images.findIndex((img) => img.page === page)
    if (idx === -1) return
    const targetIdx = direction === "up" ? idx - 1 : idx + 1
    if (targetIdx < 0 || targetIdx >= images.length) return
    const next = [...images]
    const [moved] = next.splice(idx, 1)
    next.splice(targetIdx, 0, moved)
    const renumbered = next.map((img, i) => ({ ...img, page: i + 1 }))
    onChange(renumbered)
  }

  return (
    <div className={cn("space-y-3", className)}>
      <div
        onDragOver={(e) => {
          e.preventDefault()
          setDragOver(true)
        }}
        onDragLeave={() => setDragOver(false)}
        onDrop={handleDrop}
        className={cn(
          "rounded-md border-2 border-dashed p-6 text-center transition-colors",
          dragOver ? "border-primary bg-primary/5" : "border-border",
          disabled && "opacity-50"
        )}
      >
        <Upload className="mx-auto mb-2 h-8 w-8 text-muted-foreground" />
        <p className="text-sm text-muted-foreground">
          {t("homework.take.dragDropHint")}
        </p>
        <p className="mt-1 text-xs text-muted-foreground">
          支持 JPG/PNG/WebP,每张不超过 10MB
        </p>
        <label className="mt-3 inline-block">
          <input
            type="file"
            accept="image/*"
            multiple
            onChange={handleFileInput}
            disabled={disabled || isUploading}
            className="hidden"
          />
          <Button
            type="button"
            variant="outline"
            size="sm"
            disabled={disabled || isUploading}
            className="gap-2"
            onClick={() => {
              // 触发隐藏的 file input
              const input = document.createElement("input")
              input.type = "file"
              input.accept = "image/*"
              input.multiple = true
              input.onchange = () => {
                if (input.files) uploadFiles(input.files)
              }
              input.click()
            }}
          >
            {isUploading ? (
              <Loader2 className="h-4 w-4 animate-spin" />
            ) : (
              <Upload className="h-4 w-4" />
            )}
            {isUploading ? t("homework.take.submitting") : t("homework.take.scanTitle")}
          </Button>
        </label>
      </div>

      {images.length > 0 && (
        <div className="grid grid-cols-2 gap-3 sm:grid-cols-3 md:grid-cols-4">
          {images.map((img) => (
            <div
              key={img.fileId}
              className="group relative overflow-hidden rounded-md border bg-muted"
            >
              <div className="relative aspect-[3/4] w-full">
                <Image
                  src={img.url}
                  alt={img.filename}
                  fill
                  sizes="(max-width: 768px) 50vw, (max-width: 1200px) 33vw, 25vw"
                  className="h-full w-full object-cover"
                />
              </div>
              <div className="absolute left-1 top-1 rounded bg-black/60 px-1.5 py-0.5 text-xs text-white">
                {t("homework.take.pageLabel", { page: img.page })}
              </div>
              {!disabled && (
                <div className="absolute inset-0 flex items-center justify-center gap-1 bg-black/40 opacity-0 transition-opacity group-hover:opacity-100">
                  <Button
                    type="button"
                    variant="secondary"
                    size="icon"
                    className="h-7 w-7"
                    onClick={() => handleMove(img.page, "up")}
                    disabled={img.page === 1}
                    title={t("homework.take.moveUp")}
                  >
                    ↑
                  </Button>
                  <Button
                    type="button"
                    variant="secondary"
                    size="icon"
                    className="h-7 w-7"
                    onClick={() => handleMove(img.page, "down")}
                    disabled={img.page === images.length}
                    title={t("homework.take.moveDown")}
                  >
                    ↓
                  </Button>
                  <Button
                    type="button"
                    variant="destructive"
                    size="icon"
                    className="h-7 w-7"
                    onClick={() => handleRemove(img.page)}
                    title={t("homework.take.deleteScan")}
                  >
                    <X className="h-3.5 w-3.5" />
                  </Button>
                </div>
              )}
            </div>
          ))}
        </div>
      )}

      {images.length === 0 && !disabled && (
        <div className="flex items-center justify-center py-6 text-sm text-muted-foreground">
          <ImageIcon className="mr-2 h-4 w-4" />
          {t("homework.take.noScans")}
        </div>
      )}
    </div>
  )
}
