import { useCallback, useEffect, useState, type ComponentType, type SVGProps } from "react"
import { Package, Leaf, Apple, Zap, RefreshCw, CheckCircle2, Circle, Coins } from "lucide-react"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { ScrollArea } from "@/components/ui/scroll-area"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { cn } from "@/lib/utils"

interface Item {
  id: number
  uid: number
  name: string
  count: number
  type: 'seed' | 'produce' | 'other'
}

interface WarehouseData {
  seeds: Item[]
  produce: Item[]
  others: Item[]
}
interface Gain {
  id: number
  name: string
  count: number
}

export function WarehousePanel({ email, refreshKey, onRefresh }: { email: string, refreshKey?: number, onRefresh?: () => void }) {
  const [data, setData] = useState<WarehouseData>({ seeds: [], produce: [], others: [] })
  const [isLoading, setIsLoading] = useState(false)
  const [isSelling, setIsSelling] = useState(false)
  const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set()) // Format: "id-uid"
  const [isSelectionMode, setIsSelectionMode] = useState(false)
  const [activeTab, setActiveTab] = useState("seeds")
  const [message, setMessage] = useState("")
  const [seedImageMap, setSeedImageMap] = useState<Record<number, string>>({})
  const [nameImageMap, setNameImageMap] = useState<Record<string, string>>({})
  const [verifiedItemMap, setVerifiedItemMap] = useState<Record<number, string>>({})
  const [useDialogOpen, setUseDialogOpen] = useState(false)
  const [useTargets, setUseTargets] = useState<Item[]>([])
  const [useQuantities, setUseQuantities] = useState<Record<string, number>>({})
  const [gainDialogOpen, setGainDialogOpen] = useState(false)
  const [gains, setGains] = useState<Gain[]>([])

  const fetchWarehouse = useCallback(async (silent = false) => {
    if (!email) return
    if (!silent) setIsLoading(true)
    try {
      const res = await fetch(`/api/warehouse?email=${email}`)
      const json = await res.json()
      if (json.seeds) {
        setData(json)
      }
    } catch (e) {
      console.error(e)
    } finally {
      if (!silent) setIsLoading(false)
    }
  }, [email])

  useEffect(() => {
    fetchWarehouse()
    const interval = setInterval(() => fetchWarehouse(true), 5000)
    return () => clearInterval(interval)
  }, [fetchWarehouse, refreshKey])

  useEffect(() => {
    let cancelled = false
    fetch('/shop_plants_organized/mapping.csv')
      .then(res => res.text())
      .then(text => {
        if (cancelled) return
        const lines = text.split(/\r?\n/).filter(Boolean)
        if (lines.length <= 1) {
          setSeedImageMap({})
          setNameImageMap({})
          return
        }
        const map: Record<number, string> = {}
        const nameMap: Record<string, string> = {}
        for (let i = 1; i < lines.length; i += 1) {
          const line = lines[i].trim()
          if (!line) continue
          const parts = line.split(',')
          if (parts.length < 5) continue
          const seedId = Number(parts[0])
          const fileName = parts[4]
          if (!Number.isNaN(seedId) && fileName) {
            map[seedId] = fileName
          }
          if (fileName) {
            const name = fileName.split('_from_')[0]
            if (name) nameMap[name] = fileName
          }
        }
        setSeedImageMap(map)
        setNameImageMap(nameMap)
      })
      .catch(() => {
        if (!cancelled) {
          setSeedImageMap({})
          setNameImageMap({})
        }
      })
    return () => {
      cancelled = true
    }
  }, [])

  useEffect(() => {
    let cancelled = false
    fetch('/verified_items/mapping.json')
      .then(res => res.json())
      .then((list: Array<{ id: string, path: string }>) => {
        if (cancelled || !Array.isArray(list)) return
        const map: Record<number, string> = {}
        for (const item of list) {
          const id = Number(item.id)
          if (!Number.isNaN(id) && item.path) {
            map[id] = item.path
          }
        }
        setVerifiedItemMap(map)
      })
      .catch(() => {
        if (!cancelled) setVerifiedItemMap({})
      })
    return () => {
      cancelled = true
    }
  }, [])

  const toggleSelection = (item: Item) => {
    const key = `${item.id}-${item.uid}`
    const newSet = new Set(selectedItems)
    if (newSet.has(key)) {
      newSet.delete(key)
    } else {
      newSet.add(key)
    }
    setSelectedItems(newSet)
  }

  const collectSelectedItems = useCallback(() => {
    if (selectedItems.size === 0) return []
    const allItems = [...data.seeds, ...data.produce, ...data.others]
    const result: Item[] = []
    selectedItems.forEach(key => {
      const [idStr, uidStr] = key.split('-')
      const id = Number(idStr)
      const uid = Number(uidStr)
      const item = allItems.find(i => i.id === id && i.uid === uid)
      if (item) result.push(item)
    })
    return result
  }, [data.others, data.produce, data.seeds, selectedItems])

  const closeUseDialog = useCallback(() => {
    setUseDialogOpen(false)
    setUseTargets([])
    setUseQuantities({})
  }, [])

  const openUseDialogForItems = useCallback((list: Item[]) => {
    if (list.length === 0) return
    const nextQuantities: Record<string, number> = {}
    list.forEach(item => {
      nextQuantities[`${item.id}-${item.uid}`] = 1
    })
    setUseTargets(list)
    setUseQuantities(nextQuantities)
    setUseDialogOpen(true)
  }, [])

  const openUseDialog = useCallback(() => {
    const list = collectSelectedItems()
    openUseDialogForItems(list)
  }, [collectSelectedItems, openUseDialogForItems])

  const updateUseQuantity = useCallback((key: string, value: string, maxCount: number) => {
    const parsed = Number(value)
    const next = Number.isNaN(parsed) ? 1 : Math.floor(parsed)
    const clamped = Math.max(1, Math.min(maxCount, next))
    setUseQuantities(prev => {
      if (prev[key] === clamped) return prev
      return { ...prev, [key]: clamped }
    })
  }, [])

  const handleSell = async () => {
    if (selectedItems.size === 0) return

    if (activeTab === 'others') {
      openUseDialog()
      return
    }

    setIsSelling(true)
    setMessage("")
    
    const selectedList = collectSelectedItems()
    if (selectedList.length === 0) {
      setIsSelling(false)
      return
    }
    const itemsToSell: { id: number, count: number, uid: number }[] = []
    selectedList.forEach(item => {
      itemsToSell.push({ id: item.id, count: item.count, uid: item.uid })
    })

    try {
      const res = await fetch('/api/warehouse/sell', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email, items: itemsToSell })
      })
      const json = await res.json()
      
      if (json.success) {
        setMessage(`出售成功！获得 ${json.gold} 金币`)
        setSelectedItems(new Set())
        setIsSelectionMode(false)
        fetchWarehouse()
        onRefresh?.()
      } else {
        setMessage(`出售失败: ${json.error}`)
      }
    } catch (error) {
      console.error(error)
      setMessage("网络错误")
    } finally {
      setIsSelling(false)
      setTimeout(() => setMessage(""), 3000)
    }
  }

  const handleUse = async () => {
    if (useTargets.length === 0) return

    setIsSelling(true)
    setMessage("")
    setGains([])

    const itemsToUse: { id: number, count: number, uid: number }[] = []
    useTargets.forEach(item => {
      const key = `${item.id}-${item.uid}`
      const selectedCount = useQuantities[key] ?? 1
      const count = Math.max(1, Math.min(item.count, selectedCount))
      itemsToUse.push({ id: item.id, count, uid: item.uid })
    })
    if (itemsToUse.length === 0) {
      setIsSelling(false)
      return
    }

    try {
      const res = await fetch('/api/warehouse/use', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email, items: itemsToUse })
      })
      const json = await res.json()
      if (json.success) {
        setMessage(json.message || "使用成功")
        if (Array.isArray(json.gains) && json.gains.length > 0) {
          setGains(json.gains)
          setGainDialogOpen(true)
        }
        setSelectedItems(new Set())
        setIsSelectionMode(false)
        fetchWarehouse()
        onRefresh?.()
        closeUseDialog()
      } else {
        setMessage(`使用失败: ${json.error}`)
      }
    } catch (error) {
      console.error(error)
      setMessage("网络错误")
    } finally {
      setIsSelling(false)
      setTimeout(() => setMessage(""), 3000)
    }
  }

  const getGainImage = (id: number, name?: string) => {
    if (verifiedItemMap[id]) return `/${verifiedItemMap[id]}`
    if (seedImageMap[id]) return `/shop_plants_organized/${seedImageMap[id]}`
    if (name && nameImageMap[name]) return `/shop_plants_organized/${nameImageMap[name]}`
    return undefined
  }

  return (
    <div className="bg-white/60 backdrop-blur-md rounded-[2.5rem] p-6 shadow-sm border border-white/50 h-[600px] flex flex-col relative overflow-hidden">
      <Dialog open={useDialogOpen} onOpenChange={(open) => { if (!open) closeUseDialog() }}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>使用数量</DialogTitle>
          </DialogHeader>
          <div className="space-y-3">
            {useTargets.map(item => {
              const key = `${item.id}-${item.uid}`
              const value = useQuantities[key] ?? 1
              return (
                <div key={key} className="flex items-center justify-between gap-3">
                  <div className="flex-1 min-w-0">
                    <div className="text-sm font-semibold text-slate-700 truncate">{item.name}</div>
                    <div className="text-xs text-slate-400">拥有 {item.count}</div>
                  </div>
                  <div className="w-24">
                    <Input
                      type="number"
                      min={1}
                      max={item.count}
                      value={value}
                      onChange={(event) => updateUseQuantity(key, event.target.value, item.count)}
                      className="text-center"
                    />
                  </div>
                </div>
              )
            })}
          </div>
          <div className="flex items-center justify-end gap-2 pt-2">
            <Button variant="ghost" onClick={closeUseDialog}>
              取消
            </Button>
            <Button onClick={handleUse} disabled={isSelling}>
              确认使用
            </Button>
          </div>
        </DialogContent>
      </Dialog>
      <Dialog open={gainDialogOpen} onOpenChange={setGainDialogOpen}>
        <DialogContent className="max-w-2xl">
          <DialogHeader>
            <DialogTitle>获得物品</DialogTitle>
          </DialogHeader>
          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 max-h-[60vh] overflow-y-auto pr-1">
            {gains.map(gain => {
              const imagePath = getGainImage(gain.id, gain.name)
              return (
                <div key={`${gain.id}-${gain.count}`} className="flex items-center gap-3 p-3 rounded-2xl bg-slate-50 border border-slate-100">
                  {imagePath ? (
                    <div className="w-12 h-12 rounded-full bg-white shadow-sm flex items-center justify-center overflow-hidden">
                      <img src={imagePath} alt={gain.name} className="w-9 h-9 object-contain" />
                    </div>
                  ) : (
                    <div className="w-12 h-12 rounded-full bg-white shadow-sm flex items-center justify-center text-slate-400">
                      <Package className="w-6 h-6" />
                    </div>
                  )}
                  <div className="min-w-0 flex-1">
                    <div className="text-sm font-semibold text-slate-700 break-words">{gain.name}</div>
                    <div className="text-xs text-slate-400">x{gain.count}</div>
                  </div>
                </div>
              )
            })}
          </div>
          <div className="flex items-center justify-end pt-2">
            <Button onClick={() => setGainDialogOpen(false)}>知道了</Button>
          </div>
        </DialogContent>
      </Dialog>
      <div className="flex items-center justify-between mb-6 px-2">
        <h2 className="text-xl font-bold text-slate-700 flex items-center gap-2">
          <span className="p-2 bg-orange-100 text-orange-600 rounded-xl">
            <Package className="h-5 w-5" />
          </span>
          我的仓库
        </h2>
        <div className="flex items-center gap-2">
           {message && (
             <span className="text-sm font-medium text-green-600 animate-fade-in bg-green-50 px-3 py-1 rounded-full border border-green-100">
               {message}
             </span>
           )}
           <Button
            variant={isSelectionMode ? "secondary" : "ghost"}
            size="sm"
            onClick={() => {
              setIsSelectionMode(!isSelectionMode)
              setSelectedItems(new Set())
            }}
            className="rounded-xl"
           >
             {isSelectionMode ? "取消选择" : (activeTab === 'others' ? "批量使用" : "批量出售")}
           </Button>
           <button 
            onClick={() => fetchWarehouse()}
            className="p-2 hover:bg-white/50 rounded-full transition-colors text-slate-400 hover:text-slate-600"
          >
            <RefreshCw className={cn("h-5 w-5", isLoading && "animate-spin")} />
          </button>
        </div>
      </div>

      <Tabs value={activeTab} className="flex-1 flex flex-col min-h-0" onValueChange={(val) => {
        setActiveTab(val)
        setSelectedItems(new Set())
        setIsSelectionMode(false)
      }}>
        <TabsList className="bg-slate-100/50 p-1 rounded-2xl w-full justify-start mb-4">
          <TabsTrigger value="seeds" className="rounded-xl data-[state=active]:bg-white data-[state=active]:text-green-600 data-[state=active]:shadow-sm flex-1">
            <Leaf className="h-4 w-4 mr-2" /> 种子
          </TabsTrigger>
          <TabsTrigger value="produce" className="rounded-xl data-[state=active]:bg-white data-[state=active]:text-red-500 data-[state=active]:shadow-sm flex-1">
            <Apple className="h-4 w-4 mr-2" /> 果实
          </TabsTrigger>
          <TabsTrigger value="others" className="rounded-xl data-[state=active]:bg-white data-[state=active]:text-purple-600 data-[state=active]:shadow-sm flex-1">
            <Zap className="h-4 w-4 mr-2" /> 道具
          </TabsTrigger>
        </TabsList>

        <ScrollArea className="flex-1 pr-4 -mr-4">
          <TabsContent value="seeds" className="mt-0">
            <ItemGrid 
              items={data.seeds} 
              color="green" 
              icon={Leaf} 
              emptyMsg="没有种子啦"
              isSelectionMode={isSelectionMode}
              selectedItems={selectedItems}
              onToggle={toggleSelection}
              seedImageMap={seedImageMap}
              nameImageMap={nameImageMap}
              verifiedItemMap={verifiedItemMap}
            />
          </TabsContent>
          <TabsContent value="produce" className="mt-0">
            <ItemGrid 
              items={data.produce} 
              color="red" 
              icon={Apple} 
              emptyMsg="空空如也"
              isSelectionMode={isSelectionMode}
              selectedItems={selectedItems}
              onToggle={toggleSelection}
              seedImageMap={seedImageMap}
              nameImageMap={nameImageMap}
              verifiedItemMap={verifiedItemMap}
            />
          </TabsContent>
          <TabsContent value="others" className="mt-0">
            <ItemGrid 
              items={data.others} 
              color="purple" 
              icon={Zap} 
              emptyMsg="啥也没有"
              isSelectionMode={isSelectionMode}
              selectedItems={selectedItems}
              onToggle={toggleSelection}
              onItemClick={(item) => {
                if (isSelectionMode) return
                setSelectedItems(new Set())
                openUseDialogForItems([item])
              }}
              seedImageMap={seedImageMap}
              nameImageMap={nameImageMap}
              verifiedItemMap={verifiedItemMap}
            />
          </TabsContent>
        </ScrollArea>
      </Tabs>
      
      {isSelectionMode && selectedItems.size > 0 && (
        <div className="absolute bottom-6 left-1/2 -translate-x-1/2 z-10 animate-in slide-in-from-bottom-4 fade-in duration-300">
          <Button 
            onClick={handleSell} 
            disabled={isSelling}
            className={cn(
              "rounded-2xl px-8 shadow-lg text-white border-0",
              activeTab === 'others' 
                ? "shadow-purple-200 bg-gradient-to-r from-purple-400 to-indigo-500 hover:from-purple-500 hover:to-indigo-600"
                : "shadow-orange-200 bg-gradient-to-r from-orange-400 to-red-500 hover:from-orange-500 hover:to-red-600"
            )}
          >
            {isSelling ? (
              <RefreshCw className="h-4 w-4 mr-2 animate-spin" />
            ) : (
              activeTab === 'others' ? <Zap className="h-4 w-4 mr-2" /> : <Coins className="h-4 w-4 mr-2" />
            )}
            {activeTab === 'others' ? `确认使用 (${selectedItems.size})` : `确认出售 (${selectedItems.size})`}
          </Button>
        </div>
      )}
    </div>
  )
}

