import { forwardRef, useEffect, useMemo, useRef, useState } from "react"
import { Link, useNavigate, useSearchParams } from "react-router-dom"
import {
  ShoppingCart,
  Trash2,
  ChevronRight,
  Cpu,
  MemoryStick,
  HardDrive,
  Network,
  Server,
  Minus,
  Plus,
  ShieldCheck,
  Check,
  AlertCircle,
  Clock,
  Info,
  MapPin,
  Settings2,
  TerminalSquare,
  Globe,
  Receipt
} from "lucide-react"
import {
  listCartItems,
  updateCartItem,
  deleteCartItem,
  type CartItem,
} from "../api/cart"
import { checkout, previewCoupon, getAvailableCoupons, type AvailableCoupon, type CouponPreviewResponse, type CouponTargetOption } from "../api/orders"
import { toast } from "../utils/toast"

const CYCLE_LABEL: Record<string, string> = {
  hourly: "按小时",
  daily: "按天",
  monthly: "1个月",
  quarterly: "3个月",
  semi_annually: "半年",
  annually: "1年",
  biennially: "2年",
  triennially: "3年",
  one_time: "一次性",
}

function itemTotal(item: CartItem): number {
  return (item.unit_price + item.addon_price) * item.quantity + item.setup_fee
}

function cartItemStockLimit(item: CartItem): number {
  const product = item.product
  if (!product) return 0
  const maxQuantity = product.max_quantity ?? 0
  if (product.stock_policy !== "tracked") return maxQuantity
  const stock = Math.max(0, product.stock ?? 0)
  return maxQuantity > 0 ? Math.min(maxQuantity, stock) : stock
}

function itemUnavailableReason(item: CartItem): string | null {
  const product = item.product
  if (!product) return "商品不存在"
  if (product.status !== "active") return "商品已下架"
  if (product.stock_policy === "tracked") {
    const stock = Math.max(0, product.stock ?? 0)
    if (stock <= 0) return "已售罄"
    if (item.quantity > stock) return `库存不足，剩余 ${stock} 台`
  }
  return null
}

function canCheckoutItem(item: CartItem): boolean {
  return itemUnavailableReason(item) === null
}

function selectedStockIssues(items: CartItem[]): string[] {
  const totals = new Map<number, { name: string; stock: number; quantity: number }>()
  for (const item of items) {
    const product = item.product
    if (!product || product.status !== "active" || product.stock_policy !== "tracked") continue
    const stock = Math.max(0, product.stock ?? 0)
    if (stock <= 0) continue
    const current = totals.get(product.id) ?? { name: product.name, stock, quantity: 0 }
    current.quantity += item.quantity
    current.stock = Math.min(current.stock, stock)
    totals.set(product.id, current)
  }
  return Array.from(totals.values())
    .filter((item) => item.quantity > item.stock)
    .map((item) => `产品「${item.name}」选中数量 ${item.quantity} 台，当前仅剩 ${item.stock} 台`)
}

function couponLabel(c: AvailableCoupon) {
  const yuan = (cents: number) => (cents / 100).toFixed(2)
  let amount = ""
  if (c.type === "fixed") amount = `立减 ¥${yuan(c.value)}`
  else if (c.type === "threshold_fixed") amount = `满 ¥${yuan(c.threshold_amount)} 减 ¥${yuan(c.value)}`
  else if (c.type === "percent") amount = `${c.value / 10} 折`
  const desc = c.description || "优惠券"
  return `${desc} · ${amount}`
}

function apiDetail(error: unknown): unknown {
  return (error as { response?: { data?: { detail?: unknown } } })?.response?.data?.detail
}

function detailMessage(error: unknown, fallback: string) {
  const detail = apiDetail(error)
  if (typeof detail === "string") return detail
  if (detail && typeof detail === "object" && "message" in detail) {
    return String((detail as { message?: unknown }).message || fallback)
  }
  return fallback
}

function handleRealNameRequired(error: unknown, navigate: (to: string) => void) {
  const detail = apiDetail(error)
  if (!detail || typeof detail !== "object") return false
  const payload = detail as { code?: unknown; message?: unknown; verification_url?: unknown }
  if (payload.code !== "REAL_NAME_REQUIRED") return false
  toast.error(String(payload.message || "请先完成实名认证"))
  navigate(String(payload.verification_url || "/settings?tab=verification"))
  return true
}

