"use client"

import type React from "react"

import { useState, useEffect, useRef, useCallback } from "react"
import {
  Plus,
  Camera,
  Upload,
  Settings,
  Copy,
  Trash2,
  Edit2,
  QrCode,
  Key,
  Clock,
  Search,
  ChevronDown,
  ChevronUp,
  Eye,
  EyeOff,
  Download,
  MoreVertical,
  Sun,
  Moon,
  Monitor,
  Languages,
} from "lucide-react"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Switch } from "@/components/ui/switch"
import { Badge } from "@/components/ui/badge"
import { Progress } from "@/components/ui/progress"
import { Toaster } from "@/components/ui/toaster"
import { useToast } from "@/hooks/use-toast"
import { useTheme } from "@/components/theme-provider"
import { useLanguage } from "@/lib/i18n"

interface TOTPToken {
  id: string
  name: string
  issuer: string
  secret: string
  algorithm: "SHA1" | "SHA256" | "SHA512"
  digits: 6 | 8
  period: number
  createdAt: number
}

interface AppSettings {
  showCodes: boolean
  autoRefresh: boolean
  compactMode: boolean
  sortBy: "name" | "issuer" | "recent"
}

// TOTP Generation functions
function base32Decode(encoded: string): Uint8Array {
  const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
  const cleanedInput = encoded.toUpperCase().replace(/[^A-Z2-7]/g, "")

  let bits = ""
  for (const char of cleanedInput) {
    const val = alphabet.indexOf(char)
    if (val === -1) continue
    bits += val.toString(2).padStart(5, "0")
  }

  const bytes = new Uint8Array(Math.floor(bits.length / 8))
  for (let i = 0; i < bytes.length; i++) {
    bytes[i] = Number.parseInt(bits.slice(i * 8, (i + 1) * 8), 2)
  }

  return bytes
}

async function hmacSha(algorithm: string, key: Uint8Array, message: Uint8Array): Promise<Uint8Array> {
  const cryptoKey = await crypto.subtle.importKey("raw", key, { name: "HMAC", hash: algorithm }, false, ["sign"])
  const signature = await crypto.subtle.sign("HMAC", cryptoKey, message)
  return new Uint8Array(signature)
}

async function generateTOTP(
  secret: string,
  algorithm: "SHA1" | "SHA256" | "SHA512" = "SHA1",
  digits: 6 | 8 = 6,
  period = 30,
): Promise<string> {
  const key = base32Decode(secret)
  const time = Math.floor(Date.now() / 1000 / period)

  const timeBuffer = new ArrayBuffer(8)
  const timeView = new DataView(timeBuffer)
  timeView.setBigUint64(0, BigInt(time), false)

  const hashAlgorithm = algorithm === "SHA1" ? "SHA-1" : algorithm === "SHA256" ? "SHA-256" : "SHA-512"
  const hmac = await hmacSha(hashAlgorithm, key, new Uint8Array(timeBuffer))

  const offset = hmac[hmac.length - 1] & 0x0f
  const binary =
    ((hmac[offset] & 0x7f) << 24) |
    ((hmac[offset + 1] & 0xff) << 16) |
    ((hmac[offset + 2] & 0xff) << 8) |
    (hmac[offset + 3] & 0xff)

  const otp = binary % Math.pow(10, digits)
  return otp.toString().padStart(digits, "0")
}

function parseOTPAuthURI(uri: string): Partial<TOTPToken> | null {
  try {
    const url = new URL(uri)
    if (url.protocol !== "otpauth:") return null
    if (url.host !== "totp") return null

    const path = decodeURIComponent(url.pathname.slice(1))
    const params = url.searchParams

    let issuer = params.get("issuer") || ""
    let name = path

    if (path.includes(":")) {
      const [iss, n] = path.split(":")
      issuer = issuer || iss
      name = n
    }

    return {
      name,
      issuer,
      secret: params.get("secret") || "",
      algorithm: (params.get("algorithm")?.toUpperCase() as "SHA1" | "SHA256" | "SHA512") || "SHA1",
      digits: Number.parseInt(params.get("digits") || "6") as 6 | 8,
      period: Number.parseInt(params.get("period") || "30"),
    }
  } catch {
    return null
  }
}

