"use client"

import { useState, useRef } from "react"
import { useTranslations } from "next-intl"
import { Download, Upload, FileJson } from "lucide-react"
import { useRouter } from "next/navigation"

import { Button } from "@/shared/components/ui/button"
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/shared/components/ui/dialog"
import { usePermission } from "@/shared/hooks/use-permission"
import { Permissions } from "@/shared/types/permissions"
import { exportQuestionsAction, importQuestionsAction } from "../actions"
import { toast } from "sonner"

/**
 * 题目导入/导出组件。
 *
 * 提供两个功能：
 * - 导出：将当前题库导出为 JSON 文件下载
 * - 导入：上传 JSON 文件批量导入题目
 *
 * 权限感知：
 * - 导出需要 QUESTION_READ
 * - 导入需要 QUESTION_CREATE
 */
export function ImportExportButtons(): React.ReactNode {
  const t = useTranslations("questions")
  const router = useRouter()
  const { hasPermission } = usePermission()
  const fileInputRef = useRef<HTMLInputElement>(null)
  const [showImportDialog, setShowImportDialog] = useState(false)
  const [pendingImportData, setPendingImportData] = useState<string | null>(null)
  const [isExporting, setIsExporting] = useState(false)
  const [isImporting, setIsImporting] = useState(false)

  const canRead = hasPermission(Permissions.QUESTION_READ)
  const canCreate = hasPermission(Permissions.QUESTION_CREATE)

  const handleExport = async (): Promise<void> => {
    setIsExporting(true)
    try {
      const fd = new FormData()
      fd.set("json", JSON.stringify({}))
      const res = await exportQuestionsAction(fd)
      if (res.success && res.data) {
        const json = JSON.stringify(res.data, null, 2)
        const blob = new Blob([json], { type: "application/json" })
        const url = URL.createObjectURL(blob)
        const a = document.createElement("a")
        a.href = url
        a.download = `questions-export-${new Date().toISOString().slice(0, 10)}.json`
        document.body.appendChild(a)
        a.click()
        document.body.removeChild(a)
        URL.revokeObjectURL(url)
        toast.success(t("importExport.exportSuccess", { count: res.data.length }))
      } else {
        toast.error(res.message || t("importExport.exportFailed"))
      }
    } catch (e) {
      console.error("Failed to export questions", e)
      toast.error(t("importExport.exportFailed"))
    } finally {
      setIsExporting(false)
    }
  }

  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>): void => {
    const file = e.target.files?.[0]
    if (!file) return

    const reader = new FileReader()
    reader.onload = (event) => {
      const text = event.target?.result
      if (typeof text === "string") {
        setPendingImportData(text)
        setShowImportDialog(true)
      } else {
        toast.error(t("importExport.invalidFile"))
      }
    }
    reader.onerror = () => {
      toast.error(t("importExport.readFailed"))
    }
    reader.readAsText(file)
    // 重置 input 以便重复选择同一文件
    e.target.value = ""
  }

  const handleImport = async (): Promise<void> => {
    if (!pendingImportData) return
    setIsImporting(true)
    try {
      const fd = new FormData()
      fd.set("json", pendingImportData)
      const res = await importQuestionsAction(undefined, fd)
      if (res.success) {
        const imported = res.data?.imported ?? 0
        toast.success(t("importExport.importSuccess", { count: imported }))
        setShowImportDialog(false)
        setPendingImportData(null)
        router.refresh()
      } else {
        toast.error(res.message || t("importExport.importFailed"))
      }
    } catch (e) {
      console.error("Failed to import questions", e)
      toast.error(t("importExport.importFailed"))
    } finally {
      setIsImporting(false)
    }
  }

  return (
    <>
      <div className="flex items-center gap-2">
        {canRead && (
          <Button
            variant="outline"
            size="sm"
            onClick={handleExport}
            disabled={isExporting}
          >
            <Download className="mr-2 h-4 w-4" />
            {isExporting ? t("importExport.exporting") : t("importExport.export")}
          </Button>
        )}
        {canCreate && (
          <>
            <Button
              variant="outline"
              size="sm"
              onClick={() => fileInputRef.current?.click()}
              disabled={isImporting}
            >
              <Upload className="mr-2 h-4 w-4" />
              {isImporting ? t("importExport.importing") : t("importExport.import")}
            </Button>
            <input
              ref={fileInputRef}
              type="file"
              accept="application/json,.json"
              onChange={handleFileSelect}
              className="hidden"
              aria-label={t("importExport.import")}
            />
          </>
        )}
      </div>

      <Dialog open={showImportDialog} onOpenChange={setShowImportDialog}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              <FileJson className="h-5 w-5" />
              {t("importExport.confirmTitle")}
            </DialogTitle>
            <DialogDescription>
              {t("importExport.confirmDesc")}
            </DialogDescription>
          </DialogHeader>
          <div className="max-h-[300px] overflow-y-auto rounded-md bg-muted p-3">
            <pre className="text-xs">
              {pendingImportData ? pendingImportData.slice(0, 2000) : ""}
              {pendingImportData && pendingImportData.length > 2000 ? "\n..." : ""}
            </pre>
          </div>
          <DialogFooter>
            <Button
              variant="outline"
              onClick={() => {
                setShowImportDialog(false)
                setPendingImportData(null)
              }}
            >
              {t("importExport.cancel")}
            </Button>
            <Button onClick={handleImport} disabled={isImporting}>
              {isImporting ? t("importExport.importing") : t("importExport.confirmImport")}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  )
}