export default function Cart() {
  const navigate = useNavigate()
  const [searchParams] = useSearchParams()
  const highlightId = Number(searchParams.get("highlight")) || null
  const preselectCouponId = Number(searchParams.get("coupon_id")) || null
  const autoCouponAppliedRef = useRef(false)
  const itemRefs = useRef<Record<number, HTMLDivElement | null>>({})
  const successRedirectTimerRef = useRef<number | null>(null)

  const [items, setItems] = useState<CartItem[]>([])
  const [loading, setLoading] = useState(true)
  const [checkoutLoading, setCheckoutLoading] = useState(false)
  const [successRedirecting, setSuccessRedirecting] = useState(false)
  const [couponLoading, setCouponLoading] = useState(false)
  const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set())
  const [availableCoupons, setAvailableCoupons] = useState<AvailableCoupon[]>([])
  const [couponsAgentDisabled, setCouponsAgentDisabled] = useState(false)
  const [selectedCouponId, setSelectedCouponId] = useState<number | null>(null)
  const [couponTargetCartItemId, setCouponTargetCartItemId] = useState<number | null>(null)
  const [couponPreview, setCouponPreview] = useState<CouponPreviewResponse | null>(null)
  const [couponTargetOptions, setCouponTargetOptions] = useState<CouponTargetOption[]>([])
  const [couponTargetDialogOpen, setCouponTargetDialogOpen] = useState(false)
  const [confirmDialog, setConfirmDialog] = useState<{
    open: boolean
    title: string
    description?: string
    confirmLabel?: string
    onConfirm: () => void
  }>({ open: false, title: "", onConfirm: () => {} })

  const reload = async () => {
    try {
      const [cartRes, coupons] = await Promise.all([
        listCartItems(),
        getAvailableCoupons(),
      ])
      const list = cartRes.data ?? []
      setItems(list)
      setSelectedIds(new Set(list.filter(canCheckoutItem).map((i) => i.id)))
      setAvailableCoupons(coupons.items)
      setCouponsAgentDisabled(coupons.agentDisabled)
    } catch (e: unknown) {
      const detail = (e as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail ?? "购物车加载失败")
      setAvailableCoupons([])
      setCouponsAgentDisabled(false)
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    reload()
  }, [])

  useEffect(() => {
    return () => {
      if (successRedirectTimerRef.current !== null) {
        window.clearTimeout(successRedirectTimerRef.current)
      }
    }
  }, [])

  useEffect(() => {
    const validIds = new Set(items.filter(canCheckoutItem).map((item) => item.id))
    setSelectedIds((prev) => {
      let changed = false
      const next = new Set<number>()
      for (const id of prev) {
        if (validIds.has(id)) next.add(id)
        else changed = true
      }
      return changed ? next : prev
    })
  }, [items])

  // 数据加载完成后滚动到高亮项
  useEffect(() => {
    if (!highlightId || loading) return
    const el = itemRefs.current[highlightId]
    if (el) {
      setTimeout(() => el.scrollIntoView({ behavior: "smooth", block: "center" }), 100)
    }
  }, [highlightId, loading])

  const toggleSelect = (id: number) => {
    const item = items.find((i) => i.id === id)
    if (!selectedIds.has(id) && item) {
      const reason = itemUnavailableReason(item)
      if (reason) {
        toast.error(reason)
        return
      }
    }
    setSelectedIds((prev) => {
      const next = new Set(prev)
      if (next.has(id)) next.delete(id)
      else next.add(id)
      return next
    })
  }

  const toggleAll = () => {
    const selectable = items.filter(canCheckoutItem)
    if (selectable.length > 0 && selectable.every((item) => selectedIds.has(item.id))) {
      setSelectedIds(new Set())
    } else {
      setSelectedIds(new Set(selectable.map((i) => i.id)))
    }
  }

  const handleQuantityChange = async (item: CartItem, q: number) => {
    if (q < 1) return
    let nextQuantity = q
    const max = cartItemStockLimit(item)
    if (max > 0 && q > max) {
      if (q < item.quantity) {
        nextQuantity = max
      } else {
        toast.error(`当前最多可购买 ${max} 台`)
        return
      }
    }
    if (nextQuantity === item.quantity) {
      return
    }
    if (max > 0 && nextQuantity > max) {
      toast.error(`当前最多可购买 ${max} 台`)
      return
    }
    try {
      const res = await updateCartItem(item.id, { quantity: nextQuantity })
      if (res.data) {
        setItems((prev) => prev.map((it) => (it.id === item.id ? res.data! : it)))
      }
    } catch (e: unknown) {
      const detail = (e as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail ?? "更新数量失败")
    }
  }

  const handleAutoRenewChange = async (item: CartItem, v: boolean) => {
    try {
      const res = await updateCartItem(item.id, { auto_renew: v })
      if (res.data) {
        setItems((prev) => prev.map((it) => (it.id === item.id ? res.data! : it)))
      }
    } catch {
      toast.error("更新续费设置失败")
    }
  }

  const handleAliasChange = async (item: CartItem, alias: string) => {
    try {
      const res = await updateCartItem(item.id, { alias: alias || null })
      if (res.data) {
        setItems((prev) => prev.map((it) => (it.id === item.id ? res.data! : it)))
      }
    } catch {
      toast.error("更新别名失败")
    }
  }

  const handleDelete = (item: CartItem) => {
    setConfirmDialog({
      open: true,
      title: `移除「${item.product?.name ?? item.product_id}」`,
      description: "该商品将从购物车中移除，此操作不可撤销。",
      confirmLabel: "确认移除",
      onConfirm: async () => {
        setConfirmDialog((d) => ({ ...d, open: false }))
        try {
          await deleteCartItem(item.id)
          setItems((prev) => prev.filter((it) => it.id !== item.id))
          setSelectedIds((prev) => { const next = new Set(prev); next.delete(item.id); return next })
          toast.success("已移除")
        } catch {
          toast.error("删除失败")
        }
      },
    })
  }

  const handleBatchDelete = () => {
    if (selectedIds.size === 0) return
    setConfirmDialog({
      open: true,
      title: `移除选中的 ${selectedIds.size} 件商品`,
      description: "选中的商品将全部从购物车移除，此操作不可撤销。",
      confirmLabel: `移除 ${selectedIds.size} 件`,
      onConfirm: async () => {
        setConfirmDialog((d) => ({ ...d, open: false }))
        const promises = Array.from(selectedIds).map((id) => deleteCartItem(id).catch(() => null))
        await Promise.all(promises)
        setItems((prev) => prev.filter((it) => !selectedIds.has(it.id)))
        setSelectedIds(new Set())
        toast.success("批量移除成功")
      },
    })
  }

  const selectedItems = useMemo(
    () => items.filter((i) => selectedIds.has(i.id)),
    [items, selectedIds]
  )
  const selectableItems = useMemo(
    () => items.filter(canCheckoutItem),
    [items],
  )
  const selectedInvalidItems = useMemo(
    () => selectedItems.filter((item) => !canCheckoutItem(item)),
    [selectedItems],
  )
  const selectedStockIssueMessages = useMemo(
    () => selectedStockIssues(selectedItems),
    [selectedItems],
  )
  const checkoutBlockedReason = selectedInvalidItems.length > 0
    ? itemUnavailableReason(selectedInvalidItems[0]) ?? "存在不可结算商品"
    : selectedStockIssueMessages[0] ?? null
  const selectedCheckoutIds = useMemo(
    () => selectedItems.filter(canCheckoutItem).map((item) => item.id),
    [selectedItems],
  )
  const grandTotal = selectedItems.reduce((sum, i) => sum + itemTotal(i), 0)
  const totalQuantity = selectedItems.reduce((sum, i) => sum + i.quantity, 0)
  const totalSetupFee = selectedItems.reduce((sum, i) => sum + i.setup_fee, 0)
  const isAllSelected = selectableItems.length > 0 && selectableItems.every((item) => selectedIds.has(item.id))
  const couponDiscountYuan = (couponPreview?.coupon_discount_amount ?? 0) / 100
  const payableYuan = couponPreview ? couponPreview.final_amount / 100 : grandTotal

  useEffect(() => {
    setCouponPreview(null)
    setSelectedCouponId(null)
    setCouponTargetCartItemId((prev) => (prev && selectedIds.has(prev) ? prev : null))
    setCouponTargetOptions([])
    setCouponTargetDialogOpen(false)
  }, [items, selectedIds])

  // URL 带 coupon_id 时自动选中优惠券（只触发一次，需在上面的重置副作用之后执行）
  useEffect(() => {
    if (loading || !preselectCouponId || autoCouponAppliedRef.current) return
    if (selectedItems.length === 0) return
    const coupon = availableCoupons.find((c) => c.id === preselectCouponId)
    if (!coupon) return
    autoCouponAppliedRef.current = true
    void handleSelectCoupon(preselectCouponId)
  }, [loading, availableCoupons, preselectCouponId, selectedItems])

  const handleSelectCoupon = async (couponId: number | null) => {
    setSelectedCouponId(couponId)
    setCouponTargetCartItemId(null)
    setCouponTargetOptions([])
    setCouponTargetDialogOpen(false)
    if (!couponId) {
      setCouponPreview(null)
      return
    }
    if (selectedItems.length === 0) {
      toast.error("请先选择要结算的商品")
      return
    }
    if (checkoutBlockedReason) {
      toast.error(checkoutBlockedReason)
      return
    }
    setCouponLoading(true)
    try {
      const res = await previewCoupon(selectedCheckoutIds, {
        coupon_id: couponId,
      })
      const data = res.data.data ?? null
      if (data?.requires_target_selection) {
        const options = data.target_options ?? []
        if (options.length === 0) {
          toast.error("当前购物车没有可使用该产品级优惠券的商品")
          setCouponPreview(null)
          return
        }
        setCouponPreview(null)
        setCouponTargetCartItemId(null)
        setCouponTargetOptions(options)
        setCouponTargetDialogOpen(true)
        return
      }
      setCouponPreview(data)
      toast.success("优惠券已应用")
    } catch (e: unknown) {
      setCouponPreview(null)
      if (!handleRealNameRequired(e, navigate)) {
        toast.error(detailMessage(e, "优惠券不可用"))
      }
    } finally {
      setCouponLoading(false)
    }
  }

  const handleApplyCouponTarget = async (targetCartItemId: number) => {
    if (!selectedCouponId) return
    if (checkoutBlockedReason) {
      toast.error(checkoutBlockedReason)
      return
    }
    setCouponLoading(true)
    try {
      const res = await previewCoupon(selectedCheckoutIds, {
        coupon_id: selectedCouponId,
        coupon_target_cart_item_id: targetCartItemId,
      })
      const data = res.data.data ?? null
      setCouponPreview(data)
      setCouponTargetCartItemId(targetCartItemId)
      setCouponTargetOptions([])
      setCouponTargetDialogOpen(false)
      toast.success("优惠券已应用")
    } catch (e: unknown) {
      setCouponPreview(null)
      if (!handleRealNameRequired(e, navigate)) {
        toast.error(detailMessage(e, "优惠券不可用"))
      }
    } finally {
      setCouponLoading(false)
    }
  }

  const handleRemoveCoupon = () => {
    setSelectedCouponId(null)
    setCouponTargetCartItemId(null)
    setCouponPreview(null)
    setCouponTargetOptions([])
    setCouponTargetDialogOpen(false)
  }

  if (loading) {
    return (
      <div className="min-h-screen bg-[#f3f4f6] text-gray-900 pb-20 font-sans">
        {/* 骨架 Header */}
        <div className="relative h-[240px] lg:h-[280px] bg-slate-900 overflow-hidden">
          <div className="absolute inset-0 bg-gradient-to-b from-slate-900/80 via-slate-900/60 to-[#f3f4f6]" />
          <div className="relative z-10 max-w-[1400px] mx-auto px-6 h-full flex flex-col justify-center pb-8">
            <div className="h-3 w-40 rounded bg-white/10 mb-6 animate-pulse" />
            <div className="h-8 w-56 rounded bg-white/10 mb-3 animate-pulse" />
            <div className="h-3 w-96 rounded bg-white/10 animate-pulse" />
          </div>
        </div>
        {/* 骨架内容 */}
        <div className="max-w-[1400px] mx-auto px-6 -mt-8 relative z-20">
          <div className="flex flex-col xl:flex-row gap-6 items-start">
            {/* 左侧列表骨架 */}
            <div className="flex-1 w-full space-y-4">
              {/* 控制栏骨架 */}
              <div className="bg-white border border-gray-200 shadow-sm rounded-sm p-3.5 flex items-center gap-4">
                <div className="h-4 w-4 rounded bg-gray-200 animate-pulse" />
                <div className="h-3 w-16 rounded bg-gray-200 animate-pulse" />
                <div className="h-3 w-px bg-gray-200" />
                <div className="h-3 w-16 rounded bg-gray-200 animate-pulse" />
              </div>
              {/* 商品行骨架 */}
              <div className="bg-white border border-gray-200 shadow-sm rounded-sm overflow-hidden divide-y divide-gray-100">
                {[1, 2].map((i) => (
                  <div key={i} className="flex gap-5 p-5">
                    <div className="h-4 w-4 rounded bg-gray-200 animate-pulse shrink-0 mt-1" />
                    <div className="flex-1 space-y-3">
                      <div className="flex items-center gap-3">
                        <div className="h-8 w-8 rounded-lg bg-gray-200 animate-pulse shrink-0" />
                        <div className="space-y-1.5 flex-1">
                          <div className="h-4 w-48 rounded bg-gray-200 animate-pulse" />
                          <div className="h-3 w-32 rounded bg-gray-100 animate-pulse" />
                        </div>
                      </div>
                      <div className="flex gap-4">
                        <div className="h-3 w-20 rounded bg-gray-100 animate-pulse" />
                        <div className="h-3 w-20 rounded bg-gray-100 animate-pulse" />
                        <div className="h-3 w-20 rounded bg-gray-100 animate-pulse" />
                      </div>
                      <div className="flex justify-between items-center pt-1">
                        <div className="h-7 w-24 rounded bg-gray-100 animate-pulse" />
                        <div className="h-6 w-20 rounded bg-gray-200 animate-pulse" />
                      </div>
                    </div>
                  </div>
                ))}
              </div>
            </div>
            {/* 右侧侧边栏骨架 */}
            <div className="w-full xl:w-[380px] shrink-0">
              <div className="bg-white border border-gray-200 shadow-lg shadow-gray-200/40 rounded-sm overflow-hidden">
                <div className="bg-gray-50 px-5 py-4 border-b border-gray-200">
                  <div className="h-4 w-24 rounded bg-gray-200 animate-pulse" />
                </div>
                <div className="p-5 space-y-4">
                  {[1, 2, 3].map((i) => (
                    <div key={i} className="flex justify-between">
                      <div className="h-3 w-24 rounded bg-gray-100 animate-pulse" />
                      <div className="h-3 w-16 rounded bg-gray-200 animate-pulse" />
                    </div>
                  ))}
                  <div className="border-t border-dashed border-gray-200 pt-4 flex justify-between items-center">
                    <div className="h-3 w-16 rounded bg-gray-100 animate-pulse" />
                    <div className="h-7 w-28 rounded bg-gray-200 animate-pulse" />
                  </div>
                  <div className="h-10 w-full rounded bg-gray-200 animate-pulse mt-2" />
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    )
  }

  return (
    <div className="min-h-screen bg-[#f3f4f6] text-gray-900 pb-20 font-sans">
      <ConfirmDialog
        {...confirmDialog}
        onCancel={() => setConfirmDialog((d) => ({ ...d, open: false }))}
      />
      <ProductCouponTargetDialog
        open={couponTargetDialogOpen}
        loading={couponLoading}
        label={selectedCouponId ? couponLabel(availableCoupons.find((c) => c.id === selectedCouponId)!) : ""}
        options={couponTargetOptions}
        onCancel={() => {
          setCouponTargetDialogOpen(false)
          setCouponTargetOptions([])
        }}
        onSelect={handleApplyCouponTarget}
      />
      {/* 顶部大厂风格 Header，使用 bg.mp4 的帧作为背景（通过 video 模拟静态或极慢动态） */}
      <div className="relative h-[240px] lg:h-[280px] bg-slate-900 overflow-hidden">
        {/* 背景视频/图像层 */}
        <div className="absolute inset-0 z-0">
          <video autoPlay loop muted playsInline className="w-full h-full object-cover opacity-30 mix-blend-luminosity">
            <source src="/bg.mp4" type="video/mp4" />
          </video>
          <div className="absolute inset-0 bg-gradient-to-b from-slate-900/80 via-slate-900/60 to-[#f3f4f6]" />
        </div>

        {/* 内容层 */}
        <div className="relative z-10 max-w-[1400px] mx-auto px-6 h-full flex flex-col justify-center pb-8">
          <div className="flex items-center text-sm text-sky-200/80 mb-6 gap-2">
            <Link to="/store" className="hover:text-white transition-colors">产品中心</Link>
            <ChevronRight className="w-3.5 h-3.5" />
            <span className="text-white">购物车</span>
          </div>

          <div className="flex justify-between items-end">
            <div>
              <h1 className="text-3xl font-medium text-white tracking-tight flex items-center gap-4">
                购物车
                <span className="text-lg font-normal text-sky-300/80 tracking-normal border border-sky-400/30 bg-sky-400/10 px-3 py-1 rounded-sm">
                  共 {items.length} 件商品
                </span>
              </h1>
              <p className="text-slate-300 text-sm mt-3 max-w-xl leading-relaxed">
                确认您选择的云服务器、网络及其他云资源的配置详情与计费周期。在提交订单前，请确保所有实例设置符合您的业务需求。
              </p>
            </div>

            <div className="hidden md:flex flex-col items-end">
              <div className="flex items-center gap-1.5 text-sm font-medium text-sky-400 mb-2">
                <ShieldCheck className="w-4 h-4" /> 官方自营产品
              </div>
              <div className="flex gap-1">
                {[1, 2, 3].map(step => (
                  <div key={step} className={`h-1.5 w-12 rounded-full ${step === 1 ? 'bg-sky-500' : 'bg-slate-700/50'}`} />
                ))}
              </div>
              <div className="flex gap-8 text-xs text-slate-400 mt-2">
                <span className="text-sky-400">1. 确认配置</span>
                <span>2. 提交订单</span>
                <span>3. 支付开通</span>
              </div>
            </div>
          </div>
        </div>
      </div>

      <div className="max-w-[1400px] mx-auto px-6 -mt-8 relative z-20">
        {items.length === 0 ? (
          <EmptyState onShop={() => navigate("/store")} />
        ) : (
          <div className="flex flex-col xl:flex-row gap-6 items-start">

            {/* 左侧：复杂列表区域 */}
            <div className="flex-1 w-full space-y-4">

              {/* 批量操作控制台 */}
              <div className="bg-white border border-gray-200 shadow-sm rounded-sm p-3.5 flex items-center justify-between sticky top-0 z-30">
                <div className="flex items-center gap-6">
                  <label className="flex items-center gap-2 cursor-pointer select-none group">
                    <Checkbox checked={isAllSelected} onChange={toggleAll} />
                    <span className="text-sm text-gray-700 font-medium group-hover:text-sky-600 transition-colors">
                      全选
                    </span>
                  </label>

                  <div className="h-4 w-px bg-gray-300" />

                  <button
                    onClick={handleBatchDelete}
                    disabled={selectedIds.size === 0}
                    className="text-sm text-gray-600 hover:text-red-600 disabled:text-gray-400 disabled:cursor-not-allowed transition-colors"
                  >
                    批量移除
                  </button>
                </div>
                <div className="text-sm text-gray-500 flex items-center gap-2">
                  <Info className="w-4 h-4 text-sky-500" />
                  开通后首个账期内享受退订保障
                </div>
              </div>

              {/* 大厂风格：列表视图 */}
              <div className="bg-white border border-gray-200 shadow-sm rounded-sm overflow-hidden">
                <div className="flex flex-col divide-y divide-gray-100">
                  {items.map((item) => (
                    <CartItemDataRow
                      key={item.id}
                      item={item}
                      selected={selectedIds.has(item.id)}
                      highlight={item.id === highlightId}
                      ref={(el) => { itemRefs.current[item.id] = el }}
                      onToggle={() => toggleSelect(item.id)}
                      onQuantityChange={(q) => handleQuantityChange(item, q)}
                      onAutoRenewChange={(v) => handleAutoRenewChange(item, v)}
                      onAliasChange={(v) => handleAliasChange(item, v)}
                      onDelete={() => handleDelete(item)}
                    />
                  ))}
                </div>
              </div>
            </div>

            {/* 右侧：订单计费侧边栏 */}
            <div className="w-full xl:w-[380px] shrink-0 sticky top-20">
              <div className="bg-white border border-gray-200 shadow-lg shadow-gray-200/40 rounded-sm overflow-hidden">
                <div className="bg-gray-50 px-5 py-4 border-b border-gray-200">
                  <h3 className="text-base font-medium text-gray-900 flex items-center gap-2">
                    <Receipt className="w-5 h-5 text-gray-500" />
                    费用清单
                  </h3>
                </div>

                <div className="p-5 space-y-6">
                  {/* 明细项 */}
                  <div className="space-y-3">
                    <div className="flex justify-between items-center text-sm">
                      <span className="text-gray-500">已选配置清单</span>
                      <span className="text-gray-900 font-medium">{selectedItems.length} 项</span>
                    </div>
                    <div className="flex justify-between items-center text-sm">
                      <span className="text-gray-500">资源实例总数</span>
                      <span className="text-gray-900 font-medium">{totalQuantity} 台</span>
                    </div>
                    <div className="flex justify-between items-center text-sm">
                      <span className="text-gray-500">配置费用</span>
                      <span className="text-gray-900">¥ {(grandTotal - totalSetupFee).toFixed(2)}</span>
                    </div>
                    {totalSetupFee > 0 && (
                      <div className="flex justify-between items-center text-sm">
                        <span className="text-gray-500 flex items-center gap-1">
                          初装及配置费
                          <div className="group relative cursor-help">
                            <Info className="w-3.5 h-3.5 text-gray-400" />
                          </div>
                        </span>
                        <span className="text-gray-900">¥ {totalSetupFee.toFixed(2)}</span>
                      </div>
                    )}
                  </div>

                  <div className="border-t border-dashed border-gray-200 pt-5 space-y-3">
                    <div className="flex items-center justify-between">
                      <div className="text-sm font-medium text-gray-900">优惠券</div>
                      {couponPreview && (
                        <button
                          type="button"
                          onClick={handleRemoveCoupon}
                          className="text-xs text-gray-500 hover:text-red-600"
                        >
                          移除
                        </button>
                      )}
                    </div>
                    <select
                      value={selectedCouponId ?? ""}
                      disabled={couponLoading || selectedCheckoutIds.length === 0 || !!checkoutBlockedReason || availableCoupons.length === 0 || couponsAgentDisabled}
                      onChange={(e) => handleSelectCoupon(e.target.value ? Number(e.target.value) : null)}
                      className="w-full h-10 border border-gray-200 rounded-sm px-3 text-sm outline-none focus:border-sky-500 disabled:bg-gray-100 disabled:text-gray-400"
                    >
                      <option value="">
                        {couponsAgentDisabled
                          ? "代理身份不可使用优惠券"
                          : availableCoupons.length === 0
                            ? "暂无可使用优惠券"
                            : "选择优惠券"}
                      </option>
                      {availableCoupons.map((c) => (
                        <option key={c.id} value={c.id}>
                          {couponLabel(c)}
                        </option>
                      ))}
                    </select>
                    {couponPreview?.coupon && (
                      <div className="rounded-sm bg-emerald-50 border border-emerald-100 px-3 py-2 text-xs text-emerald-700 flex items-center justify-between gap-3">
                        <span>
                          {couponPreview.coupon.discount_level === "product" ? "产品级优惠" : "订单级优惠"}
                          {couponPreview.coupon.description ? ` · ${couponPreview.coupon.description}` : ""}
                        </span>
                        <span className="font-medium">-¥ {couponDiscountYuan.toFixed(2)}</span>
                      </div>
                    )}
                  </div>

                  <div className="border-t border-dashed border-gray-200 pt-5">
                    {couponPreview && (
                      <div className="space-y-2 mb-5">
                        <div className="flex justify-between items-center text-sm">
                          <span className="text-gray-500">原始金额</span>
                          <span className="text-gray-900">¥ {grandTotal.toFixed(2)}</span>
                        </div>
                        <div className="flex justify-between items-center text-sm">
                          <span className="text-gray-500">优惠券抵扣</span>
                          <span className="text-emerald-600">-¥ {couponDiscountYuan.toFixed(2)}</span>
                        </div>
                      </div>
                    )}
                    <div className="flex flex-col items-end gap-1 mb-6">
                      <div className="text-xs text-gray-500">总计费用 (含税)</div>
                      <div className="flex items-baseline text-orange-600 gap-1">
                        <span className="text-lg">¥</span>
                        <span className="text-4xl font-medium tracking-tight">{payableYuan.toFixed(2)}</span>
                      </div>
                    </div>

                    {checkoutBlockedReason && (
                      <div className="mb-4 rounded-sm border border-red-100 bg-red-50 px-3 py-2 text-xs leading-relaxed text-red-600">
                        {checkoutBlockedReason}
                      </div>
                    )}

                    <button
                      disabled={selectedCheckoutIds.length === 0 || !!checkoutBlockedReason || checkoutLoading || successRedirecting}
                      onClick={async () => {
                        if (checkoutBlockedReason) {
                          toast.error(checkoutBlockedReason)
                          return
                        }
                        if (selectedCouponId && !couponPreview) {
                          toast.error("请先应用优惠券")
                          return
                        }
                        setCheckoutLoading(true)
                        setSuccessRedirecting(false)
                        let success = false
                        try {
                          await checkout(selectedCheckoutIds, couponPreview?.coupon ? {
                            coupon_id: selectedCouponId,
                            coupon_target_cart_item_id: couponPreview.coupon.target_cart_item_id ?? couponTargetCartItemId,
                          } : {})
                          success = true
                          setSuccessRedirecting(true)
                          toast.success("支付成功，2 秒后跳转到实例控制台")
                          if (successRedirectTimerRef.current !== null) {
                            window.clearTimeout(successRedirectTimerRef.current)
                          }
                          successRedirectTimerRef.current = window.setTimeout(() => {
                            navigate("/control/server")
                          }, 2000)
                        } catch (e: unknown) {
                          if (!handleRealNameRequired(e, navigate)) {
                            toast.error(detailMessage(e, "下单失败，请稍后重试"))
                          }
                        } finally {
                          if (!success) {
                            setCheckoutLoading(false)
                          }
                        }
                      }}
                      className="w-full h-11 bg-sky-600 hover:bg-sky-500 active:bg-sky-700 disabled:bg-sky-200 disabled:cursor-not-allowed text-white text-sm font-medium rounded-sm transition-colors flex items-center justify-center gap-2"
                    >
                      {successRedirecting ? "支付成功，正在跳转..." : checkoutLoading ? "正在提交..." : "确认配置并下单"}
                      {!checkoutLoading && !successRedirecting && <ChevronRight className="w-4 h-4" />}
                    </button>

                    <div className="mt-4 text-xs text-gray-500 flex items-start gap-1.5 leading-relaxed">
                      <AlertCircle className="w-3.5 h-3.5 text-gray-400 shrink-0 mt-0.5" />
                      点击下单即表示您同意《服务条款》与《隐私政策》。价格受汇率或活动影响，以最终账单为准。
                    </div>
                  </div>
                </div>
              </div>

              <div className="mt-4 bg-blue-50/50 border border-blue-100 p-4 rounded-sm">
                <div className="flex gap-3">
                  <div className="text-blue-500 mt-0.5"><Settings2 className="w-4 h-4" /></div>
                  <div className="text-xs text-blue-900/80 leading-relaxed">
                    <strong className="block text-blue-900 mb-1 font-medium">需要定制化方案？</strong>
                    如果您需要大批量采购或特殊的混合云架构配置，请联系专属架构师为您出具部署方案。
                  </div>
                </div>
              </div>
            </div>
          </div>
        )}
      </div>
    </div>
  )
}

