import { useCallback, useEffect, useMemo, useState } from "react"
import { useNavigate, useParams } from "react-router-dom"
import {
  ArrowLeftOutlined,
  CloudServerOutlined,
  DollarOutlined,
  KeyOutlined,
  LoginOutlined,
  MinusCircleOutlined,
  PlusCircleOutlined,
  ReloadOutlined,
  SaveOutlined,
  StopOutlined,
  ThunderboltOutlined,
  UnlockOutlined,
  UserOutlined,
  WalletOutlined,
} from "@ant-design/icons"
import {
  Avatar,
  Button,
  Card,
  Col,
  Descriptions,
  Empty,
  Form,
  Image,
  Input,
  InputNumber,
  Modal,
  Popconfirm,
  Result,
  Row,
  Select,
  Skeleton,
  Space,
  Statistic,
  Switch,
  Table,
  Tabs,
  Tag,
  Typography,
  type TableColumnsType,
} from "antd"
import { listAdminBalanceLogs, type AdminBalanceLog } from "../api/finance"
import { listMemberLevels, type MemberLevel } from "../api/membership"
import { listAdminServiceOrders, type AdminServiceOrder } from "../api/service_orders"
import { toast } from "../../utils/toast"
import {
  adjustUserBalance,
  addUserVerificationQuota,
  addUserInviteCodeQuota,
  addUserRefundQuota,
  banUser,
  getUser,
  impersonateUser,
  listUserInstances,
  reduceUserVerificationQuota,
  reduceUserRefundQuota,
  resetUserVerificationFreeQuota,
  resetUserInviteCodeQuota,
  resetUserPassword,
  resetUserRefundQuota,
  unbanUser,
  updateUser,
  type AgentTier,
  type AdminUser,
  type AdminUserInstance,
} from "../api/user"
import { useAdminAuth } from "../contexts/AdminAuthContext"

const { Title, Text, Paragraph } = Typography

const ROLE_META: Record<AdminUser["role"], { label: string; color: string }> = {
  super_admin: { label: "超级管理员", color: "purple" },
  admin: { label: "管理员", color: "blue" },
  user: { label: "普通用户", color: "default" },
}

const STATUS_META: Record<string, { label: string; color: string }> = {
  active: { label: "正常", color: "success" },
  inactive: { label: "未激活", color: "warning" },
  banned: { label: "已封禁", color: "error" },
  provisioning: { label: "开通中", color: "processing" },
  provision_failed: { label: "待处理", color: "error" },
  failed: { label: "开通失败", color: "error" },
  suspended: { label: "已暂停", color: "warning" },
  terminated: { label: "已销毁", color: "default" },
}

const ORDER_STATUS_META: Record<string, { label: string; color: string }> = {
  pending: { label: "待处理", color: "warning" },
  paid: { label: "已支付", color: "green" },
  cancelled: { label: "已退订", color: "default" },
  refunded: { label: "已退款", color: "purple" },
}

const TICKET_STATUS_META: Record<string, { label: string; color: string }> = {
  open: { label: "待处理", color: "red" },
  pending: { label: "待处理", color: "orange" },
  processing: { label: "处理中", color: "processing" },
  waiting_user: { label: "等用户", color: "blue" },
  answered: { label: "已回复", color: "green" },
  resolved: { label: "已解决", color: "cyan" },
  closed: { label: "已关闭", color: "default" },
}

const TICKET_PRIORITY_META: Record<string, { label: string; color: string }> = {
  low: { label: "低", color: "default" },
  normal: { label: "普通", color: "blue" },
  high: { label: "高", color: "orange" },
  urgent: { label: "紧急", color: "red" },
}

const BALANCE_TYPE_LABEL: Record<string, string> = {
  recharge: "充值到账",
  admin_adjust: "管理员调账",
  order_pay: "订单扣款",
  order_refund: "订单退款",
  recharge_refund: "充值退款",
}

const AGENT_TIER_OPTIONS: Array<{ value: AgentTier; label: string }> = [
  { value: "yunqi", label: "云启伙伴" },
  { value: "yunxiang", label: "云享伙伴" },
  { value: "yunce", label: "云策伙伴" },
  { value: "yunling", label: "云领伙伴" },
  { value: "yunzun", label: "云尊伙伴" },
  { value: "yunguan", label: "云冠伙伴" },
]

type UserTimelineItem = {
  key: string
  at: string | null
  type: string
  title: string
  description: string
}

type SummaryRow = {
  key: string
  label: string
  value: number | string
  extra?: string
}

function yuan(cents: number | null | undefined) {
  return `¥${((cents ?? 0) / 100).toFixed(2)}`
}

function fmtDate(value: string | null | undefined) {
  if (!value) return "-"
  return new Date(value).toLocaleString("zh-CN", {
    year: "numeric",
    month: "2-digit",
    day: "2-digit",
    hour: "2-digit",
    minute: "2-digit",
    hour12: false,
  })
}