function ItemGrid({ 
  items, 
  color, 
  icon: Icon, 
  emptyMsg,
  isSelectionMode,
  selectedItems,
  onToggle,
  onItemClick,
  seedImageMap,
  nameImageMap,
  verifiedItemMap
}: { 
  items: Item[], 
  color: string, 
  icon: ComponentType<SVGProps<SVGSVGElement>>, 
  emptyMsg: string,
  isSelectionMode: boolean,
  selectedItems: Set<string>,
  onToggle: (item: Item) => void,
  onItemClick?: (item: Item) => void,
  seedImageMap: Record<number, string>,
  nameImageMap: Record<string, string>,
  verifiedItemMap: Record<number, string>
}) {
  if (items.length === 0) {
    return (
      <div className="h-40 flex flex-col items-center justify-center text-slate-400 gap-2">
        <Package className="h-10 w-10 opacity-20" />
        <span className="text-sm">{emptyMsg}</span>
      </div>
    )
  }

  const colorStyles = {
    green: "bg-green-50 border-green-100 text-green-700",
    red: "bg-red-50 border-red-100 text-red-700",
    purple: "bg-purple-50 border-purple-100 text-purple-700",
  }

  return (
    <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-3 pb-20">
      {items.map(item => {
        const key = `${item.id}-${item.uid}`
        const isSelected = selectedItems.has(key)
        const imagePath = item.type === 'seed'
          ? seedImageMap[item.id]
            ? `/shop_plants_organized/${seedImageMap[item.id]}`
            : undefined
          : item.type === 'produce'
            ? nameImageMap[item.name]
              ? `/shop_plants_organized/${nameImageMap[item.name]}`
              : undefined
            : item.type === 'other'
              ? verifiedItemMap[item.id]
                ? `/${verifiedItemMap[item.id]}`
                : undefined
              : undefined
        
        return (
          <div 
            key={key}
            onClick={() => {
              if (isSelectionMode) {
                onToggle(item)
                return
              }
              onItemClick?.(item)
            }}
            className={cn(
              "relative group flex flex-col items-center p-4 rounded-2xl border transition-all duration-300",
              colorStyles[color as keyof typeof colorStyles] || colorStyles.green,
              isSelectionMode ? "cursor-pointer hover:shadow-md" : (onItemClick ? "cursor-pointer hover:shadow-md" : "cursor-default hover:scale-[1.02]"),
              isSelected && "ring-2 ring-offset-2 ring-orange-400 bg-orange-50 border-orange-200"
            )}
          >
            {isSelectionMode && (
              <div className="absolute top-2 right-2">
                {isSelected ? (
                  <CheckCircle2 className="h-5 w-5 text-orange-500 fill-white" />
                ) : (
                  <Circle className="h-5 w-5 text-slate-300" />
                )}
              </div>
            )}
            
            {imagePath ? (
              <div className="bg-white/60 p-2 rounded-full mb-2 shadow-sm">
                <img src={imagePath} alt={item.name} className="h-10 w-10 object-contain" />
              </div>
            ) : (
              <div className="bg-white/60 p-3 rounded-full mb-2 shadow-sm">
                <Icon className="h-6 w-6" />
              </div>
            )}
            <span className="font-bold text-sm text-center line-clamp-1">{item.name}</span>
            <span className="text-xs opacity-70 mt-1">x{item.count}</span>
          </div>
        )
      })}
    </div>
  )
}