// ─── 空状态 ─────────────────────────────────────────────────────────────────

function EmptyState({ onShop }: { onShop: () => void }) {
  return (
    <div className="bg-white border border-gray-200 shadow-sm rounded-sm p-16 flex flex-col items-center justify-center text-center">
      <div className="w-24 h-24 bg-gray-50 rounded-full flex items-center justify-center mb-6">
        <ShoppingCart className="w-10 h-10 text-gray-300" />
      </div>
      <h3 className="text-xl font-medium text-gray-900 mb-2">购物车暂无商品</h3>
      <p className="text-sm text-gray-500 max-w-sm mb-8">
        您还未选择任何云资源配置，请前往产品中心选购所需的高性能计算、存储及网络服务。
      </p>
      <button
        onClick={onShop}
        className="px-6 py-2.5 bg-sky-600 hover:bg-sky-500 text-white text-sm font-medium rounded-sm transition-colors"
      >
        浏览产品中心
      </button>
    </div>
  )
}

// ─── 大厂风格：复杂数据行组件 ────────────────────────────────────────────────

const CartItemDataRow = forwardRef<HTMLDivElement, {
  item: CartItem
  selected: boolean
  highlight?: boolean
  onToggle: () => void
  onQuantityChange: (q: number) => void
  onAutoRenewChange: (v: boolean) => void
  onAliasChange: (v: string) => void
  onDelete: () => void
}>(function CartItemDataRow({
  item,
  selected,
  highlight = false,
  onToggle,
  onQuantityChange,
  onAutoRenewChange,
  onAliasChange,
  onDelete,
}, ref) {
  const [aliasDraft, setAliasDraft] = useState(item.alias ?? "")
  const [glowing, setGlowing] = useState(highlight)
  useEffect(() => {
    setAliasDraft(item.alias ?? "")
  }, [item.alias])
  useEffect(() => {
    if (!highlight) return
    setGlowing(true)
    const t = setTimeout(() => setGlowing(false), 2000)
    return () => clearTimeout(t)
  }, [highlight])

  const product = item.product
  const lineTotal = itemTotal(item)
  const unavailableReason = itemUnavailableReason(item)
  const stockLimit = cartItemStockLimit(item)
  const plusDisabled = !!unavailableReason || (stockLimit > 0 && item.quantity >= stockLimit)

  return (
    <div
      ref={ref}
      className={`group flex flex-col md:flex-row transition-colors duration-300 ${
        unavailableReason
          ? "bg-gray-50/70 opacity-80"
          : glowing ? "bg-sky-50 ring-2 ring-inset ring-sky-300" : selected ? "bg-sky-50/20" : "hover:bg-gray-50/50"
      }`}
    >

      {/* 1. 复选框区域 */}
      <div className="p-5 pt-6 shrink-0 border-r border-gray-100 hidden md:block">
        <Checkbox checked={selected} disabled={!!unavailableReason && !selected} onChange={onToggle} />
      </div>

      {/* 移动端顶栏 */}
      <div className="md:hidden flex items-center justify-between p-4 border-b border-gray-100 bg-gray-50/50">
        <div className="flex items-center gap-3">
          <Checkbox checked={selected} disabled={!!unavailableReason && !selected} onChange={onToggle} />
          <span className="text-sm font-medium text-gray-900">选中该项</span>
        </div>
        <button onClick={onDelete} className="text-gray-400 hover:text-red-500 p-1">
          <Trash2 className="w-4 h-4" />
        </button>
      </div>

      {/* 2. 主体信息区域 */}
      <div className="flex-1 p-5 flex flex-col xl:flex-row gap-8">

        {/* 产品基本信息栏 */}
        <div className="flex-1 min-w-0">
          <div className="flex items-start justify-between">
            <div className="flex gap-4">
              <div className="w-12 h-12 bg-sky-50 rounded border border-sky-100 flex items-center justify-center shrink-0">
                <Server className="w-6 h-6 text-sky-600" />
              </div>
              <div>
                <h4 className="text-base font-medium text-gray-900 flex items-center gap-2">
                  {product?.name ?? `资源实例 #${item.product_id}`}
                  {item.auto_renew && (
                    <span className="px-1.5 py-0.5 bg-green-50 text-green-600 border border-green-200 text-[10px] rounded-sm font-normal">
                      自动续费
                    </span>
                  )}
                  {unavailableReason ? (
                    <span className="px-1.5 py-0.5 bg-red-50 text-red-600 border border-red-100 text-[10px] rounded-sm font-normal">
                      {unavailableReason}
                    </span>
                  ) : product?.stock_policy === "tracked" ? (
                    <span className="px-1.5 py-0.5 bg-emerald-50 text-emerald-600 border border-emerald-100 text-[10px] rounded-sm font-normal">
                      剩余 {product.stock} 台
                    </span>
                  ) : null}
                </h4>
                <div className="flex items-center gap-4 mt-2 text-xs text-gray-500">
                  <span className="flex items-center gap-1">
                    <Globe className="w-3.5 h-3.5" /> SKU: {product?.sku ?? "N/A"}
                  </span>
                  <span className="flex items-center gap-1">
                    <MapPin className="w-3.5 h-3.5" /> 默认可用区
                  </span>
                </div>
              </div>
            </div>

            <button
              onClick={onDelete}
              className="hidden md:flex text-gray-400 hover:text-red-500 transition-colors opacity-0 group-hover:opacity-100"
            >
              <Trash2 className="w-4 h-4" />
            </button>
          </div>

          {/* 复杂规格参数 */}
          <div className="mt-5 grid grid-cols-2 lg:grid-cols-4 gap-y-3 gap-x-6">
            <SpecDetail icon={<Cpu />} label="计算资源" value={product?.vcpu ? `${product.vcpu} vCPU` : "—"} />
            <SpecDetail icon={<MemoryStick />} label="内存容量" value={product?.memory || "—"} />
            <SpecDetail icon={<HardDrive />} label="系统盘/数据盘" value={product?.disk || "—"} />
            <SpecDetail icon={<Network />} label="公网带宽" value={product?.bandwidth || "—"} />

            <div className="col-span-2 lg:col-span-4 mt-1">
              <SpecDetail icon={<TerminalSquare />} label="操作系统" value={(() => { const v = item.os_image; return v?.includes("|") ? v.split("|")[1] : (v || "无需镜像") })()} highlight />
            </div>
          </div>
        </div>

        {/* 交互配置栏 */}
        <div className="xl:w-[320px] shrink-0 border-t xl:border-t-0 xl:border-l border-gray-100 pt-5 xl:pt-0 xl:pl-8 flex flex-col gap-4">

          {/* 计费模式 */}
          <div className="flex items-center justify-between text-sm">
            <span className="text-gray-500">计费周期</span>
            <span className="font-medium text-gray-900 border border-gray-200 px-3 py-1 rounded-sm bg-gray-50">
              {CYCLE_LABEL[item.cycle] ?? item.cycle}
            </span>
          </div>

          {/* 购买数量 */}
          <div className="flex items-center justify-between text-sm">
            <span className="text-gray-500">购买数量</span>
            <div className="flex items-center border border-gray-300 rounded-sm bg-white overflow-hidden h-7">
              <button
                onClick={() => onQuantityChange(item.quantity - 1)}
                disabled={item.quantity <= 1}
                className="w-7 h-full flex items-center justify-center text-gray-600 hover:bg-gray-100 disabled:opacity-30 transition-colors"
              >
                <Minus className="w-3 h-3" />
              </button>
              <span className="w-10 h-full flex items-center justify-center text-sm font-medium border-x border-gray-200">
                {item.quantity}
              </span>
              <button
                onClick={() => onQuantityChange(item.quantity + 1)}
                disabled={plusDisabled}
                className="w-7 h-full flex items-center justify-center text-gray-600 hover:bg-gray-100 disabled:opacity-30 transition-colors"
              >
                <Plus className="w-3 h-3" />
              </button>
            </div>
          </div>

          {/* 实例名称 */}
          <div className="flex items-center justify-between text-sm">
            <span className="text-gray-500">实例名称</span>
            <input
              type="text"
              value={aliasDraft}
              onChange={(e) => setAliasDraft(e.target.value)}
              onBlur={() => {
                if (aliasDraft !== (item.alias ?? "")) onAliasChange(aliasDraft)
              }}
              placeholder="自定义标识"
              className="w-[120px] h-7 px-2 border border-gray-300 rounded-sm text-xs focus:border-sky-500 focus:ring-1 focus:ring-sky-500/20 outline-none text-right"
            />
          </div>

          {/* 自动续费 */}
          <div className="flex items-center justify-between text-sm">
            <span className="text-gray-500 flex items-center gap-1">
              自动续费 <Clock className="w-3.5 h-3.5" />
            </span>
            <ToggleSwitch checked={item.auto_renew} onChange={() => onAutoRenewChange(!item.auto_renew)} />
          </div>

          <div className="mt-2 text-right">
            <div className="text-orange-600 text-xl font-medium tracking-tight">
              <span className="text-sm mr-0.5">¥</span>{lineTotal.toFixed(2)}
            </div>
            {(item.quantity > 1 || item.setup_fee > 0) && (
              <div className="text-xs text-gray-400 mt-1">
                包含 {item.quantity} 台配置费用
                {item.setup_fee > 0 && `及 ¥${item.setup_fee} 初装费`}
              </div>
            )}
          </div>

        </div>
      </div>
    </div>
  )
})