export default function TwoFactorAuth() {
  const [tokens, setTokens] = useState<TOTPToken[]>([])
  const [codes, setCodes] = useState<Record<string, string>>({})
  const [timeLeft, setTimeLeft] = useState(30)
  const [searchQuery, setSearchQuery] = useState("")
  const [isAddDialogOpen, setIsAddDialogOpen] = useState(false)
  const [isCameraOpen, setIsCameraOpen] = useState(false)
  const [isSettingsOpen, setIsSettingsOpen] = useState(false)
  const [editingToken, setEditingToken] = useState<TOTPToken | null>(null)
  const [showAdvanced, setShowAdvanced] = useState(false)
  const videoRef = useRef<HTMLVideoElement>(null)
  const canvasRef = useRef<HTMLCanvasElement>(null)
  const fileInputRef = useRef<HTMLInputElement>(null)
  const streamRef = useRef<MediaStream | null>(null)
  const { toast } = useToast()
  const { theme, setTheme } = useTheme()
  const { language, setLanguage, t } = useLanguage()

  const [newToken, setNewToken] = useState({
    name: "",
    issuer: "",
    secret: "",
    algorithm: "SHA1" as "SHA1" | "SHA256" | "SHA512",
    digits: 6 as 6 | 8,
    period: 30,
  })

  const [settings, setSettings] = useState<AppSettings>({
    showCodes: true,
    autoRefresh: true,
    compactMode: false,
    sortBy: "name",
  })

  // Load tokens and settings from localStorage
  useEffect(() => {
    const savedTokens = localStorage.getItem("2fa-tokens")
    const savedSettings = localStorage.getItem("2fa-settings")
    if (savedTokens) {
      setTokens(JSON.parse(savedTokens))
    }
    if (savedSettings) {
      setSettings(JSON.parse(savedSettings))
    }
  }, [])

  // Save tokens to localStorage
  useEffect(() => {
    localStorage.setItem("2fa-tokens", JSON.stringify(tokens))
  }, [tokens])

  // Save settings to localStorage
  useEffect(() => {
    localStorage.setItem("2fa-settings", JSON.stringify(settings))
  }, [settings])

  // Generate codes for all tokens
  const generateAllCodes = useCallback(async () => {
    const newCodes: Record<string, string> = {}
    for (const token of tokens) {
      try {
        newCodes[token.id] = await generateTOTP(token.secret, token.algorithm, token.digits, token.period)
      } catch {
        newCodes[token.id] = "Error"
      }
    }
    setCodes(newCodes)
  }, [tokens])

  // Timer for TOTP refresh
  useEffect(() => {
    generateAllCodes()

    const interval = setInterval(() => {
      const now = Math.floor(Date.now() / 1000)
      const remaining = 30 - (now % 30)
      setTimeLeft(remaining)

      if (remaining === 30) {
        generateAllCodes()
      }
    }, 1000)

    return () => clearInterval(interval)
  }, [generateAllCodes])

  const addToken = () => {
    if (!newToken.name || !newToken.secret) {
      toast({
        title: t.error,
        description: t.fillRequired,
        variant: "destructive",
      })
      return
    }

    const cleanSecret = newToken.secret.replace(/\s/g, "").toUpperCase()

    const token: TOTPToken = {
      id: crypto.randomUUID(),
      name: newToken.name,
      issuer: newToken.issuer,
      secret: cleanSecret,
      algorithm: newToken.algorithm,
      digits: newToken.digits,
      period: newToken.period,
      createdAt: Date.now(),
    }

    setTokens([...tokens, token])
    setNewToken({
      name: "",
      issuer: "",
      secret: "",
      algorithm: "SHA1",
      digits: 6,
      period: 30,
    })
    setShowAdvanced(false)
    setIsAddDialogOpen(false)

    toast({
      title: t.addSuccess,
      description: `${t.added} ${token.name}`,
    })
  }

  const deleteToken = (id: string) => {
    const token = tokens.find((t) => t.id === id)
    setTokens(tokens.filter((t) => t.id !== id))
    toast({
      title: t.deleted,
      description: `${t.deleted} ${token?.name}`,
    })
  }

  const updateToken = () => {
    if (!editingToken) return
    setTokens(tokens.map((tk) => (tk.id === editingToken.id ? editingToken : tk)))
    setEditingToken(null)
    toast({
      title: t.updated,
      description: t.tokenUpdated,
    })
  }

  const copyCode = (code: string, name: string) => {
    navigator.clipboard.writeText(code)
    toast({
      title: t.copied,
      description: `${name} ${t.codeCopied}`,
    })
  }

  // QR Code scanning from camera
  const startCamera = async () => {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({
        video: { facingMode: "environment" },
      })
      streamRef.current = stream
      if (videoRef.current) {
        videoRef.current.srcObject = stream
        videoRef.current.play()
      }
      setIsCameraOpen(true)
      scanQRCode()
    } catch (error) {
      toast({
        title: t.cameraFailed,
        description: t.cameraPermission,
        variant: "destructive",
      })
    }
  }

  const stopCamera = () => {
    if (streamRef.current) {
      streamRef.current.getTracks().forEach((track) => track.stop())
      streamRef.current = null
    }
    setIsCameraOpen(false)
  }

  const scanQRCode = async () => {
    if (!videoRef.current || !canvasRef.current) return

    const video = videoRef.current
    const canvas = canvasRef.current
    const ctx = canvas.getContext("2d")

    if (!ctx) return

    const scan = async () => {
      if (!isCameraOpen && !streamRef.current) return

      if (video.readyState === video.HAVE_ENOUGH_DATA) {
        canvas.width = video.videoWidth
        canvas.height = video.videoHeight
        ctx.drawImage(video, 0, 0, canvas.width, canvas.height)

        const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)

        // Simple QR detection - in production, use a library like jsQR
        // For now, we'll rely on image upload for QR codes
      }

      if (streamRef.current) {
        requestAnimationFrame(scan)
      }
    }

    scan()
  }

  // Handle image upload for QR scanning
  const handleImageUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0]
    if (!file) return

    const img = new Image()
    img.crossOrigin = "anonymous"
    img.onload = async () => {
      const canvas = document.createElement("canvas")
      canvas.width = img.width
      canvas.height = img.height
      const ctx = canvas.getContext("2d")
      if (!ctx) return

      ctx.drawImage(img, 0, 0)

      toast({
        title: t.imageUploaded,
        description: t.imageUploadedHint,
      })
    }
    img.src = URL.createObjectURL(file)

    // Reset file input
    if (fileInputRef.current) {
      fileInputRef.current.value = ""
    }
  }

  // Handle URI paste
  const handleURIPaste = (uri: string) => {
    const parsed = parseOTPAuthURI(uri)
    if (parsed) {
      setNewToken({
        name: parsed.name || "",
        issuer: parsed.issuer || "",
        secret: parsed.secret || "",
        algorithm: parsed.algorithm || "SHA1",
        digits: parsed.digits || 6,
        period: parsed.period || 30,
      })
      toast({
        title: t.parseSuccess,
        description: t.extractedInfo,
      })
    } else {
      toast({
        title: t.parseFailed,
        description: t.invalidUri,
        variant: "destructive",
      })
    }
  }

  // Export tokens
  const exportTokens = () => {
    const data = JSON.stringify(tokens, null, 2)
    const blob = new Blob([data], { type: "application/json" })
    const url = URL.createObjectURL(blob)
    const a = document.createElement("a")
    a.href = url
    a.download = "2fa-tokens-backup.json"
    a.click()
    URL.revokeObjectURL(url)
    toast({
      title: t.exportSuccess,
      description: t.exportedJson,
    })
  }

  // Import tokens
  const importTokens = (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0]
    if (!file) return

    const reader = new FileReader()
    reader.onload = (e) => {
      try {
        const imported = JSON.parse(e.target?.result as string)
        if (Array.isArray(imported)) {
          setTokens([...tokens, ...imported])
          toast({
            title: t.importSuccess,
            description: `${t.added} ${imported.length} ${t.importedTokens}`,
          })
        }
      } catch {
        toast({
          title: t.importFailed,
          description: t.invalidFormat,
          variant: "destructive",
        })
      }
    }
    reader.readAsText(file)
  }

  // Filter and sort tokens
  const filteredTokens = tokens
    .filter(
      (t) =>
        t.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
        t.issuer.toLowerCase().includes(searchQuery.toLowerCase()),
    )
    .sort((a, b) => {
      switch (settings.sortBy) {
        case "name":
          return a.name.localeCompare(b.name)
        case "issuer":
          return a.issuer.localeCompare(b.issuer)
        case "recent":
          return b.createdAt - a.createdAt
        default:
          return 0
      }
    })

  return (
    <div className="min-h-screen bg-background flex flex-col">
      {/* Header */}
      <header className="border-b bg-card/50 backdrop-blur-sm sticky top-0 z-50">
        <div className="container mx-auto px-4 py-4">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-3">
              <div className="h-10 w-10 rounded-xl bg-primary/10 flex items-center justify-center">
                <Key className="h-5 w-5 text-primary" />
              </div>
              <div>
                <h1 className="text-xl font-bold">{t.appName}</h1>
                <p className="text-xs text-muted-foreground">{t.appDescription}</p>
              </div>
            </div>
            <div className="flex items-center gap-2">
              <DropdownMenu>
                <DropdownMenuTrigger asChild>
                  <Button variant="ghost" size="icon">
                    <Sun className="h-5 w-5 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
                    <Moon className="absolute h-5 w-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
                    <span className="sr-only">Toggle theme</span>
                  </Button>
                </DropdownMenuTrigger>
                <DropdownMenuContent align="end">
                  <DropdownMenuItem onClick={() => setTheme("light")}>
                    <Sun className="h-4 w-4 mr-2" />
                    {t.themeLight}
                  </DropdownMenuItem>
                  <DropdownMenuItem onClick={() => setTheme("dark")}>
                    <Moon className="h-4 w-4 mr-2" />
                    {t.themeDark}
                  </DropdownMenuItem>
                  <DropdownMenuItem onClick={() => setTheme("system")}>
                    <Monitor className="h-4 w-4 mr-2" />
                    {t.themeSystem}
                  </DropdownMenuItem>
                </DropdownMenuContent>
              </DropdownMenu>

              <DropdownMenu>
                <DropdownMenuTrigger asChild>
                  <Button variant="ghost" size="icon">
                    <Languages className="h-5 w-5" />
                    <span className="sr-only">Toggle language</span>
                  </Button>
                </DropdownMenuTrigger>
                <DropdownMenuContent align="end">
                  <DropdownMenuItem onClick={() => setLanguage("zh")}>中文 {language === "zh" && "✓"}</DropdownMenuItem>
                  <DropdownMenuItem onClick={() => setLanguage("en")}>
                    English {language === "en" && "✓"}
                  </DropdownMenuItem>
                </DropdownMenuContent>
              </DropdownMenu>

              <Dialog open={isSettingsOpen} onOpenChange={setIsSettingsOpen}>
                <DialogTrigger asChild>
                  <Button variant="ghost" size="icon">
                    <Settings className="h-5 w-5" />
                  </Button>
                </DialogTrigger>
                <DialogContent>
                  <DialogHeader>
                    <DialogTitle>{t.settings}</DialogTitle>
                    <DialogDescription>{t.settingsDesc}</DialogDescription>
                  </DialogHeader>
                  <div className="space-y-6 py-4">
                    <div className="flex items-center justify-between">
                      <div>
                        <Label>{t.showCodes}</Label>
                        <p className="text-sm text-muted-foreground">{t.showCodesDesc}</p>
                      </div>
                      <Switch
                        checked={settings.showCodes}
                        onCheckedChange={(checked) => setSettings({ ...settings, showCodes: checked })}
                      />
                    </div>
                    <div className="flex items-center justify-between">
                      <div>
                        <Label>{t.compactMode}</Label>
                        <p className="text-sm text-muted-foreground">{t.compactModeDesc}</p>
                      </div>
                      <Switch
                        checked={settings.compactMode}
                        onCheckedChange={(checked) => setSettings({ ...settings, compactMode: checked })}
                      />
                    </div>
                    <div className="space-y-2">
                      <Label>{t.sortBy}</Label>
                      <Select
                        value={settings.sortBy}
                        onValueChange={(value: "name" | "issuer" | "recent") =>
                          setSettings({ ...settings, sortBy: value })
                        }
                      >
                        <SelectTrigger>
                          <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                          <SelectItem value="name">{t.sortByName}</SelectItem>
                          <SelectItem value="issuer">{t.sortByIssuer}</SelectItem>
                          <SelectItem value="recent">{t.sortByRecent}</SelectItem>
                        </SelectContent>
                      </Select>
                    </div>
                    <div className="border-t pt-4 space-y-3">
                      <Label>{t.dataManagement}</Label>
                      <div className="flex gap-2">
                        <Button variant="outline" size="sm" onClick={exportTokens}>
                          <Download className="h-4 w-4 mr-2" />
                          {t.exportBackup}
                        </Button>
                        <Button variant="outline" size="sm" asChild>
                          <label>
                            <Upload className="h-4 w-4 mr-2" />
                            {t.importBackup}
                            <input type="file" accept=".json" className="hidden" onChange={importTokens} />
                          </label>
                        </Button>
                      </div>
                    </div>
                  </div>
                </DialogContent>
              </Dialog>
            </div>
          </div>
        </div>
      </header>

      {/* Main Content */}
      <main className="flex-1 container mx-auto px-4 py-6">
        {/* Timer Progress */}
        <div className="mb-6">
          <div className="flex items-center justify-between mb-2">
            <div className="flex items-center gap-2 text-sm text-muted-foreground">
              <Clock className="h-4 w-4" />
              <span>{t.nextRefresh}</span>
            </div>
            <span className="text-sm font-medium">{timeLeft}s</span>
          </div>
          <Progress value={(timeLeft / 30) * 100} className="h-1" />
        </div>

        {/* Search and Actions */}
        <div className="flex flex-col sm:flex-row gap-3 mb-6">
          <div className="relative flex-1">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
            <Input
              placeholder={t.searchPlaceholder}
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
              className="pl-10"
            />
          </div>
          <div className="flex gap-2">
            <Dialog open={isAddDialogOpen} onOpenChange={setIsAddDialogOpen}>
              <DialogTrigger asChild>
                <Button>
                  <Plus className="h-4 w-4 mr-2" />
                  {t.addToken}
                </Button>
              </DialogTrigger>
              <DialogContent className="max-w-md">
                <DialogHeader>
                  <DialogTitle>{t.addNewToken}</DialogTitle>
                  <DialogDescription>{t.addNewTokenDesc}</DialogDescription>
                </DialogHeader>
                <Tabs defaultValue="manual" className="mt-4">
                  <TabsList className="grid w-full grid-cols-3">
                    <TabsTrigger value="manual">
                      <Key className="h-4 w-4 mr-2" />
                      {t.manualInput}
                    </TabsTrigger>
                    <TabsTrigger value="camera">
                      <Camera className="h-4 w-4 mr-2" />
                      {t.scanQr}
                    </TabsTrigger>
                    <TabsTrigger value="upload">
                      <Upload className="h-4 w-4 mr-2" />
                      {t.uploadImage}
                    </TabsTrigger>
                  </TabsList>

                  <TabsContent value="manual" className="space-y-4 mt-4">
                    <div className="space-y-2">
                      <Label>{t.otpauthUri}</Label>
                      <Input placeholder="otpauth://totp/..." onChange={(e) => handleURIPaste(e.target.value)} />
                      <p className="text-xs text-muted-foreground">{t.otpauthUriHint}</p>
                    </div>
                    <div className="space-y-2">
                      <Label>{t.name} *</Label>
                      <Input
                        placeholder={t.namePlaceholder}
                        value={newToken.name}
                        onChange={(e) => setNewToken({ ...newToken, name: e.target.value })}
                      />
                    </div>
                    <div className="space-y-2">
                      <Label>{t.issuer}</Label>
                      <Input
                        placeholder={t.issuerPlaceholder}
                        value={newToken.issuer}
                        onChange={(e) => setNewToken({ ...newToken, issuer: e.target.value })}
                      />
                    </div>
                    <div className="space-y-2">
                      <Label>{t.secretKey} *</Label>
                      <Input
                        placeholder="JBSWY3DPEHPK3PXP"
                        value={newToken.secret}
                        onChange={(e) => setNewToken({ ...newToken, secret: e.target.value })}
                        className="font-mono"
                      />
                    </div>

                    {/* Advanced Settings */}
                    <div className="border-t pt-4">
                      <button
                        type="button"
                        className="flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors"
                        onClick={() => setShowAdvanced(!showAdvanced)}
                      >
                        {showAdvanced ? <ChevronUp className="h-4 w-4" /> : <ChevronDown className="h-4 w-4" />}
                        {t.advancedSettings}
                      </button>

                      {showAdvanced && (
                        <div className="mt-4 space-y-4">
                          <div className="space-y-2">
                            <Label>{t.algorithm}</Label>
                            <Select
                              value={newToken.algorithm}
                              onValueChange={(value: "SHA1" | "SHA256" | "SHA512") =>
                                setNewToken({ ...newToken, algorithm: value })
                              }
                            >
                              <SelectTrigger>
                                <SelectValue />
                              </SelectTrigger>
                              <SelectContent>
                                <SelectItem value="SHA1">{t.algorithmDefault}</SelectItem>
                                <SelectItem value="SHA256">SHA-256</SelectItem>
                                <SelectItem value="SHA512">SHA-512</SelectItem>
                              </SelectContent>
                            </Select>
                          </div>
                          <div className="space-y-2">
                            <Label>{t.digits}</Label>
                            <Select
                              value={newToken.digits.toString()}
                              onValueChange={(value) =>
                                setNewToken({ ...newToken, digits: Number.parseInt(value) as 6 | 8 })
                              }
                            >
                              <SelectTrigger>
                                <SelectValue />
                              </SelectTrigger>
                              <SelectContent>
                                <SelectItem value="6">{t.digitsDefault}</SelectItem>
                                <SelectItem value="8">{t.digits8}</SelectItem>
                              </SelectContent>
                            </Select>
                          </div>
                          <div className="space-y-2">
                            <Label>{t.period}</Label>
                            <Input
                              type="number"
                              value={newToken.period}
                              onChange={(e) =>
                                setNewToken({ ...newToken, period: Number.parseInt(e.target.value) || 30 })
                              }
                            />
                          </div>
                        </div>
                      )}
                    </div>
                  </TabsContent>

                  <TabsContent value="camera" className="mt-4">
                    <div className="space-y-4">
                      {!isCameraOpen ? (
                        <div className="aspect-video bg-muted rounded-lg flex flex-col items-center justify-center gap-4">
                          <Camera className="h-12 w-12 text-muted-foreground" />
                          <Button onClick={startCamera}>
                            <Camera className="h-4 w-4 mr-2" />
                            {t.startCamera}
                          </Button>
                        </div>
                      ) : (
                        <div className="relative aspect-video bg-black rounded-lg overflow-hidden">
                          <video ref={videoRef} className="w-full h-full object-cover" playsInline />
                          <canvas ref={canvasRef} className="hidden" />
                          <div className="absolute inset-0 flex items-center justify-center pointer-events-none">
                            <div className="w-48 h-48 border-2 border-white/50 rounded-lg" />
                          </div>
                          <Button
                            variant="secondary"
                            size="sm"
                            className="absolute bottom-4 right-4"
                            onClick={stopCamera}
                          >
                            {t.closeCamera}
                          </Button>
                        </div>
                      )}
                      <p className="text-sm text-muted-foreground text-center">{t.scanHint}</p>
                    </div>
                  </TabsContent>

                  <TabsContent value="upload" className="mt-4">
                    <div className="space-y-4">
                      <div
                        className="aspect-video border-2 border-dashed rounded-lg flex flex-col items-center justify-center gap-4 cursor-pointer hover:border-primary transition-colors"
                        onClick={() => fileInputRef.current?.click()}
                      >
                        <QrCode className="h-12 w-12 text-muted-foreground" />
                        <div className="text-center">
                          <p className="font-medium">{t.uploadHint}</p>
                          <p className="text-sm text-muted-foreground">{t.uploadFormats}</p>
                        </div>
                      </div>
                      <input
                        ref={fileInputRef}
                        type="file"
                        accept="image/*"
                        className="hidden"
                        onChange={handleImageUpload}
                      />
                    </div>
                  </TabsContent>
                </Tabs>
                <DialogFooter className="mt-6">
                  <Button variant="outline" onClick={() => setIsAddDialogOpen(false)}>
                    {t.cancel}
                  </Button>
                  <Button onClick={addToken}>{t.add}</Button>
                </DialogFooter>
              </DialogContent>
            </Dialog>
          </div>
        </div>

        {/* Tokens List */}
        {filteredTokens.length === 0 ? (
          <Card className="border-dashed">
            <CardContent className="py-12 text-center">
              <Key className="h-12 w-12 mx-auto text-muted-foreground mb-4" />
              <h3 className="text-lg font-medium mb-2">{t.noTokens}</h3>
              <p className="text-muted-foreground mb-4">{t.noTokensHint}</p>
              <Button onClick={() => setIsAddDialogOpen(true)}>
                <Plus className="h-4 w-4 mr-2" />
                {t.addToken}
              </Button>
            </CardContent>
          </Card>
        ) : (
          <div
            className={`grid gap-4 ${settings.compactMode ? "grid-cols-1" : "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"}`}
          >
            {filteredTokens.map((token) => (
              <TokenCard
                key={token.id}
                token={token}
                code={codes[token.id] || "------"}
                timeLeft={timeLeft}
                showCode={settings.showCodes}
                compact={settings.compactMode}
                onCopy={() => copyCode(codes[token.id], token.name)}
                onEdit={() => setEditingToken(token)}
                onDelete={() => deleteToken(token.id)}
                t={t}
              />
            ))}
          </div>
        )}
      </main>

      {/* Edit Dialog */}
      <Dialog open={!!editingToken} onOpenChange={(open) => !open && setEditingToken(null)}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>{t.editToken}</DialogTitle>
          </DialogHeader>
          {editingToken && (
            <div className="space-y-4 py-4">
              <div className="space-y-2">
                <Label>{t.name}</Label>
                <Input
                  value={editingToken.name}
                  onChange={(e) => setEditingToken({ ...editingToken, name: e.target.value })}
                />
              </div>
              <div className="space-y-2">
                <Label>{t.issuer}</Label>
                <Input
                  value={editingToken.issuer}
                  onChange={(e) => setEditingToken({ ...editingToken, issuer: e.target.value })}
                />
              </div>
            </div>
          )}
          <DialogFooter>
            <Button variant="outline" onClick={() => setEditingToken(null)}>
              {t.cancel}
            </Button>
            <Button onClick={updateToken}>{t.save}</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Footer */}
      <footer className="border-t py-6 mt-auto">
        <div className="mx-auto flex max-w-4xl flex-col items-center gap-2 text-center md:flex-row md:justify-between md:gap-4 px-4">
          <p className="text-xs tracking-wider text-muted-foreground">© 2025 Simon. All rights reserved.</p>
          <div className="flex items-center gap-4 text-xs tracking-wider text-muted-foreground/60">
            <a
              href="https://beian.miit.gov.cn/"
              target="_blank"
              rel="noopener noreferrer"
              className="transition-colors hover:text-muted-foreground"
            >
              滇ICP备2025074424号
            </a>
            <span className="text-muted-foreground/30">|</span>
            <a
              href="https://beian.mps.gov.cn"
              target="_blank"
              rel="noopener noreferrer"
              className="flex items-center gap-1.5 transition-colors hover:text-muted-foreground"
            >
              <img
                alt="公安备案"
                loading="lazy"
                width="14"
                height="14"
                decoding="async"
                className="opacity-60"
                src="/images/beian.png"
              />
              滇公网安备53250402000233号
            </a>
          </div>
        </div>
      </footer>

      <Toaster />
    </div>
  )
}