function mediaUrl(value: string | null | undefined) {
  if (!value) return undefined
  if (/^https?:\/\//i.test(value)) return value
  if (value.startsWith("/")) return value
  return `/media/${value.replace(/^media\//, "")}`
}

function tag(value: string | null | undefined, fallback = "未知") {
  const meta = STATUS_META[value || ""] ?? { label: value || fallback, color: "default" }
  return <Tag color={meta.color}>{meta.label}</Tag>
}

function orderTag(value: string) {
  const meta = ORDER_STATUS_META[value] ?? { label: value, color: "default" }
  return <Tag color={meta.color}>{meta.label}</Tag>
}

function ticketTag(value: string) {
  const meta = TICKET_STATUS_META[value] ?? { label: value, color: "default" }
  return <Tag color={meta.color}>{meta.label}</Tag>
}

function ticketPriorityTag(value: string) {
  const meta = TICKET_PRIORITY_META[value] ?? { label: value, color: "default" }
  return <Tag color={meta.color}>{meta.label}</Tag>
}

function riskTag(level: "ok" | "warn" | "danger") {
  if (level === "danger") return <Tag color="red">需处理</Tag>
  if (level === "warn") return <Tag color="orange">需关注</Tag>
  return <Tag color="green">正常</Tag>
}

function verificationImageLinks(record: {
  id_card_front_image?: string | null
  id_card_back_image?: string | null
  id_card_face_image?: string | null
}) {
  const images = [
    { label: "正面", url: mediaUrl(record.id_card_front_image) },
    { label: "反面", url: mediaUrl(record.id_card_back_image) },
    { label: "人脸", url: mediaUrl(record.id_card_face_image) },
  ].filter((item): item is { label: string; url: string } => Boolean(item.url))

  if (!images.length) return <Text type="secondary">无材料</Text>
  return (
    <Image.PreviewGroup>
      <Space wrap size={6}>
        {images.map((item) => (
          <Image
            key={item.label}
            src={item.url}
            width={48}
            height={36}
            style={{ objectFit: "cover", borderRadius: 4 }}
            preview={{ mask: item.label }}
          />
        ))}
      </Space>
    </Image.PreviewGroup>
  )
}

function providerResponseText(value: Record<string, unknown> | null | undefined) {
  if (!value) return "-"
  const text = JSON.stringify(value)
  return (
    <Paragraph code copyable={{ text }} ellipsis={{ rows: 2, expandable: true, symbol: "展开" }} style={{ marginBottom: 0 }}>
      {text}
    </Paragraph>
  )
}

function agentTierLabel(value?: AgentTier | null) {
  return AGENT_TIER_OPTIONS.find((item) => item.value === value)?.label ?? "无"
}

export default function AdminUserDetail() {
  const { id } = useParams<{ id: string }>()
  const navigate = useNavigate()
  const { admin } = useAdminAuth()
  const [form] = Form.useForm()
  const userId = Number(id)

  const [activeTab, setActiveTab] = useState("overview")
  const [loading, setLoading] = useState(true)
  const [user, setUser] = useState<AdminUser | null>(null)
  const [formValues, setFormValues] = useState<Record<string, unknown>>({})
  const [memberLevels, setMemberLevels] = useState<MemberLevel[]>([])
  const [saving, setSaving] = useState(false)
  const [resettingPwd, setResettingPwd] = useState(false)
  const [adjustingBalance, setAdjustingBalance] = useState(false)
  const [adjustingRefundQuota, setAdjustingRefundQuota] = useState(false)
  const [adjustingInviteQuota, setAdjustingInviteQuota] = useState(false)
  const [adjustingVerificationQuota, setAdjustingVerificationQuota] = useState(false)
  const [impersonating, setImpersonating] = useState(false)
  const [impersonationPath, setImpersonationPath] = useState<string | null>(null)
  const [impersonationReason, setImpersonationReason] = useState("")
  const [instancesLoading, setInstancesLoading] = useState(false)
  const [ordersLoading, setOrdersLoading] = useState(false)
  const [logsLoading, setLogsLoading] = useState(false)

  const [instances, setInstances] = useState<AdminUserInstance[]>([])
  const [orders, setOrders] = useState<AdminServiceOrder[]>([])
  const [balanceLogs, setBalanceLogs] = useState<AdminBalanceLog[]>([])
  const [newPassword, setNewPassword] = useState("")
  const [balanceDelta, setBalanceDelta] = useState<number | null>(null)
  const [balanceReason, setBalanceReason] = useState("")
  const [refundQuotaCount, setRefundQuotaCount] = useState<number | null>(1)
  const [refundQuotaReason, setRefundQuotaReason] = useState("")
  const [inviteQuotaCount, setInviteQuotaCount] = useState<number | null>(1)
  const [inviteQuotaReason, setInviteQuotaReason] = useState("")
  const [verificationQuotaCount, setVerificationQuotaCount] = useState<number | null>(1)
  const [verificationQuotaReason, setVerificationQuotaReason] = useState("")

  const isSelf = useMemo(() => admin?.id === user?.id, [admin, user])
  const canEditRole = admin?.role === "super_admin"
  const canImpersonate = admin?.role === "super_admin"

  const applyUserToForm = useCallback((nextUser: AdminUser) => {
    setFormValues({
      nickname: nextUser.nickname ?? "",
      email: nextUser.email ?? "",
      phone: nextUser.phone ?? "",
      real_name: nextUser.real_name_full ?? nextUser.real_name ?? "",
      id_card_no: nextUser.id_card_no_full ?? nextUser.id_card_no ?? "",
      id_card_verified: nextUser.id_card_verified ?? "unverified",
      member_level_id: nextUser.membership?.member_level_id ?? undefined,
      member_level_locked: nextUser.membership?.member_level_locked ?? false,
      agent_tier: nextUser.membership?.agent_tier ?? null,
      role: nextUser.role,
      status: nextUser.status,
      is_email_verified: nextUser.is_email_verified,
      is_phone_verified: nextUser.is_phone_verified,
    })
  }, [])

  const reloadUser = useCallback(async () => {
    setLoading(true)
    try {
      const res = await getUser(userId)
      if (res.data) {
        setUser(res.data)
        applyUserToForm(res.data)
      }
    } catch (error: unknown) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail ?? "加载用户失败")
    } finally {
      setLoading(false)
    }
  }, [applyUserToForm, userId])

  const reloadInstances = useCallback(async () => {
    setInstancesLoading(true)
    try {
      const res = await listUserInstances(userId)
      setInstances(res.data ?? [])
    } catch (error: unknown) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail ?? "加载用户实例失败")
    } finally {
      setInstancesLoading(false)
    }
  }, [userId])

  const reloadOrders = useCallback(async () => {
    setOrdersLoading(true)
    try {
      const res = await listAdminServiceOrders({ user_id: userId, limit: 200 })
      setOrders(res.data ?? [])
    } catch (error: unknown) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail ?? "加载服务订单失败")
    } finally {
      setOrdersLoading(false)
    }
  }, [userId])

  const reloadBalanceLogs = useCallback(async () => {
    setLogsLoading(true)
    try {
      const res = await listAdminBalanceLogs({ user_id: userId, limit: 100 })
      setBalanceLogs(res.data ?? [])
    } catch (error: unknown) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail ?? "加载余额流水失败")
    } finally {
      setLogsLoading(false)
    }
  }, [userId])

  useEffect(() => {
    void reloadUser()
    void reloadInstances()
    void (async () => {
      try {
        const res = await listMemberLevels()
        setMemberLevels(res.data ?? [])
      } catch {
        setMemberLevels([])
      }
    })()
  }, [reloadInstances, reloadUser])

  useEffect(() => {
    if (["instances", "resource-profile"].includes(activeTab)) void reloadInstances()
    if (["orders", "membership", "risk", "timeline", "order-analysis"].includes(activeTab)) void reloadOrders()
    if (["finance", "risk", "timeline", "balance-audit"].includes(activeTab)) void reloadBalanceLogs()
  }, [activeTab, reloadBalanceLogs, reloadInstances, reloadOrders])

  useEffect(() => {
    if (user && ["profile", "verification"].includes(activeTab)) {
      form.setFieldsValue(formValues)
    }
  }, [activeTab, form, formValues, user])

  const instanceStats = useMemo(() => ({
    total: instances.length,
    active: instances.filter((item) => item.status === "active").length,
    suspended: instances.filter((item) => item.status === "suspended").length,
    dueSoon: instances.filter((item) => {
      if (!item.expires_at) return false
      const diff = new Date(item.expires_at).getTime() - Date.now()
      return diff > 0 && diff <= 7 * 86400 * 1000
    }).length,
  }), [instances])

  const orderStats = useMemo(() => ({
    total: orders.length,
    paid: orders.filter((item) => item.status === "paid").length,
    pending: orders.filter((item) => item.status === "pending").length,
    refunded: orders.filter((item) => item.status === "refunded").length,
    refunding: orders.filter((item) => item.refund && !["finished", "manual_handled", "ignored"].includes(item.refund.resource_status)).length,
    resourceFailed: orders.filter((item) => item.resource_summary?.failed_count > 0 || item.refund?.resource_status === "failed").length,
    paidAmount: orders.reduce((sum, item) => sum + (item.status === "paid" || item.status === "refunded" ? Number(item.paid_amount || 0) : 0), 0),
  }), [orders])

  const balanceStats = useMemo(() => ({
    income: balanceLogs.filter((item) => item.delta > 0).reduce((sum, item) => sum + item.delta, 0),
    outcome: balanceLogs.filter((item) => item.delta < 0).reduce((sum, item) => sum + Math.abs(item.delta), 0),
    adminAdjust: balanceLogs.filter((item) => item.change_type === "admin_adjust").reduce((sum, item) => sum + item.delta, 0),
    latestAt: balanceLogs[0]?.created_at ?? null,
  }), [balanceLogs])

  const riskItems = useMemo(() => {
    if (!user) return []
    const items: Array<{ key: string; title: string; level: "ok" | "warn" | "danger"; detail: string }> = []
    items.push({
      key: "account",
      title: "账号状态",
      level: user.status === "banned" ? "danger" : user.status === "inactive" ? "warn" : "ok",
      detail: user.status === "banned" ? "账号已封禁，前台不可正常使用。" : user.status === "inactive" ? "账号未激活，需要确认是否为沉默或异常注册。" : "账号处于正常状态。",
    })
    items.push({
      key: "verification",
      title: "实名认证",
      level: user.id_card_verified === "verified" ? "ok" : user.id_card_verified === "pending" ? "warn" : "danger",
      detail: user.id_card_verified === "verified" ? "实名已通过。" : user.id_card_verified === "pending" ? "实名仍在处理中，需要关注任务终态。" : "实名未通过或未提交，涉及购买限制时需先处理。",
    })
    items.push({
      key: "contact",
      title: "联系方式",
      level: user.is_email_verified || user.is_phone_verified ? "ok" : "warn",
      detail: user.is_email_verified || user.is_phone_verified ? "至少一个联系方式已验证。" : "邮箱和手机都未验证，找回和通知能力较弱。",
    })
    items.push({
      key: "instances",
      title: "资源状态",
      level: instances.some((item) => ["failed", "provision_failed"].includes(item.status)) ? "danger" : instanceStats.dueSoon > 0 || instanceStats.suspended > 0 ? "warn" : "ok",
      detail: `共 ${instanceStats.total} 台实例，运行 ${instanceStats.active} 台，暂停 ${instanceStats.suspended} 台，7 天内到期 ${instanceStats.dueSoon} 台。`,
    })
    items.push({
      key: "orders",
      title: "订单状态",
      level: orderStats.resourceFailed > 0 ? "danger" : orderStats.pending > 0 || orderStats.refunding > 0 ? "warn" : "ok",
      detail: `共 ${orderStats.total} 个订单，待支付 ${orderStats.pending} 个，退款/资源处理中 ${orderStats.refunding} 个，资源失败 ${orderStats.resourceFailed} 个。`,
    })
    items.push({
      key: "tickets",
      title: "工单压力",
      level: (user.stats?.tickets_unread ?? 0) > 0 ? "danger" : (user.stats?.tickets_open ?? 0) > 0 ? "warn" : "ok",
      detail: `进行中 ${user.stats?.tickets_open ?? 0} 个，后台未读 ${user.stats?.tickets_unread ?? 0} 条。`,
    })
    return items
  }, [instanceStats.active, instanceStats.dueSoon, instanceStats.suspended, instanceStats.total, instances, orderStats.pending, orderStats.refunding, orderStats.resourceFailed, orderStats.total, user])

  const timelineItems = useMemo<UserTimelineItem[]>(() => {
    if (!user) return []
    const items: UserTimelineItem[] = [
      { key: "user-created", at: user.created_at, type: "账号", title: "用户注册", description: `用户名 @${user.username}` },
      { key: "user-login", at: user.last_login_at, type: "安全", title: "最近登录", description: user.last_login_at ? "用户最近一次登录时间" : "暂无登录记录" },
    ]
    user.verification_records?.forEach((record) => {
      items.push({
        key: `verification-${record.id}`,
        at: record.created_at,
        type: "实名",
        title: `实名认证 ${record.status}`,
        description: `${record.real_name || "-"} / ${record.id_card_no || "-"} / ${record.provider_task_id || record.provider}`,
      })
    })
    user.tickets?.forEach((ticket) => {
      items.push({
        key: `ticket-${ticket.id}`,
        at: ticket.last_message_at || ticket.created_at,
        type: "工单",
        title: ticket.subject,
        description: `${ticket.ticket_no} / ${ticket.department_name || "未分配部门"} / ${ticket.status}`,
      })
    })
    instances.forEach((instance) => {
      items.push({
        key: `instance-${instance.id}`,
        at: instance.created_at,
        type: "实例",
        title: instance.hostname || instance.alias || `实例 #${instance.id}`,
        description: `${instance.product_name} / ${instance.status} / 到期 ${fmtDate(instance.expires_at)}`,
      })
    })
    orders.forEach((order) => {
      items.push({
        key: `order-${order.id}`,
        at: order.created_at,
        type: "订单",
        title: order.out_order_no,
        description: `${order.status} / 实付 ${yuan(order.paid_amount)} / ${order.refund ? `退订 ${order.refund.status}` : "无退订"}`,
      })
    })
    balanceLogs.forEach((log) => {
      items.push({
        key: `balance-${log.id}`,
        at: log.created_at,
        type: "余额",
        title: BALANCE_TYPE_LABEL[log.change_type] ?? log.change_type,
        description: `${log.delta >= 0 ? "+" : "-"}${yuan(Math.abs(log.delta))} / 余额 ${yuan(log.balance_after)} / ${log.remark || "-"}`,
      })
    })
    return items
      .filter((item) => item.at)
      .sort((a, b) => new Date(b.at || 0).getTime() - new Date(a.at || 0).getTime())
      .slice(0, 60)
  }, [balanceLogs, instances, orders, user])

  const resourceProfile = useMemo(() => {
    const byStatus = new Map<string, number>()
    const byProduct = new Map<string, number>()
    const byGroup = new Map<string, number>()
    let natCount = 0
    let publicIpCount = 0
    let autoRenewCount = 0
    let monthlyAmount = 0
    instances.forEach((item) => {
      byStatus.set(item.status || "unknown", (byStatus.get(item.status || "unknown") ?? 0) + 1)
      byProduct.set(item.product_name || "未知产品", (byProduct.get(item.product_name || "未知产品") ?? 0) + 1)
      byGroup.set(item.product_group_name || "未分组", (byGroup.get(item.product_group_name || "未分组") ?? 0) + 1)
      if (item.main_ip) publicIpCount += 1
      else natCount += 1
      if (Number(item.auto_renew || 0) === 1) autoRenewCount += 1
      monthlyAmount += Number(item.next_renew_amount || 0)
    })
    const toRows = (map: Map<string, number>, labeler?: (key: string) => string): SummaryRow[] => (
      Array.from(map.entries())
        .sort((a, b) => b[1] - a[1])
        .map(([key, value]) => ({ key, label: labeler ? labeler(key) : key, value }))
    )
    return {
      byStatus: toRows(byStatus, (key) => STATUS_META[key]?.label ?? key),
      byProduct: toRows(byProduct),
      byGroup: toRows(byGroup),
      natCount,
      publicIpCount,
      autoRenewCount,
      monthlyAmount,
    }
  }, [instances])

  const orderAnalysis = useMemo(() => {
    const byStatus = new Map<string, number>()
    const byRefund = new Map<string, number>()
    const byResource = new Map<string, number>()
    let discountAmount = 0
    let refundableAmount = 0
    orders.forEach((item) => {
      byStatus.set(item.status || "unknown", (byStatus.get(item.status || "unknown") ?? 0) + 1)
      if (item.refund) byRefund.set(item.refund.status || "unknown", (byRefund.get(item.refund.status || "unknown") ?? 0) + 1)
      if (item.resource_summary?.status) byResource.set(item.resource_summary.status, (byResource.get(item.resource_summary.status) ?? 0) + 1)
      discountAmount += Number(item.discount_amount || 0)
      refundableAmount += Number(item.refund_policy?.refund_amount || 0)
    })
    const rows = (map: Map<string, number>, labeler?: (key: string) => string): SummaryRow[] => Array.from(map.entries()).map(([key, value]) => ({ key, label: labeler ? labeler(key) : key, value }))
    return {
      byStatus: rows(byStatus, (key) => ORDER_STATUS_META[key]?.label ?? key),
      byRefund: rows(byRefund),
      byResource: rows(byResource),
      discountAmount,
      refundableAmount,
    }
  }, [orders])

  const balanceAudit = useMemo(() => {
    const byType = new Map<string, { count: number; amount: number }>()
    balanceLogs.forEach((item) => {
      const current = byType.get(item.change_type) ?? { count: 0, amount: 0 }
      current.count += 1
      current.amount += item.delta
      byType.set(item.change_type, current)
    })
    return Array.from(byType.entries()).map(([key, value]) => ({
      key,
      label: BALANCE_TYPE_LABEL[key] ?? key,
      value: value.count,
      extra: yuan(value.amount),
    }))
  }, [balanceLogs])

  const verificationAudit = useMemo(() => {
    const records = user?.verification_records ?? []
    const byStatus = new Map<string, number>()
    const byProvider = new Map<string, number>()
    let cleaned = 0
    let withMaterial = 0
    records.forEach((item) => {
      byStatus.set(item.status || "unknown", (byStatus.get(item.status || "unknown") ?? 0) + 1)
      byProvider.set(item.provider || "unknown", (byProvider.get(item.provider || "unknown") ?? 0) + 1)
      if (item.material_cleaned) cleaned += 1
      if (item.id_card_front_image || item.id_card_back_image || item.id_card_face_image) withMaterial += 1
    })
    const statusRows: SummaryRow[] = Array.from(byStatus.entries()).map(([key, value]) => ({ key, label: STATUS_META[key]?.label ?? key, value }))
    const providerRows: SummaryRow[] = Array.from(byProvider.entries()).map(([key, value]) => ({ key, label: key, value }))
    return {
      total: records.length,
      cleaned,
      withMaterial,
      latest: records[0]?.created_at ?? null,
      byStatus: statusRows,
      byProvider: providerRows,
    }
  }, [user?.verification_records])

  const ticketProfile = useMemo(() => {
    const tickets = user?.tickets ?? []
    const byStatus = new Map<string, number>()
    const byPriority = new Map<string, number>()
    const byDepartment = new Map<string, number>()
    let rated = 0
    let ratingSum = 0
    tickets.forEach((item) => {
      byStatus.set(item.status || "unknown", (byStatus.get(item.status || "unknown") ?? 0) + 1)
      byPriority.set(item.priority || "unknown", (byPriority.get(item.priority || "unknown") ?? 0) + 1)
      byDepartment.set(item.department_name || "未分配部门", (byDepartment.get(item.department_name || "未分配部门") ?? 0) + 1)
      if (item.satisfaction_rating) {
        rated += 1
        ratingSum += item.satisfaction_rating
      }
    })
    const rows = (map: Map<string, number>, labeler?: (key: string) => string): SummaryRow[] => Array.from(map.entries()).map(([key, value]) => ({ key, label: labeler ? labeler(key) : key, value }))
    return {
      byStatus: rows(byStatus, (key) => TICKET_STATUS_META[key]?.label ?? key),
      byPriority: rows(byPriority, (key) => TICKET_PRIORITY_META[key]?.label ?? key),
      byDepartment: rows(byDepartment),
      rated,
      averageRating: rated ? (ratingSum / rated).toFixed(1) : "-",
    }
  }, [user?.tickets])

  const handleSave = async () => {
    if (!user) return
    const values = await form.validateFields()
    setSaving(true)
    try {
      const payload: Record<string, unknown> = {
        nickname: values.nickname || null,
        email: values.email || null,
        phone: values.phone || null,
        real_name: values.real_name || null,
        id_card_no: values.id_card_no ? String(values.id_card_no).replace(/\s/g, "").toUpperCase() : null,
        id_card_verified: values.id_card_verified || null,
        member_level_id: values.member_level_id ?? null,
        member_level_locked: !!values.member_level_locked,
        agent_tier: values.agent_tier || null,
        is_email_verified: !!values.is_email_verified,
        is_phone_verified: !!values.is_phone_verified,
      }
      if (!isSelf) {
        payload.status = values.status
        if (canEditRole) payload.role = values.role
      }
      const res = await updateUser(user.id, payload)
      if (res.data) {
        setUser(res.data)
        applyUserToForm(res.data)
        toast.success("已保存")
      }
    } catch (error: unknown) {
      const raw = (error as { response?: { data?: { detail?: unknown } } })?.response?.data?.detail
      const detail = typeof raw === "string" ? raw : raw ? JSON.stringify(raw) : null
      toast.error(detail || "保存失败")
    } finally {
      setSaving(false)
    }
  }

  const handleResetPassword = async () => {
    if (!user) return
    if (newPassword.length < 8) {
      toast.error("新密码至少 8 位")
      return
    }
    setResettingPwd(true)
    try {
      await resetUserPassword(user.id, newPassword)
      toast.success("密码已重置，用户会话已清除")
      setNewPassword("")
    } catch (error: unknown) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail ?? "重置失败")
    } finally {
      setResettingPwd(false)
    }
  }

  const handleAdjustBalance = async (sign: 1 | -1) => {
    if (!user || !balanceDelta || balanceDelta <= 0) {
      toast.error("请输入有效的金额")
      return
    }
    const cents = Math.round(balanceDelta * 100) * sign
    setAdjustingBalance(true)
    try {
      const res = await adjustUserBalance(user.id, {
        delta: cents,
        reason: balanceReason || undefined,
      })
      if (res.data) {
        setUser(res.data)
        toast.success(sign > 0 ? `已充值 ${yuan(Math.abs(cents))}` : `已扣减 ${yuan(Math.abs(cents))}`)
        setBalanceDelta(null)
        setBalanceReason("")
        void reloadBalanceLogs()
      }
    } catch (error: unknown) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail ?? "调整失败")
    } finally {
      setAdjustingBalance(false)
    }
  }

  const handleAddRefundQuota = async () => {
    if (!user || !refundQuotaCount || refundQuotaCount <= 0) {
      toast.error("请输入有效的增加次数")
      return
    }
    const reason = refundQuotaReason.trim()
    if (!reason) {
      toast.error("请填写增加名额原因")
      return
    }
    setAdjustingRefundQuota(true)
    try {
      const res = await addUserRefundQuota(user.id, Math.floor(refundQuotaCount), reason)
      if (res.data) {
        setUser(res.data)
        toast.success("全额退订名额已增加")
        setRefundQuotaCount(1)
        setRefundQuotaReason("")
        void reloadOrders()
      }
    } catch (error: unknown) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail ?? "增加名额失败")
    } finally {
      setAdjustingRefundQuota(false)
    }
  }

  const handleReduceRefundQuota = async () => {
    if (!user || !refundQuotaCount || refundQuotaCount <= 0) {
      toast.error("请输入有效的减少次数")
      return
    }
    const reason = refundQuotaReason.trim()
    if (!reason) {
      toast.error("请填写减少名额原因")
      return
    }
    setAdjustingRefundQuota(true)
    try {
      const res = await reduceUserRefundQuota(user.id, Math.floor(refundQuotaCount), reason)
      if (res.data) {
        setUser(res.data)
        toast.success("全额退订额外名额已减少")
        setRefundQuotaCount(1)
        setRefundQuotaReason("")
        void reloadOrders()
      }
    } catch (error: unknown) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail ?? "减少名额失败")
    } finally {
      setAdjustingRefundQuota(false)
    }
  }

  const handleResetRefundQuota = async () => {
    if (!user) return
    const reason = refundQuotaReason.trim()
    if (!reason) {
      toast.error("请填写重置次数原因")
      return
    }
    setAdjustingRefundQuota(true)
    try {
      const res = await resetUserRefundQuota(user.id, reason)
      if (res.data) {
        setUser(res.data)
        toast.success("全额退订已用次数已重置")
        setRefundQuotaReason("")
        void reloadOrders()
      }
    } catch (error: unknown) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail ?? "重置次数失败")
    } finally {
      setAdjustingRefundQuota(false)
    }
  }

  const handleAddInviteQuota = async () => {
    if (!user || !inviteQuotaCount || inviteQuotaCount <= 0) {
      toast.error("请输入有效的增加次数")
      return
    }
    const reason = inviteQuotaReason.trim()
    if (!reason) {
      toast.error("请填写增加邀请码次数的原因")
      return
    }
    setAdjustingInviteQuota(true)
    try {
      const res = await addUserInviteCodeQuota(user.id, Math.floor(inviteQuotaCount), reason)
      if (res.data) {
        setUser(res.data)
        toast.success("邀请码额外修改次数已增加")
        setInviteQuotaCount(1)
        setInviteQuotaReason("")
      }
    } catch (error: unknown) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail ?? "增加邀请码次数失败")
    } finally {
      setAdjustingInviteQuota(false)
    }
  }

  const handleResetInviteQuota = async () => {
    if (!user) return
    const reason = inviteQuotaReason.trim()
    if (!reason) {
      toast.error("请填写重置邀请码次数的原因")
      return
    }
    setAdjustingInviteQuota(true)
    try {
      const res = await resetUserInviteCodeQuota(user.id, reason)
      if (res.data) {
        setUser(res.data)
        toast.success("邀请码已用修改次数已重置")
        setInviteQuotaReason("")
      }
    } catch (error: unknown) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail ?? "重置邀请码次数失败")
    } finally {
      setAdjustingInviteQuota(false)
    }
  }

  const handleAddVerificationQuota = async () => {
    if (!user || !verificationQuotaCount || verificationQuotaCount <= 0) {
      toast.error("请输入有效的实名次数")
      return
    }
    const reason = verificationQuotaReason.trim()
    if (!reason) {
      toast.error("请填写调整实名次数的原因")
      return
    }
    setAdjustingVerificationQuota(true)
    try {
      const res = await addUserVerificationQuota(user.id, Math.floor(verificationQuotaCount), reason)
      if (res.data) {
        setUser(res.data)
        toast.success("实名认证次数已增加")
        setVerificationQuotaCount(1)
        setVerificationQuotaReason("")
      }
    } catch (error: unknown) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail ?? "调整实名次数失败")
    } finally {
      setAdjustingVerificationQuota(false)
    }
  }

  const handleReduceVerificationQuota = async () => {
    if (!user || !verificationQuotaCount || verificationQuotaCount <= 0) {
      toast.error("请输入有效的实名次数")
      return
    }
    const reason = verificationQuotaReason.trim()
    if (!reason) {
      toast.error("请填写调整实名次数的原因")
      return
    }
    setAdjustingVerificationQuota(true)
    try {
      const res = await reduceUserVerificationQuota(user.id, Math.floor(verificationQuotaCount), reason)
      if (res.data) {
        setUser(res.data)
        toast.success("实名认证次数已减少")
        setVerificationQuotaCount(1)
        setVerificationQuotaReason("")
      }
    } catch (error: unknown) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail ?? "调整实名次数失败")
    } finally {
      setAdjustingVerificationQuota(false)
    }
  }

  const handleResetVerificationFreeQuota = async () => {
    if (!user) return
    const reason = verificationQuotaReason.trim()
    if (!reason) {
      toast.error("请填写重置免费次数的原因")
      return
    }
    setAdjustingVerificationQuota(true)
    try {
      const res = await resetUserVerificationFreeQuota(user.id, reason)
      if (res.data) {
        setUser(res.data)
        toast.success("实名认证免费已用次数已重置")
        setVerificationQuotaReason("")
      }
    } catch (error: unknown) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail ?? "重置免费次数失败")
    } finally {
      setAdjustingVerificationQuota(false)
    }
  }

  const handleBanToggle = async () => {
    if (!user) return
    const isBan = user.status !== "banned"
    try {
      const res = isBan ? await banUser(user.id) : await unbanUser(user.id)
      if (res.data) {
        setUser(res.data)
        form.setFieldValue("status", res.data.status)
        toast.success(isBan ? "已封禁" : "已解封")
      }
    } catch (error: unknown) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail ?? "操作失败")
    }
  }

  const openAsUser = async (path: string) => {
    if (!user || !canImpersonate || !impersonationReason.trim()) return
    setImpersonating(true)
    try {
      const res = await impersonateUser(user.id, impersonationReason.trim())
      if (!res.data) return
      const popup = window.open("about:blank", "_blank")
      if (!popup) {
        toast.error("浏览器拦截了新窗口，请允许弹窗后重试")
        return
      }
      popup.document.write(`
        <script>
          try {
            localStorage.setItem("access_token", ${JSON.stringify(res.data.access_token)});
            localStorage.removeItem("refresh_token");
          } catch (e) {}
          location.replace(${JSON.stringify(path)});
        </script>
      `)
      toast.success(`已以 ${user.username} 身份打开`)
      setImpersonationPath(null)
      setImpersonationReason("")
    } catch (error: unknown) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail ?? "打开失败")
    } finally {
      setImpersonating(false)
    }
  }

  if (loading) return <Skeleton active paragraph={{ rows: 12 }} />

  if (!user) {
    return (
      <Result
        status="404"
        title="用户不存在"
        extra={<Button onClick={() => navigate("/admin/users")}>返回用户列表</Button>}
      />
    )
  }

  const roleMeta = ROLE_META[user.role]
  const userStatusMeta = STATUS_META[user.status]

  const instanceColumns: TableColumnsType<AdminUserInstance> = [
    {
      title: "实例",
      dataIndex: "hostname",
      width: 260,
      render: (_value, record) => (
        <Space orientation="vertical" size={0}>
          <Button type="link" style={{ padding: 0 }} onClick={() => navigate(`/admin/users/${user.id}/instances/${record.id}`)}>
            {record.hostname || record.alias || `实例 #${record.id}`}
          </Button>
          <Text type="secondary" style={{ fontSize: 12 }}>
            ID {record.id} · {record.product_name}
          </Text>
        </Space>
      ),
    },
    { title: "状态", dataIndex: "status", width: 110, render: (value) => tag(value) },
    {
      title: "网络",
      width: 170,
      render: (_value, record) => (
        <Space orientation="vertical" size={0}>
          <Text>{record.main_ip || "NAT网络"}</Text>
          <Text type="secondary" style={{ fontSize: 12 }}>
            上游 {record.upstream_id || "-"} / SSH {record.ssh_port || "-"}
          </Text>
        </Space>
      ),
    },
    {
      title: "计费",
      width: 190,
      render: (_value, record) => (
        <Space orientation="vertical" size={0}>
          <Text>{yuan(record.next_renew_amount)} / {record.cycle}</Text>
          <Text type="secondary" style={{ fontSize: 12 }}>到期 {fmtDate(record.expires_at)}</Text>
        </Space>
      ),
    },
    {
      title: "自动续费",
      dataIndex: "auto_renew",
      width: 110,
      render: (_value, record) => Number(record.auto_renew || 0) === 1 ? <Tag color="green">已开启</Tag> : <Tag>未开启</Tag>,
    },
    {
      title: "操作",
      key: "actions",
      width: 120,
      render: (_value, record) => (
        <Button type="primary" size="small" onClick={() => navigate(`/admin/users/${user.id}/instances/${record.id}`)}>
          管理实例
        </Button>
      ),
    },
  ]

  const balanceColumns: TableColumnsType<AdminBalanceLog> = [
    { title: "时间", dataIndex: "created_at", width: 170, render: fmtDate },
    { title: "类型", dataIndex: "change_type", width: 120, render: (value) => BALANCE_TYPE_LABEL[value] ?? value },
    {
      title: "变动",
      dataIndex: "delta",
      width: 120,
      align: "right",
      render: (value: number) => <Text type={value < 0 ? "danger" : "success"}>{value < 0 ? "-" : "+"}{yuan(Math.abs(value))}</Text>,
    },
    { title: "余额", dataIndex: "balance_after", width: 120, align: "right", render: yuan },
    { title: "关联单号", dataIndex: "ref_no", width: 180, render: (value) => value || "-" },
    { title: "备注", dataIndex: "remark", render: (value) => value || "-" },
  ]

  const inviteCodeColumns: TableColumnsType<NonNullable<AdminUser["invite_codes"]>[number]> = [
    { title: "邀请码", dataIndex: "code", render: (value, row) => <Space><Text code>{value}</Text>{row.is_current ? <Tag color="green">当前</Tag> : null}</Space> },
    { title: "来源", dataIndex: "source", width: 110 },
    { title: "创建时间", dataIndex: "created_at", width: 170, render: fmtDate },
  ]

  const inviteLogColumns: TableColumnsType<NonNullable<AdminUser["invite_code_logs"]>[number]> = [
    { title: "时间", dataIndex: "created_at", width: 170, render: fmtDate },
    { title: "动作", dataIndex: "action", width: 90, render: (value) => value === "add" ? "增加" : value === "reset" ? "重置" : value },
    { title: "次数", dataIndex: "count", width: 80 },
    { title: "已用变化", key: "used", width: 120, render: (_value, row) => `${row.before_used} -> ${row.after_used}` },
    { title: "额外变化", key: "extra", width: 120, render: (_value, row) => `${row.before_extra} -> ${row.after_extra}` },
    { title: "操作人", dataIndex: "operator_id", width: 100, render: (value) => value ? `#${value}` : "-" },
    { title: "原因", dataIndex: "reason", render: (value) => value || "-" },
  ]

  const verificationColumns: TableColumnsType<NonNullable<AdminUser["verification_records"]>[number]> = [
    { title: "时间", dataIndex: "created_at", width: 170, render: fmtDate },
    { title: "状态", dataIndex: "status", width: 100, render: (value) => tag(value) },
    {
      title: "身份",
      width: 180,
      render: (_value, record) => (
        <Space orientation="vertical" size={0}>
          <Text>{record.real_name || "-"}</Text>
          <Text type="secondary" style={{ fontSize: 12 }}>{record.id_card_no || "-"}</Text>
        </Space>
      ),
    },
    {
      title: "通道",
      width: 180,
      render: (_value, record) => (
        <Space orientation="vertical" size={0}>
          <Text>{record.provider}</Text>
          <Text type="secondary" style={{ fontSize: 12 }}>{record.mode}</Text>
        </Space>
      ),
    },
    {
      title: "原始材料",
      width: 220,
      render: (_value, record) => (
        <Space orientation="vertical" size={4}>
          {verificationImageLinks(record)}
          <Space wrap size={4}>
            {record.material_cleaned ? <Tag>已清理</Tag> : null}
            {record.material_expires_at ? <Text type="secondary" style={{ fontSize: 12 }}>保留至 {fmtDate(record.material_expires_at)}</Text> : null}
          </Space>
        </Space>
      ),
    },
    { title: "任务号", dataIndex: "provider_task_id", width: 220, render: (value) => value ? <Text code>{value}</Text> : "-" },
    { title: "上游返回", dataIndex: "provider_response", width: 280, render: providerResponseText },
    { title: "失败原因", dataIndex: "reject_reason", render: (value) => value || "-" },
  ]

  const ticketColumns: TableColumnsType<NonNullable<AdminUser["tickets"]>[number]> = [
    {
      title: "工单",
      width: 260,
      render: (_value, record) => (
        <Space orientation="vertical" size={0}>
          <Button type="link" style={{ padding: 0 }} onClick={() => navigate(`/admin/tickets/${record.id}`)}>
            {record.subject}
          </Button>
          <Text type="secondary" style={{ fontSize: 12 }}>{record.ticket_no}</Text>
        </Space>
      ),
    },
    { title: "状态", dataIndex: "status", width: 100, render: ticketTag },
    { title: "优先级", dataIndex: "priority", width: 90, render: ticketPriorityTag },
    { title: "部门", dataIndex: "department_name", width: 120, render: (value) => value || "-" },
    { title: "关联实例", dataIndex: "instance_id", width: 100, render: (value) => value ? `#${value}` : "-" },
    { title: "未读", dataIndex: "admin_unread_count", width: 90, render: (value) => value > 0 ? <Tag color="red">{value}</Tag> : "-" },
    { title: "评分", dataIndex: "satisfaction_rating", width: 90, render: (value) => value ? `${value} 星` : "-" },
    { title: "最后消息", dataIndex: "last_message_at", width: 170, render: fmtDate },
  ]

  const orderColumns: TableColumnsType<AdminServiceOrder> = [
    { title: "订单号", dataIndex: "out_order_no", width: 190 },
    { title: "状态", dataIndex: "status", width: 110, render: orderTag },
    { title: "实付", dataIndex: "paid_amount", width: 120, align: "right", render: yuan },
    {
      title: "实例",
      dataIndex: "instances",
      width: 220,
      render: (items: AdminServiceOrder["instances"]) => (
        <Space orientation="vertical" size={0}>
          {items.length ? items.map((item) => (
            <Button key={item.id} type="link" style={{ padding: 0, height: 20 }} onClick={() => navigate(`/admin/users/${user.id}/instances/${item.id}`)}>
              {item.hostname || `实例 #${item.id}`}
            </Button>
          )) : "-"}
        </Space>
      ),
    },
    { title: "退订", dataIndex: "refund_policy", width: 180, render: (policy) => policy?.reason || "-" },
    { title: "创建时间", dataIndex: "created_at", width: 170, render: fmtDate },
  ]

  const timelineColumns: TableColumnsType<UserTimelineItem> = [
    { title: "时间", dataIndex: "at", width: 170, render: fmtDate },
    { title: "类型", dataIndex: "type", width: 90, render: (value) => <Tag>{value}</Tag> },
    { title: "事件", dataIndex: "title", width: 220, render: (value) => <Text strong>{value}</Text> },
    { title: "说明", dataIndex: "description", render: (value) => value || "-" },
  ]

  const summaryColumns: TableColumnsType<SummaryRow> = [
    { title: "项目", dataIndex: "label" },
    { title: "数量", dataIndex: "value", width: 120, align: "right" },
    { title: "补充", dataIndex: "extra", width: 140, align: "right", render: (value) => value || "-" },
  ]

  return (
    <Space orientation="vertical" size={20} style={{ width: "100%" }}>
      <Modal
        title="以用户身份打开前台"
        open={impersonationPath !== null}
        okText="生成只读会话"
        cancelText="取消"
        confirmLoading={impersonating}
        okButtonProps={{ disabled: !impersonationReason.trim() }}
        onCancel={() => {
          if (!impersonating) {
            setImpersonationPath(null)
            setImpersonationReason("")
          }
        }}
        onOk={() => {
          if (impersonationPath) void openAsUser(impersonationPath)
        }}
      >
        <Input.TextArea
          value={impersonationReason}
          maxLength={500}
          showCount
          autoSize={{ minRows: 3, maxRows: 6 }}
          placeholder="填写本次代办原因"
          onChange={(event) => setImpersonationReason(event.target.value)}
        />
      </Modal>
      <Row gutter={[16, 16]} align="bottom" justify="space-between">
        <Col>
          <Button type="link" icon={<ArrowLeftOutlined />} style={{ paddingLeft: 0 }} onClick={() => navigate("/admin/users")}>
            返回用户列表
          </Button>
          <Space align="center" size={12}>
            <Avatar size={48} src={user.avatar || undefined} icon={<UserOutlined />}>
              {(user.nickname || user.username).charAt(0).toUpperCase()}
            </Avatar>
            <Space orientation="vertical" size={2}>
              <Title level={3} style={{ margin: 0 }}>{user.nickname || user.username}</Title>
              <Space wrap>
                <Tag color={roleMeta.color}>{roleMeta.label}</Tag>
                <Tag color={userStatusMeta?.color || "default"}>{userStatusMeta?.label || user.status}</Tag>
                <Text type="secondary">ID {user.id} · @{user.username}</Text>
              </Space>
            </Space>
          </Space>
        </Col>
        <Col>
          <Space wrap>
            <Button icon={<ReloadOutlined />} onClick={() => {
              void reloadUser()
              if (["instances", "resource-profile"].includes(activeTab)) void reloadInstances()
              if (["finance", "risk", "timeline", "balance-audit"].includes(activeTab)) void reloadBalanceLogs()
              if (["orders", "membership", "risk", "timeline", "order-analysis"].includes(activeTab)) void reloadOrders()
            }}>
              刷新
            </Button>
            <Button type="primary" icon={<SaveOutlined />} loading={saving} onClick={handleSave}>保存资料</Button>
          </Space>
        </Col>
      </Row>

      <Row gutter={[16, 16]}>
        <Col xs={24} sm={12} xl={6}>
          <Card variant="outlined"><Statistic title="账户余额" value={yuan(user.balance)} prefix={<WalletOutlined />} /></Card>
        </Col>
        <Col xs={24} sm={12} xl={6}>
          <Card variant="outlined"><Statistic title="实例总数" value={instanceStats.total} prefix={<CloudServerOutlined />} /></Card>
        </Col>
        <Col xs={24} sm={12} xl={6}>
          <Card variant="outlined"><Statistic title="累计消费" value={yuan(user.membership?.total_spent ?? 0)} prefix={<DollarOutlined />} /></Card>
        </Col>
        <Col xs={24} sm={12} xl={6}>
          <Card variant="outlined"><Statistic title="最近登录" value={fmtDate(user.last_login_at)} /></Card>
        </Col>
      </Row>

      <Card variant="outlined" styles={{ body: { paddingTop: 8 } }}>
        <Tabs
          activeKey={activeTab}
          onChange={setActiveTab}
          items={[
            {
              key: "overview",
              label: "概览",
              children: (
                <Space orientation="vertical" size={16} style={{ width: "100%" }}>
                  <Row gutter={[16, 16]}>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="账户余额" value={yuan(user.balance)} prefix={<WalletOutlined />} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="实例总数" value={user.stats?.instances_total ?? instanceStats.total} prefix={<CloudServerOutlined />} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="订单数" value={user.stats?.orders_total ?? orders.length} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="工单未读" value={user.stats?.tickets_unread ?? 0} /></Card></Col>
                  </Row>
                  <Row gutter={[16, 16]}>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="账户摘要">
                        <Descriptions column={1} size="small">
                          <Descriptions.Item label="用户 ID">#{user.id}</Descriptions.Item>
                          <Descriptions.Item label="用户名">@{user.username}</Descriptions.Item>
                          <Descriptions.Item label="昵称">{user.nickname || "-"}</Descriptions.Item>
                          <Descriptions.Item label="角色"><Tag color={roleMeta.color}>{roleMeta.label}</Tag></Descriptions.Item>
                          <Descriptions.Item label="状态"><Tag color={userStatusMeta?.color || "default"}>{userStatusMeta?.label || user.status}</Tag></Descriptions.Item>
                          <Descriptions.Item label="注册时间">{fmtDate(user.created_at)}</Descriptions.Item>
                          <Descriptions.Item label="最近登录">{fmtDate(user.last_login_at)}</Descriptions.Item>
                        </Descriptions>
                      </Card>
                    </Col>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="认证与绑定">
                        <Descriptions column={1} size="small">
                          <Descriptions.Item label="实名认证">{user.id_card_verified === "verified" ? "已认证" : user.id_card_verified === "pending" ? "认证中" : user.id_card_verified === "rejected" ? "已拒绝" : "未认证"}</Descriptions.Item>
                          <Descriptions.Item label="真实姓名">{user.real_name_full || user.real_name || "-"}</Descriptions.Item>
                          <Descriptions.Item label="身份证号"><Text copyable={!!(user.id_card_no_full || user.id_card_no)}>{user.id_card_no_full || user.id_card_no || "-"}</Text></Descriptions.Item>
                          <Descriptions.Item label="邮箱">{user.email || "-"}</Descriptions.Item>
                          <Descriptions.Item label="邮箱验证">{user.is_email_verified ? "已验证" : "未验证"}</Descriptions.Item>
                          <Descriptions.Item label="手机">{user.phone || "-"}</Descriptions.Item>
                          <Descriptions.Item label="手机验证">{user.is_phone_verified ? "已验证" : "未验证"}</Descriptions.Item>
                        </Descriptions>
                      </Card>
                    </Col>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="会员与权益">
                        <Descriptions column={1} size="small">
                          <Descriptions.Item label="会员等级">{user.membership?.member_level ? `LV${user.membership.member_level.level} ${user.membership.member_level.name}` : "-"}</Descriptions.Item>
                          <Descriptions.Item label="等级模式">{user.membership?.member_level_locked ? "手动锁定" : "自动升级"}</Descriptions.Item>
                          <Descriptions.Item label="代理档位">{agentTierLabel(user.membership?.agent_tier)}</Descriptions.Item>
                          <Descriptions.Item label="累计消费">{yuan(user.membership?.total_spent ?? 0)}</Descriptions.Item>
                          <Descriptions.Item label="可用积分">{user.membership?.available_points ?? 0}</Descriptions.Item>
                          <Descriptions.Item label="邀请码">{user.invite_code_quota?.current_code ? <Text code>{user.invite_code_quota.current_code}</Text> : "-"}</Descriptions.Item>
                        </Descriptions>
                      </Card>
                    </Col>
                  </Row>
                </Space>
              ),
            },
            {
              key: "basic",
              label: "基础资料",
              children: (
                <Row gutter={[16, 16]}>
                  <Col xs={24} xl={8}>
                    <Card variant="outlined" title="账号身份">
                      <Descriptions column={1} size="small">
                        <Descriptions.Item label="用户 ID">#{user.id}</Descriptions.Item>
                        <Descriptions.Item label="用户名"><Text copyable>@{user.username}</Text></Descriptions.Item>
                        <Descriptions.Item label="昵称">{user.nickname || "-"}</Descriptions.Item>
                        <Descriptions.Item label="角色"><Tag color={roleMeta.color}>{roleMeta.label}</Tag></Descriptions.Item>
                        <Descriptions.Item label="状态"><Tag color={userStatusMeta?.color || "default"}>{userStatusMeta?.label || user.status}</Tag></Descriptions.Item>
                        <Descriptions.Item label="是否有密码">{user.has_password ? "已设置" : "未设置"}</Descriptions.Item>
                        <Descriptions.Item label="注册时间">{fmtDate(user.created_at)}</Descriptions.Item>
                        <Descriptions.Item label="最近登录">{fmtDate(user.last_login_at)}</Descriptions.Item>
                      </Descriptions>
                    </Card>
                  </Col>
                  <Col xs={24} xl={8}>
                    <Card variant="outlined" title="联系绑定">
                      <Descriptions column={1} size="small">
                        <Descriptions.Item label="邮箱"><Text copyable={!!user.email}>{user.email || "-"}</Text></Descriptions.Item>
                        <Descriptions.Item label="邮箱验证">{user.is_email_verified ? <Tag color="green">已验证</Tag> : <Tag>未验证</Tag>}</Descriptions.Item>
                        <Descriptions.Item label="手机"><Text copyable={!!user.phone}>{user.phone || "-"}</Text></Descriptions.Item>
                        <Descriptions.Item label="手机验证">{user.is_phone_verified ? <Tag color="green">已验证</Tag> : <Tag>未验证</Tag>}</Descriptions.Item>
                        <Descriptions.Item label="实名状态">{user.id_card_verified === "verified" ? <Tag color="green">已认证</Tag> : user.id_card_verified === "pending" ? <Tag color="processing">认证中</Tag> : user.id_card_verified === "rejected" ? <Tag color="red">已拒绝</Tag> : <Tag>未认证</Tag>}</Descriptions.Item>
                      </Descriptions>
                    </Card>
                  </Col>
                  <Col xs={24} xl={8}>
                    <Card variant="outlined" title="实名原始资料">
                      <Descriptions column={1} size="small">
                        <Descriptions.Item label="真实姓名"><Text copyable={!!(user.real_name_full || user.real_name)}>{user.real_name_full || user.real_name || "-"}</Text></Descriptions.Item>
                        <Descriptions.Item label="身份证号"><Text copyable={!!(user.id_card_no_full || user.id_card_no)}>{user.id_card_no_full || user.id_card_no || "-"}</Text></Descriptions.Item>
                        <Descriptions.Item label="证件材料">{verificationImageLinks(user)}</Descriptions.Item>
                        <Descriptions.Item label="审核备注">{user.id_card_verify_remark || "-"}</Descriptions.Item>
                      </Descriptions>
                    </Card>
                  </Col>
                </Row>
              ),
            },
            {
              key: "membership",
              label: "会员权益",
              children: (
                <Space orientation="vertical" size={16} style={{ width: "100%" }}>
                  <Row gutter={[16, 16]}>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="累计消费" value={yuan(user.membership?.total_spent ?? 0)} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="累计积分" value={user.membership?.total_points ?? 0} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="可用积分" value={user.membership?.available_points ?? 0} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="已支付订单" value={orderStats.paid} suffix="单" /></Card></Col>
                  </Row>
                  <Row gutter={[16, 16]}>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="会员档案">
                        <Descriptions column={1} size="small">
                          <Descriptions.Item label="会员等级">{user.membership?.member_level ? `LV${user.membership.member_level.level} ${user.membership.member_level.name}` : "-"}</Descriptions.Item>
                          <Descriptions.Item label="升级模式">{user.membership?.member_level_locked ? "手动锁定" : "自动升级"}</Descriptions.Item>
                          <Descriptions.Item label="升级时间">{fmtDate(user.membership?.upgraded_at)}</Descriptions.Item>
                          <Descriptions.Item label="代理档位">{agentTierLabel(user.membership?.agent_tier)}</Descriptions.Item>
                        </Descriptions>
                      </Card>
                    </Col>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="权益额度">
                        <Descriptions column={1} size="small">
                          <Descriptions.Item label="全额退订">{user.refund_quota?.unlimited ? "不限" : `${user.refund_quota?.remaining ?? 0} / ${user.refund_quota?.limit ?? 0}`}</Descriptions.Item>
                          <Descriptions.Item label="邀请码修改">{`${user.invite_code_quota?.remaining ?? 0} / ${user.invite_code_quota?.limit ?? 3}`}</Descriptions.Item>
                          <Descriptions.Item label="实名认证次数">{`${user.verification_quota?.remaining_total ?? 0} 次剩余`}</Descriptions.Item>
                          <Descriptions.Item label="实名付费购买">{user.verification_quota?.purchase_enabled ? "允许" : "关闭"}</Descriptions.Item>
                        </Descriptions>
                      </Card>
                    </Col>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="关联身份">
                        <Descriptions column={1} size="small">
                          <Descriptions.Item label="当前邀请码">{user.invite_code_quota?.current_code ? <Text code copyable>{user.invite_code_quota.current_code}</Text> : "-"}</Descriptions.Item>
                          <Descriptions.Item label="历史邀请码">{user.invite_codes?.length ?? 0} 个</Descriptions.Item>
                          <Descriptions.Item label="邀请码日志">{user.invite_code_logs?.length ?? 0} 条</Descriptions.Item>
                          <Descriptions.Item label="订单实付合计">{yuan(orderStats.paidAmount)}</Descriptions.Item>
                        </Descriptions>
                      </Card>
                    </Col>
                  </Row>
                </Space>
              ),
            },
            {
              key: "risk",
              label: "风控画像",
              children: (
                <Space orientation="vertical" size={16} style={{ width: "100%" }}>
                  <Row gutter={[16, 16]}>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="风险项" value={riskItems.filter((item) => item.level !== "ok").length} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="失败资源" value={orderStats.resourceFailed} styles={{ content: { color: orderStats.resourceFailed > 0 ? "#ff4d4f" : undefined } }} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="后台未读工单" value={user.stats?.tickets_unread ?? 0} styles={{ content: { color: (user.stats?.tickets_unread ?? 0) > 0 ? "#ff4d4f" : undefined } }} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="7天内到期实例" value={instanceStats.dueSoon} styles={{ content: { color: instanceStats.dueSoon > 0 ? "#faad14" : undefined } }} /></Card></Col>
                  </Row>
                  <Row gutter={[16, 16]}>
                    {riskItems.map((item) => (
                      <Col xs={24} xl={8} key={item.key}>
                        <Card variant="outlined" title={<Space>{item.title}{riskTag(item.level)}</Space>}>
                          <Paragraph type="secondary" style={{ marginBottom: 0 }}>{item.detail}</Paragraph>
                        </Card>
                      </Col>
                    ))}
                  </Row>
                </Space>
              ),
            },
            {
              key: "resource-profile",
              label: "资源画像",
              children: (
                <Space orientation="vertical" size={16} style={{ width: "100%" }}>
                  <Row gutter={[16, 16]}>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="公网实例" value={resourceProfile.publicIpCount} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="NAT 实例" value={resourceProfile.natCount} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="自动续费" value={resourceProfile.autoRenewCount} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="下期续费合计" value={yuan(resourceProfile.monthlyAmount)} /></Card></Col>
                  </Row>
                  <Row gutter={[16, 16]}>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="按实例状态">
                        <Table rowKey="key" size="small" columns={summaryColumns} dataSource={resourceProfile.byStatus} pagination={false} locale={{ emptyText: <Empty description="暂无数据" /> }} />
                      </Card>
                    </Col>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="按产品">
                        <Table rowKey="key" size="small" columns={summaryColumns} dataSource={resourceProfile.byProduct} pagination={{ pageSize: 6, showSizeChanger: false }} />
                      </Card>
                    </Col>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="按产品组">
                        <Table rowKey="key" size="small" columns={summaryColumns} dataSource={resourceProfile.byGroup} pagination={{ pageSize: 6, showSizeChanger: false }} />
                      </Card>
                    </Col>
                  </Row>
                </Space>
              ),
            },
            {
              key: "order-analysis",
              label: "订单分析",
              children: (
                <Space orientation="vertical" size={16} style={{ width: "100%" }}>
                  <Row gutter={[16, 16]}>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="订单总数" value={orderStats.total} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="已支付" value={orderStats.paid} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="优惠合计" value={yuan(orderAnalysis.discountAmount)} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="可退金额合计" value={yuan(orderAnalysis.refundableAmount)} /></Card></Col>
                  </Row>
                  <Row gutter={[16, 16]}>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="订单状态">
                        <Table rowKey="key" size="small" columns={summaryColumns} dataSource={orderAnalysis.byStatus} pagination={false} locale={{ emptyText: <Empty description="暂无数据" /> }} />
                      </Card>
                    </Col>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="退订状态">
                        <Table rowKey="key" size="small" columns={summaryColumns} dataSource={orderAnalysis.byRefund} pagination={false} locale={{ emptyText: <Empty description="暂无退订记录" /> }} />
                      </Card>
                    </Col>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="资源处理">
                        <Table rowKey="key" size="small" columns={summaryColumns} dataSource={orderAnalysis.byResource} pagination={false} locale={{ emptyText: <Empty description="暂无资源处理记录" /> }} />
                      </Card>
                    </Col>
                  </Row>
                </Space>
              ),
            },
            {
              key: "balance-audit",
              label: "余额审计",
              children: (
                <Space orientation="vertical" size={16} style={{ width: "100%" }}>
                  <Row gutter={[16, 16]}>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="当前余额" value={yuan(user.balance)} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="近百条收入" value={yuan(balanceStats.income)} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="近百条支出" value={yuan(balanceStats.outcome)} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="管理调账净额" value={yuan(balanceStats.adminAdjust)} /></Card></Col>
                  </Row>
                  <Row gutter={[16, 16]}>
                    <Col xs={24} xl={10}>
                      <Card variant="outlined" title="流水类型汇总">
                        <Table rowKey="key" size="small" columns={summaryColumns} dataSource={balanceAudit} pagination={false} locale={{ emptyText: <Empty description="暂无流水" /> }} />
                      </Card>
                    </Col>
                    <Col xs={24} xl={14}>
                      <Card variant="outlined" title="最近流水">
                        <Table rowKey="id" size="small" loading={logsLoading} columns={balanceColumns} dataSource={balanceLogs.slice(0, 8)} pagination={false} scroll={{ x: 900 }} />
                      </Card>
                    </Col>
                  </Row>
                </Space>
              ),
            },
            {
              key: "verification-audit",
              label: "实名审计",
              children: (
                <Space orientation="vertical" size={16} style={{ width: "100%" }}>
                  <Row gutter={[16, 16]}>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="实名记录" value={verificationAudit.total} suffix="条" /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="有材料记录" value={verificationAudit.withMaterial} suffix="条" /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="已清理材料" value={verificationAudit.cleaned} suffix="条" /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="最近提交" value={fmtDate(verificationAudit.latest)} /></Card></Col>
                  </Row>
                  <Row gutter={[16, 16]}>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="按状态">
                        <Table rowKey="key" size="small" columns={summaryColumns} dataSource={verificationAudit.byStatus} pagination={false} locale={{ emptyText: <Empty description="暂无实名记录" /> }} />
                      </Card>
                    </Col>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="按通道">
                        <Table rowKey="key" size="small" columns={summaryColumns} dataSource={verificationAudit.byProvider} pagination={false} locale={{ emptyText: <Empty description="暂无实名通道" /> }} />
                      </Card>
                    </Col>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="当前实名资料">
                        <Descriptions column={1} size="small">
                          <Descriptions.Item label="状态">{user.id_card_verified || "-"}</Descriptions.Item>
                          <Descriptions.Item label="姓名"><Text copyable={!!(user.real_name_full || user.real_name)}>{user.real_name_full || user.real_name || "-"}</Text></Descriptions.Item>
                          <Descriptions.Item label="身份证"><Text copyable={!!(user.id_card_no_full || user.id_card_no)}>{user.id_card_no_full || user.id_card_no || "-"}</Text></Descriptions.Item>
                          <Descriptions.Item label="材料">{verificationImageLinks(user)}</Descriptions.Item>
                        </Descriptions>
                      </Card>
                    </Col>
                  </Row>
                </Space>
              ),
            },
            {
              key: "ticket-profile",
              label: "工单画像",
              children: (
                <Space orientation="vertical" size={16} style={{ width: "100%" }}>
                  <Row gutter={[16, 16]}>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="最近工单" value={user.tickets?.length ?? 0} suffix="条" /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="进行中" value={user.stats?.tickets_open ?? 0} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="后台未读" value={user.stats?.tickets_unread ?? 0} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="平均评分" value={ticketProfile.averageRating} /></Card></Col>
                  </Row>
                  <Row gutter={[16, 16]}>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="按状态">
                        <Table rowKey="key" size="small" columns={summaryColumns} dataSource={ticketProfile.byStatus} pagination={false} locale={{ emptyText: <Empty description="暂无工单" /> }} />
                      </Card>
                    </Col>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="按优先级">
                        <Table rowKey="key" size="small" columns={summaryColumns} dataSource={ticketProfile.byPriority} pagination={false} locale={{ emptyText: <Empty description="暂无优先级数据" /> }} />
                      </Card>
                    </Col>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="按部门">
                        <Table rowKey="key" size="small" columns={summaryColumns} dataSource={ticketProfile.byDepartment} pagination={false} locale={{ emptyText: <Empty description="暂无部门数据" /> }} />
                      </Card>
                    </Col>
                  </Row>
                </Space>
              ),
            },
            {
              key: "timeline",
              label: "时间线",
              children: (
                <Card variant="outlined" title="用户关键时间线">
                  <Table
                    rowKey="key"
                    columns={timelineColumns}
                    dataSource={timelineItems}
                    pagination={{ pageSize: 12 }}
                    scroll={{ x: 900 }}
                    locale={{ emptyText: <Empty description="暂无时间线记录" /> }}
                  />
                </Card>
              ),
            },
            {
              key: "operations",
              label: "操作入口",
              children: (
                <Row gutter={[16, 16]}>
                  <Col xs={24} xl={8}>
                    <Card variant="outlined" title="前台代办">
                      <Space orientation="vertical" size={12} style={{ width: "100%" }}>
                        <Button block type="primary" icon={<LoginOutlined />} disabled={!canImpersonate} onClick={() => setImpersonationPath("/dashboard")}>打开用户控制台</Button>
                        <Button block icon={<CloudServerOutlined />} disabled={!canImpersonate} onClick={() => setImpersonationPath("/control/server")}>打开用户实例页</Button>
                        <Button block icon={<WalletOutlined />} disabled={!canImpersonate} onClick={() => setImpersonationPath("/finance")}>打开用户财务页</Button>
                      </Space>
                    </Card>
                  </Col>
                  <Col xs={24} xl={8}>
                    <Card variant="outlined" title="后台跳转">
                      <Space orientation="vertical" size={12} style={{ width: "100%" }}>
                        <Button block onClick={() => navigate(`/admin/tickets?user_id=${user.id}`)}>查看全部工单</Button>
                        <Button block onClick={() => setActiveTab("instances")}>查看用户实例</Button>
                        <Button block onClick={() => setActiveTab("orders")}>查看服务订单</Button>
                        <Button block onClick={() => setActiveTab("finance")}>查看余额流水</Button>
                      </Space>
                    </Card>
                  </Col>
                  <Col xs={24} xl={8}>
                    <Card variant="outlined" title="高危操作">
                      <Space orientation="vertical" size={12} style={{ width: "100%" }}>
                        <Popconfirm title={user.status === "banned" ? "确认解封该用户？" : "确认封禁该用户？"} okText="确认" cancelText="取消" disabled={isSelf} onConfirm={handleBanToggle}>
                          <Button block danger={user.status !== "banned"} icon={user.status === "banned" ? <UnlockOutlined /> : <StopOutlined />} disabled={isSelf}>
                            {user.status === "banned" ? "解封用户" : "封禁用户"}
                          </Button>
                        </Popconfirm>
                        <Button block icon={<KeyOutlined />} onClick={() => setActiveTab("security")}>重置密码</Button>
                        <Text type="secondary">高危操作仍需要进入对应卡片确认，避免误触。</Text>
                      </Space>
                    </Card>
                  </Col>
                </Row>
              ),
            },
            {
              key: "profile",
              label: "资料编辑",
              children: (
                <Row gutter={[16, 16]}>
                  <Col xs={24} xl={16}>
                    <Form form={form} layout="vertical" initialValues={formValues}>
                      <Row gutter={16}>
                        <Col xs={24} md={12}><Form.Item label="昵称" name="nickname"><Input /></Form.Item></Col>
                        <Col xs={24} md={12}><Form.Item label="用户名"><Input value={user.username} disabled /></Form.Item></Col>
                        <Col xs={24} md={12}><Form.Item label="邮箱" name="email"><Input /></Form.Item></Col>
                        <Col xs={24} md={12}><Form.Item label="手机号" name="phone"><Input /></Form.Item></Col>
                        <Col xs={24} md={12}><Form.Item label="身份证号" name="id_card_no"><Input maxLength={18} /></Form.Item></Col>
                        <Col xs={24} md={12}>
                          <Form.Item label="角色" name="role">
                            <Select
                              disabled={!canEditRole || isSelf}
                              options={[
                                { value: "user", label: "普通用户" },
                                { value: "admin", label: "管理员" },
                                { value: "super_admin", label: "超级管理员" },
                              ]}
                            />
                          </Form.Item>
                        </Col>
                        <Col xs={24} md={12}>
                          <Form.Item label="状态" name="status">
                            <Select
                              disabled={isSelf}
                              options={[
                                { value: "active", label: "正常" },
                                { value: "inactive", label: "未激活" },
                                { value: "banned", label: "已封禁" },
                              ]}
                            />
                          </Form.Item>
                        </Col>
                        <Col xs={24} md={12}>
                          <Form.Item label="会员等级" name="member_level_id">
                            <Select
                              allowClear
                              options={memberLevels.map((level) => ({ value: level.id, label: `LV${level.level} ${level.name}` }))}
                            />
                          </Form.Item>
                        </Col>
                        <Col xs={24} md={12}><Form.Item label="会员等级模式" name="member_level_locked" valuePropName="checked"><Switch checkedChildren="手动锁定" unCheckedChildren="自动" /></Form.Item></Col>
                        <Col xs={24} md={12}><Form.Item label="代理/伙伴档位" name="agent_tier"><Select allowClear options={AGENT_TIER_OPTIONS} /></Form.Item></Col>
                        <Col xs={24} md={12}><Form.Item label="邮箱验证" name="is_email_verified" valuePropName="checked"><Switch checkedChildren="已验证" unCheckedChildren="未验证" /></Form.Item></Col>
                        <Col xs={24} md={12}><Form.Item label="手机验证" name="is_phone_verified" valuePropName="checked"><Switch checkedChildren="已验证" unCheckedChildren="未验证" /></Form.Item></Col>
                        <Col xs={24} md={12}><Form.Item label="实名认证" name="id_card_verified"><Select options={[
                          { value: "unverified", label: "未认证" },
                          { value: "pending", label: "认证中" },
                          { value: "verified", label: "已认证" },
                          { value: "rejected", label: "已拒绝" },
                        ]} /></Form.Item></Col>
                        <Col xs={24} md={12}><Form.Item label="真实姓名" name="real_name"><Input maxLength={50} /></Form.Item></Col>
                      </Row>
                    </Form>
                  </Col>
                  <Col xs={24} xl={8}>
                    <Space orientation="vertical" size={16} style={{ width: "100%" }}>
                      <Card variant="outlined" title="账户摘要">
                        <Descriptions column={1} size="small">
                          <Descriptions.Item label="实名认证">{user.id_card_verified === "verified" ? "已认证" : user.id_card_verified === "pending" ? "认证中" : user.id_card_verified === "rejected" ? "已拒绝" : "未认证"}</Descriptions.Item>
                          <Descriptions.Item label="真实姓名">{user.real_name_full || user.real_name || "-"}</Descriptions.Item>
                          <Descriptions.Item label="邮箱">{user.email || "-"}</Descriptions.Item>
                          <Descriptions.Item label="手机">{user.phone || "-"}</Descriptions.Item>
                          <Descriptions.Item label="身份证号"><Text copyable={!!(user.id_card_no_full || user.id_card_no)}>{user.id_card_no_full || user.id_card_no || "-"}</Text></Descriptions.Item>
                          <Descriptions.Item label="会员等级">{user.membership?.member_level ? `LV${user.membership.member_level.level} ${user.membership.member_level.name}` : "-"}</Descriptions.Item>
                          <Descriptions.Item label="等级模式">{user.membership?.member_level_locked ? "手动锁定" : "自动升级"}</Descriptions.Item>
                          <Descriptions.Item label="代理档位">{agentTierLabel(user.membership?.agent_tier)}</Descriptions.Item>
                          <Descriptions.Item label="可用积分">{user.membership?.available_points ?? 0}</Descriptions.Item>
                          <Descriptions.Item label="注册时间">{fmtDate(user.created_at)}</Descriptions.Item>
                        </Descriptions>
                      </Card>
                      <Card variant="outlined" title="账户操作">
                        <Space orientation="vertical" size={12} style={{ width: "100%" }}>
                          <Popconfirm title={user.status === "banned" ? "确认解封该用户？" : "确认封禁该用户？"} okText="确认" cancelText="取消" disabled={isSelf} onConfirm={handleBanToggle}>
                            <Button block danger={user.status !== "banned"} icon={user.status === "banned" ? <UnlockOutlined /> : <StopOutlined />} disabled={isSelf}>
                              {user.status === "banned" ? "解封用户" : "封禁用户"}
                            </Button>
                          </Popconfirm>
                          <Button block icon={<LoginOutlined />} disabled={!canImpersonate} onClick={() => setImpersonationPath("/dashboard")}>
                            一键登录前台
                          </Button>
                        </Space>
                      </Card>
                    </Space>
                  </Col>
                </Row>
              ),
            },
            {
              key: "verification",
              label: "实名认证",
              children: (
                <Space orientation="vertical" size={16} style={{ width: "100%" }}>
                  <Row gutter={[16, 16]}>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="免费剩余" value={user.verification_quota?.free_remaining ?? 0} suffix="次" /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="已购剩余" value={user.verification_quota?.paid_remaining ?? 0} suffix="次" /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="已用付费" value={user.verification_quota?.paid_used ?? 0} suffix="次" /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="单次价格" value={yuan(user.verification_quota?.price_cents ?? 0)} /></Card></Col>
                  </Row>
                  <Row gutter={[16, 16]}>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="实名状态">
                        <Descriptions column={1} size="small">
                          <Descriptions.Item label="状态">{user.id_card_verified === "verified" ? <Tag color="green">已认证</Tag> : user.id_card_verified === "pending" ? <Tag color="processing">认证中</Tag> : user.id_card_verified === "rejected" ? <Tag color="red">已拒绝</Tag> : <Tag>未认证</Tag>}</Descriptions.Item>
                          <Descriptions.Item label="真实姓名"><Text copyable={!!(user.real_name_full || user.real_name)}>{user.real_name_full || user.real_name || "-"}</Text></Descriptions.Item>
                          <Descriptions.Item label="身份证号"><Text copyable={!!(user.id_card_no_full || user.id_card_no)}>{user.id_card_no_full || user.id_card_no || "-"}</Text></Descriptions.Item>
                          <Descriptions.Item label="证件材料">{verificationImageLinks(user)}</Descriptions.Item>
                          <Descriptions.Item label="审核备注">{user.id_card_verify_remark || "-"}</Descriptions.Item>
                          <Descriptions.Item label="免费已用">{user.verification_quota?.free_used ?? 0} / {user.verification_quota?.free_quota_per_user ?? 0}</Descriptions.Item>
                          <Descriptions.Item label="已购总数">{user.verification_quota?.paid_purchased ?? 0}</Descriptions.Item>
                          <Descriptions.Item label="总剩余">{user.verification_quota?.remaining_total ?? 0}</Descriptions.Item>
                          <Descriptions.Item label="允许购买">{user.verification_quota?.purchase_enabled ? "允许" : "关闭"}</Descriptions.Item>
                        </Descriptions>
                      </Card>
                    </Col>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="实名次数调整">
                        <Space orientation="vertical" size={12} style={{ width: "100%" }}>
                          <InputNumber
                            min={1}
                            max={1000}
                            precision={0}
                            value={verificationQuotaCount}
                            onChange={(value) => setVerificationQuotaCount(typeof value === "number" ? value : value ? Number(value) : null)}
                            addonAfter="次"
                            style={{ width: "100%" }}
                          />
                          <Input
                            value={verificationQuotaReason}
                            onChange={(event) => setVerificationQuotaReason(event.target.value)}
                            maxLength={200}
                            placeholder="调整原因，必填"
                          />
                          <Space wrap>
                            <Button icon={<PlusCircleOutlined />} loading={adjustingVerificationQuota} onClick={handleAddVerificationQuota}>
                              增加次数
                            </Button>
                            <Button icon={<MinusCircleOutlined />} loading={adjustingVerificationQuota} onClick={handleReduceVerificationQuota}>
                              减少次数
                            </Button>
                            <Popconfirm
                              title="确认将该用户免费已用实名次数重置为 0？"
                              okText="确认重置"
                              cancelText="取消"
                              onConfirm={handleResetVerificationFreeQuota}
                            >
                              <Button danger loading={adjustingVerificationQuota}>重置免费已用</Button>
                            </Popconfirm>
                          </Space>
                          <Text type="secondary">调整的是用户可用实名提交次数，不直接修改实名认证通过状态。</Text>
                        </Space>
                      </Card>
                    </Col>
                    <Col xs={24} xl={8}>
                      <Card variant="outlined" title="实名资料编辑">
                        <Form form={form} layout="vertical" initialValues={formValues}>
                          <Form.Item label="实名认证" name="id_card_verified"><Select options={[
                            { value: "unverified", label: "未认证" },
                            { value: "pending", label: "认证中" },
                            { value: "verified", label: "已认证" },
                            { value: "rejected", label: "已拒绝" },
                          ]} /></Form.Item>
                          <Form.Item label="真实姓名" name="real_name"><Input maxLength={50} /></Form.Item>
                          <Form.Item label="身份证号" name="id_card_no"><Input maxLength={18} /></Form.Item>
                          <Button type="primary" icon={<SaveOutlined />} loading={saving} onClick={handleSave}>保存实名资料</Button>
                        </Form>
                      </Card>
                    </Col>
                  </Row>
                  <Card variant="outlined" title="最近实名认证记录">
                    <Table
                      rowKey="id"
                      columns={verificationColumns}
                      dataSource={user.verification_records ?? []}
                      pagination={{ pageSize: 8 }}
                      scroll={{ x: 1380 }}
                      locale={{ emptyText: <Empty description="暂无实名认证记录" /> }}
                    />
                  </Card>
                </Space>
              ),
            },
            {
              key: "invite",
              label: "邀请码",
              children: (
                <Row gutter={[16, 16]}>
                  <Col xs={24} xl={8}>
                    <Card variant="outlined" title="邀请码额度">
                      <Space orientation="vertical" size={12} style={{ width: "100%" }}>
                        <Statistic title="已用 / 上限" value={`${user.invite_code_quota?.used ?? 0} / ${user.invite_code_quota?.limit ?? 3}`} />
                        <Descriptions column={1} size="small">
                          <Descriptions.Item label="当前邀请码">{user.invite_code_quota?.current_code ? <Text code>{user.invite_code_quota.current_code}</Text> : "-"}</Descriptions.Item>
                          <Descriptions.Item label="基础次数">{user.invite_code_quota?.base_limit ?? 3}</Descriptions.Item>
                          <Descriptions.Item label="额外次数">{user.invite_code_quota?.extra ?? 0}</Descriptions.Item>
                          <Descriptions.Item label="剩余次数">{user.invite_code_quota?.remaining ?? 0}</Descriptions.Item>
                        </Descriptions>
                        <InputNumber
                          min={1}
                          max={100}
                          precision={0}
                          value={inviteQuotaCount}
                          onChange={(value) => setInviteQuotaCount(typeof value === "number" ? value : value ? Number(value) : null)}
                          addonAfter="次"
                          style={{ width: "100%" }}
                        />
                        <Input
                          value={inviteQuotaReason}
                          onChange={(event) => setInviteQuotaReason(event.target.value)}
                          maxLength={200}
                          placeholder="调整原因，必填"
                        />
                        <Space wrap>
                          <Button icon={<PlusCircleOutlined />} loading={adjustingInviteQuota} onClick={handleAddInviteQuota}>
                            增加额外次数
                          </Button>
                          <Popconfirm
                            title="确认将该用户的邀请码已用修改次数重置为 0？"
                            okText="确认重置"
                            cancelText="取消"
                            onConfirm={handleResetInviteQuota}
                          >
                            <Button danger loading={adjustingInviteQuota}>重置已用次数</Button>
                          </Popconfirm>
                        </Space>
                      </Space>
                    </Card>
                  </Col>
                  <Col xs={24} xl={16}>
                    <Space orientation="vertical" size={16} style={{ width: "100%" }}>
                      <Card variant="outlined" title="历史邀请码">
                        <Table rowKey="id" size="small" columns={inviteCodeColumns} dataSource={user.invite_codes ?? []} pagination={false} locale={{ emptyText: <Empty description="暂无历史邀请码" /> }} />
                      </Card>
                      <Card variant="outlined" title="邀请码操作日志">
                        <Table rowKey="id" size="small" columns={inviteLogColumns} dataSource={user.invite_code_logs ?? []} pagination={{ pageSize: 8 }} scroll={{ x: 760 }} locale={{ emptyText: <Empty description="暂无操作日志" /> }} />
                      </Card>
                    </Space>
                  </Col>
                </Row>
              ),
            },
            {
              key: "finance",
              label: "财务管理",
              children: (
                <Row gutter={[16, 16]}>
                  <Col xs={24} xl={8}>
                    <Card variant="outlined" title="余额调整">
                      <Space orientation="vertical" size={12} style={{ width: "100%" }}>
                        <Statistic title="当前余额" value={yuan(user.balance)} prefix={<WalletOutlined />} />
                        <Descriptions column={1} size="small">
                          <Descriptions.Item label="近百条收入">{yuan(balanceStats.income)}</Descriptions.Item>
                          <Descriptions.Item label="近百条支出">{yuan(balanceStats.outcome)}</Descriptions.Item>
                          <Descriptions.Item label="管理调账净额">{yuan(balanceStats.adminAdjust)}</Descriptions.Item>
                          <Descriptions.Item label="最近流水">{fmtDate(balanceStats.latestAt)}</Descriptions.Item>
                        </Descriptions>
                        <InputNumber
                          min={0}
                          precision={2}
                          value={balanceDelta}
                          onChange={(value) => setBalanceDelta(typeof value === "number" ? value : value ? Number(value) : null)}
                          prefix="¥"
                          placeholder="调整金额"
                          style={{ width: "100%" }}
                        />
                        <Input value={balanceReason} onChange={(event) => setBalanceReason(event.target.value)} placeholder="原因备注，可选" />
                        <Space wrap>
                          <Button type="primary" icon={<PlusCircleOutlined />} loading={adjustingBalance} onClick={() => handleAdjustBalance(1)}>充值</Button>
                          <Button danger icon={<MinusCircleOutlined />} loading={adjustingBalance} onClick={() => handleAdjustBalance(-1)}>扣减</Button>
                        </Space>
                      </Space>
                    </Card>
                  </Col>
                  <Col xs={24} xl={16}>
                    <Card
                      variant="outlined"
                      title="余额流水"
                      extra={<Button size="small" icon={<ReloadOutlined />} onClick={() => reloadBalanceLogs()}>刷新</Button>}
                    >
                      <Table rowKey="id" loading={logsLoading} columns={balanceColumns} dataSource={balanceLogs} pagination={{ pageSize: 8 }} scroll={{ x: 900 }} />
                    </Card>
                  </Col>
                </Row>
              ),
            },
            {
              key: "refund",
              label: "退订额度",
              children: (
                <Row gutter={[16, 16]}>
                  <Col xs={24} xl={8}>
                    <Card variant="outlined" title="全额退订名额">
                      <Space orientation="vertical" size={12} style={{ width: "100%" }}>
                        <Statistic
                          title={user.refund_quota?.unlimited ? "代理用户不限次" : "已用 / 上限"}
                          value={user.refund_quota?.unlimited ? "不限" : `${user.refund_quota?.used ?? 0} / ${user.refund_quota?.limit ?? 0}`}
                        />
                        <Descriptions column={1} size="small">
                          <Descriptions.Item label="基础名额">{user.refund_quota?.base_limit ?? 0}</Descriptions.Item>
                          <Descriptions.Item label="额外名额">{user.refund_quota?.extra ?? 0}</Descriptions.Item>
                          <Descriptions.Item label="剩余名额">{user.refund_quota?.unlimited ? "不限" : user.refund_quota?.remaining ?? 0}</Descriptions.Item>
                          <Descriptions.Item label="重置时间">{fmtDate(user.refund_quota?.reset_at)}</Descriptions.Item>
                        </Descriptions>
                      </Space>
                    </Card>
                  </Col>
                  <Col xs={24} xl={8}>
                    <Card variant="outlined" title="额度调整">
                      <Space orientation="vertical" size={12} style={{ width: "100%" }}>
                        <InputNumber
                          min={1}
                          max={100}
                          precision={0}
                          value={refundQuotaCount}
                          onChange={(value) => setRefundQuotaCount(typeof value === "number" ? value : value ? Number(value) : null)}
                          addonAfter="次"
                          style={{ width: "100%" }}
                        />
                        <Input
                          value={refundQuotaReason}
                          onChange={(event) => setRefundQuotaReason(event.target.value)}
                          maxLength={200}
                          placeholder="调整原因，必填"
                        />
                        <Space wrap>
                          <Button icon={<PlusCircleOutlined />} loading={adjustingRefundQuota} onClick={handleAddRefundQuota}>增加名额</Button>
                          <Button icon={<MinusCircleOutlined />} loading={adjustingRefundQuota} onClick={handleReduceRefundQuota}>减少名额</Button>
                          <Popconfirm
                            title="确认将该用户已用全额退订次数重置为 0？"
                            okText="确认重置"
                            cancelText="取消"
                            onConfirm={handleResetRefundQuota}
                          >
                            <Button danger loading={adjustingRefundQuota}>重置次数</Button>
                          </Popconfirm>
                        </Space>
                      </Space>
                    </Card>
                  </Col>
                  <Col xs={24} xl={8}>
                    <Card variant="outlined" title="说明">
                      <Paragraph type="secondary">
                        全额退订额度影响用户自助退订时是否可享受全额退款。代理用户可按规则显示为不限次。
                      </Paragraph>
                      <Paragraph type="secondary">
                        调整和重置需要填写原因，方便后续核对。
                      </Paragraph>
                    </Card>
                  </Col>
                </Row>
              ),
            },
            {
              key: "instances",
              label: "用户实例",
              children: (
                <Space orientation="vertical" size={16} style={{ width: "100%" }}>
                  <Row gutter={[16, 16]}>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="全部实例" value={instanceStats.total} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="运行中" value={instanceStats.active} styles={{ content: { color: "#52c41a" } }} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="已暂停" value={instanceStats.suspended} styles={{ content: { color: "#faad14" } }} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="7天内到期" value={instanceStats.dueSoon} styles={{ content: { color: "#ff4d4f" } }} /></Card></Col>
                  </Row>
                  <Card
                    variant="outlined"
                    title="实例列表"
                    extra={<Button icon={<ReloadOutlined />} onClick={() => reloadInstances()}>刷新实例</Button>}
                  >
                    <Table
                      rowKey="id"
                      loading={instancesLoading}
                      columns={instanceColumns}
                      dataSource={instances}
                      pagination={{ pageSize: 8 }}
                      scroll={{ x: 940 }}
                      locale={{ emptyText: <Empty description="暂无实例" /> }}
                    />
                  </Card>
                </Space>
              ),
            },
            {
              key: "tickets",
              label: "工单",
              children: (
                <Space orientation="vertical" size={16} style={{ width: "100%" }}>
                  <Row gutter={[16, 16]}>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="全部工单" value={user.stats?.tickets_total ?? user.tickets?.length ?? 0} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="进行中" value={user.stats?.tickets_open ?? 0} styles={{ content: { color: "#1677ff" } }} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="后台未读" value={user.stats?.tickets_unread ?? 0} styles={{ content: { color: (user.stats?.tickets_unread ?? 0) > 0 ? "#ff4d4f" : undefined } }} /></Card></Col>
                    <Col xs={24} sm={12} xl={6}><Card variant="outlined"><Statistic title="最近展示" value={user.tickets?.length ?? 0} suffix="条" /></Card></Col>
                  </Row>
                  <Card
                    variant="outlined"
                    title="最近工单"
                    extra={<Button onClick={() => navigate(`/admin/tickets?user_id=${user.id}`)}>查看全部</Button>}
                  >
                    <Table
                      rowKey="id"
                      columns={ticketColumns}
                      dataSource={user.tickets ?? []}
                      pagination={{ pageSize: 10 }}
                      scroll={{ x: 980 }}
                      locale={{ emptyText: <Empty description="暂无工单" /> }}
                    />
                  </Card>
                </Space>
              ),
            },
            {
              key: "orders",
              label: "服务订单",
              children: (
                <Card
                  variant="outlined"
                  title="服务订单"
                  extra={<Button icon={<ReloadOutlined />} onClick={() => reloadOrders()}>刷新订单</Button>}
                >
                  <Paragraph type="secondary">
                    这里按当前用户过滤购买、续费、升级、退订相关订单。退订资源处理仍在后台服务订单中心统一处理。
                  </Paragraph>
                  <Table rowKey="id" loading={ordersLoading} columns={orderColumns} dataSource={orders} pagination={{ pageSize: 10 }} scroll={{ x: 980 }} />
                </Card>
              ),
            },
            {
              key: "security",
              label: "安全",
              children: (
                <Row gutter={[16, 16]}>
                  <Col xs={24} md={12}>
                    <Card variant="outlined" title="重置密码">
                      <Space orientation="vertical" size={12} style={{ width: "100%" }}>
                        <Input.Password value={newPassword} onChange={(event) => setNewPassword(event.target.value)} placeholder="请输入至少 8 位新密码" />
                        <Popconfirm title="确认重置该用户密码？" okText="确认重置" cancelText="取消" onConfirm={handleResetPassword}>
                          <Button icon={<KeyOutlined />} loading={resettingPwd}>重置密码</Button>
                        </Popconfirm>
                        <Text type="secondary">重置后该用户现有会话会被清除。</Text>
                      </Space>
                    </Card>
                  </Col>
                  <Col xs={24} md={12}>
                    <Card variant="outlined" title="快捷登录">
                      <Space orientation="vertical" size={12} style={{ width: "100%" }}>
                        <Text type="secondary">以该用户身份打开前台，用于处理需要前台完整流程的操作。</Text>
                        <Button type="primary" icon={<ThunderboltOutlined />} disabled={!canImpersonate} onClick={() => setImpersonationPath("/dashboard")}>
                          打开用户前台
                        </Button>
                      </Space>
                    </Card>
                  </Col>
                </Row>
              ),
            },
          ]}
        />
      </Card>
    </Space>
  )
}