// ─── 基础与 UI 组件 ────────────────────────────────────────────────────────────

function SpecDetail({ icon, label, value, highlight }: { icon: React.ReactNode; label: string; value: string; highlight?: boolean }) {
  return (
    <div className="flex items-start gap-2">
      <div className="mt-0.5 text-gray-400 [&>svg]:w-3.5 [&>svg]:h-3.5">
        {icon}
      </div>
      <div>
        <div className="text-[11px] text-gray-400 mb-0.5">{label}</div>
        <div className={`text-[13px] font-medium ${highlight ? 'text-sky-600' : 'text-gray-800'}`}>
          {value}
        </div>
      </div>
    </div>
  )
}

function Checkbox({ checked, disabled = false, onChange }: { checked: boolean; disabled?: boolean; onChange: () => void }) {
  return (
    <button
      type="button"
      disabled={disabled}
      onClick={(e) => {
        e.stopPropagation()
        if (disabled) return
        onChange()
      }}
      className={`h-4 w-4 rounded-sm border flex items-center justify-center transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${
        checked
          ? "bg-sky-600 border-sky-600 text-white"
          : "border-gray-300 bg-white hover:border-sky-500"
      }`}
    >
      <Check strokeWidth={3} className={`w-3 h-3 ${checked ? "opacity-100" : "opacity-0"}`} />
    </button>
  )
}