interface TokenCardProps {
  token: TOTPToken
  code: string
  timeLeft: number
  showCode: boolean
  compact: boolean
  onCopy: () => void
  onEdit: () => void
  onDelete: () => void
  t: Record<string, string>
}

function TokenCard({ token, code, timeLeft, showCode, compact, onCopy, onEdit, onDelete, t }: TokenCardProps) {
  const [visible, setVisible] = useState(showCode)

  useEffect(() => {
    setVisible(showCode)
  }, [showCode])

  const formattedCode =
    code.length === 6
      ? `${code.slice(0, 3)} ${code.slice(3)}`
      : code.length === 8
        ? `${code.slice(0, 4)} ${code.slice(4)}`
        : code

  if (compact) {
    return (
      <Card className="hover:shadow-md transition-shadow">
        <CardContent className="py-3 px-4">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-3">
              <div className="h-8 w-8 rounded-lg bg-primary/10 flex items-center justify-center shrink-0">
                <span className="text-sm font-bold text-primary">{token.name.charAt(0).toUpperCase()}</span>
              </div>
              <div>
                <p className="font-medium text-sm">{token.name}</p>
                {token.issuer && <p className="text-xs text-muted-foreground">{token.issuer}</p>}
              </div>
            </div>
            <div className="flex items-center gap-2">
              <button onClick={() => setVisible(!visible)} className="p-1 hover:bg-muted rounded">
                {visible ? <Eye className="h-4 w-4" /> : <EyeOff className="h-4 w-4" />}
              </button>
              <span
                className={`font-mono text-lg font-bold cursor-pointer ${timeLeft <= 5 ? "text-destructive" : ""}`}
                onClick={onCopy}
              >
                {visible ? formattedCode : "••• •••"}
              </span>
              <DropdownMenu>
                <DropdownMenuTrigger asChild>
                  <Button variant="ghost" size="icon" className="h-8 w-8">
                    <MoreVertical className="h-4 w-4" />
                  </Button>
                </DropdownMenuTrigger>
                <DropdownMenuContent align="end">
                  <DropdownMenuItem onClick={onCopy}>
                    <Copy className="h-4 w-4 mr-2" />
                    {t.copy}
                  </DropdownMenuItem>
                  <DropdownMenuItem onClick={onEdit}>
                    <Edit2 className="h-4 w-4 mr-2" />
                    {t.edit}
                  </DropdownMenuItem>
                  <DropdownMenuItem onClick={onDelete} className="text-destructive">
                    <Trash2 className="h-4 w-4 mr-2" />
                    {t.delete}
                  </DropdownMenuItem>
                </DropdownMenuContent>
              </DropdownMenu>
            </div>
          </div>
        </CardContent>
      </Card>
    )
  }

  return (
    <Card className="hover:shadow-md transition-shadow">
      <CardHeader className="pb-2">
        <div className="flex items-start justify-between">
          <div className="flex items-center gap-3">
            <div className="h-10 w-10 rounded-xl bg-primary/10 flex items-center justify-center">
              <span className="text-lg font-bold text-primary">{token.name.charAt(0).toUpperCase()}</span>
            </div>
            <div>
              <CardTitle className="text-base">{token.name}</CardTitle>
              {token.issuer && <CardDescription>{token.issuer}</CardDescription>}
            </div>
          </div>
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <Button variant="ghost" size="icon" className="h-8 w-8">
                <MoreVertical className="h-4 w-4" />
              </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
              <DropdownMenuItem onClick={onCopy}>
                <Copy className="h-4 w-4 mr-2" />
                {t.copyCode}
              </DropdownMenuItem>
              <DropdownMenuItem onClick={onEdit}>
                <Edit2 className="h-4 w-4 mr-2" />
                {t.edit}
              </DropdownMenuItem>
              <DropdownMenuItem onClick={onDelete} className="text-destructive">
                <Trash2 className="h-4 w-4 mr-2" />
                {t.delete}
              </DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
        </div>
      </CardHeader>
      <CardContent>
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-2">
            <button onClick={() => setVisible(!visible)} className="p-1 hover:bg-muted rounded transition-colors">
              {visible ? <Eye className="h-4 w-4" /> : <EyeOff className="h-4 w-4" />}
            </button>
            <span
              className={`font-mono text-2xl font-bold tracking-wider cursor-pointer ${
                timeLeft <= 5 ? "text-destructive animate-pulse" : ""
              }`}
              onClick={onCopy}
            >
              {visible ? formattedCode : "••• •••"}
            </span>
          </div>
          <Button variant="ghost" size="icon" onClick={onCopy}>
            <Copy className="h-4 w-4" />
          </Button>
        </div>
        <div className="mt-3 flex items-center gap-2">
          <Progress value={(timeLeft / token.period) * 100} className="h-1 flex-1" />
          <span className="text-xs text-muted-foreground w-6">{timeLeft}s</span>
        </div>
        {(token.algorithm !== "SHA1" || token.digits !== 6 || token.period !== 30) && (
          <div className="mt-2 flex gap-1 flex-wrap">
            {token.algorithm !== "SHA1" && (
              <Badge variant="secondary" className="text-xs">
                {token.algorithm}
              </Badge>
            )}
            {token.digits !== 6 && (
              <Badge variant="secondary" className="text-xs">
                {token.digits}
                {t.digits8?.includes("digits") ? " digits" : "位"}
              </Badge>
            )}
            {token.period !== 30 && (
              <Badge variant="secondary" className="text-xs">
                {token.period}s
              </Badge>
            )}
          </div>
        )}
      </CardContent>
    </Card>
  )
}