function ToggleSwitch({ checked, onChange }: { checked: boolean; onChange: () => void }) {
  return (
    <button
      type="button"
      role="switch"
      aria-checked={checked}
      onClick={onChange}
      className={`relative inline-flex h-4 w-8 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none ${
        checked ? "bg-sky-600" : "bg-gray-300"
      }`}
    >
      <span
        className={`pointer-events-none inline-block h-3 w-3 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out ${
          checked ? "translate-x-4" : "translate-x-0"
        }`}
      />
    </button>
  )
}

function ProductCouponTargetDialog({
  open,
  loading,
  label,
  options,
  onCancel,
  onSelect,
}: {
  open: boolean
  loading: boolean
  label: string
  options: CouponTargetOption[]
  onCancel: () => void
  onSelect: (cartItemId: number) => void
}) {
  const [visible, setVisible] = useState(false)
  const [mounted, setMounted] = useState(false)

  useEffect(() => {
    if (open) {
      setMounted(true)
      requestAnimationFrame(() => requestAnimationFrame(() => setVisible(true)))
    } else {
      setVisible(false)
      const t = setTimeout(() => setMounted(false), 200)
      return () => clearTimeout(t)
    }
  }, [open])

  if (!mounted) return null

  const yuan = (cents: number) => (cents / 100).toFixed(2)

  return (
    <div className={`fixed inset-0 z-50 flex items-center justify-center transition-opacity duration-200 ${visible ? "opacity-100" : "opacity-0"}`}>
      <div className="absolute inset-0 bg-black/30 backdrop-blur-sm" onClick={loading ? undefined : onCancel} />
      <div className={`relative bg-white rounded-lg shadow-2xl w-full max-w-xl mx-4 overflow-hidden transition-all duration-200 ${visible ? "opacity-100 scale-100" : "opacity-0 scale-95"}`}>
        <div className="px-5 py-4 border-b border-gray-100">
          <div className="flex items-center justify-between gap-3">
            <div>
              <h3 className="text-base font-semibold text-gray-900">选择优惠商品</h3>
              <p className="mt-1 text-xs text-gray-500">{label || "该优惠券"} 是产品级优惠券，仅显示当前可使用的商品。</p>
            </div>
            <button
              type="button"
              onClick={onCancel}
              disabled={loading}
              className="text-sm text-gray-500 hover:text-gray-900 disabled:cursor-not-allowed"
            >
              取消
            </button>
          </div>
        </div>
        <div className="max-h-[420px] overflow-auto p-4 space-y-3">
          {options.map((option) => (
            <button
              key={option.cart_item_id}
              type="button"
              disabled={loading}
              onClick={() => onSelect(option.cart_item_id)}
              className="w-full text-left border border-gray-200 hover:border-sky-400 hover:bg-sky-50/60 disabled:opacity-70 disabled:cursor-wait rounded-sm p-4 transition-colors"
            >
              <div className="flex items-start justify-between gap-4">
                <div className="min-w-0">
                  <div className="text-sm font-medium text-gray-900 truncate">{option.product_name}</div>
                  <div className="mt-1 text-xs text-gray-500">
                    {option.sku ?? `#${option.product_id}`} · {option.cycle} · x {option.quantity}
                  </div>
                </div>
                <div className="text-right shrink-0">
                  <div className="text-xs text-gray-500">预计优惠</div>
                  <div className="text-sm font-semibold text-emerald-600">-¥ {yuan(option.discount_amount)}</div>
                </div>
              </div>
              <div className="mt-3 flex justify-between text-xs text-gray-500">
                <span>商品金额 ¥ {yuan(option.item_total)}</span>
                <span>优惠后 ¥ {yuan(option.final_amount)}</span>
              </div>
            </button>
          ))}
        </div>
      </div>
    </div>
  )
}

function ConfirmDialog({
  open,
  title,
  description,
  confirmLabel = "确认移除",
  onConfirm,
  onCancel,
}: {
  open: boolean
  title: string
  description?: string
  confirmLabel?: string
  onConfirm: () => void
  onCancel: () => void
}) {
  const [visible, setVisible] = useState(false)
  const [mounted, setMounted] = useState(false)

  useEffect(() => {
    if (open) {
      setMounted(true)
      requestAnimationFrame(() => requestAnimationFrame(() => setVisible(true)))
    } else {
      setVisible(false)
      const t = setTimeout(() => setMounted(false), 200)
      return () => clearTimeout(t)
    }
  }, [open])

  if (!mounted) return null
  return (
    <div className={`fixed inset-0 z-50 flex items-center justify-center transition-opacity duration-200 ${visible ? "opacity-100" : "opacity-0"}`}>
      <div className="absolute inset-0 bg-black/30 backdrop-blur-sm" onClick={onCancel} />
      <div className={`relative bg-white rounded-xl shadow-2xl w-full max-w-sm mx-4 overflow-hidden transition-all duration-200 ${visible ? "opacity-100 scale-100" : "opacity-0 scale-95"}`}>
        <div className="p-6">
          <div className="flex items-start gap-4">
            <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-red-50">
              <Trash2 className="h-5 w-5 text-red-500" />
            </div>
            <div className="flex-1 min-w-0">
              <h3 className="text-base font-semibold text-gray-900">{title}</h3>
              {description && <p className="mt-1 text-sm text-gray-500">{description}</p>}
            </div>
          </div>
        </div>
        <div className="flex gap-3 px-6 pb-6">
          <button
            onClick={onCancel}
            className="flex-1 rounded-lg border border-gray-200 bg-white py-2.5 text-sm font-medium text-gray-700 hover:bg-gray-50 transition-colors"
          >
            取消
          </button>
          <button
            onClick={onConfirm}
            className="flex-1 rounded-lg bg-red-500 py-2.5 text-sm font-medium text-white hover:bg-red-600 transition-colors"
          >
            {confirmLabel}
          </button>
        </div>
      </div>
    </div>
  )
}
