import { useState, useEffect, useMemo } from 'react'
import { useNavigate } from 'react-router-dom'
import {
  Input, Button, Empty, message, Modal, Form, Select, Popconfirm, Spin, Pagination,
} from 'antd'
import {
  SearchOutlined, PhoneOutlined, MailOutlined, EditOutlined, PlusOutlined,
  DeleteOutlined, ExportOutlined, CloseOutlined, GlobalOutlined, MessageOutlined,
} from '@ant-design/icons'
import {
  createCustomer, deleteCustomer, exportCustomersCSV, getCustomer, getCustomerTags, getCustomers, updateCustomer,
  type Customer, type CustomerTag, type Session,
} from '@/services/api'
import { useAuth } from '@/stores/auth'

const statusMap: Record<string, { color: string; text: string; dot: string }> = {
  online: { color: '#16a34a', text: '在线', dot: '#16a34a' },
  offline: { color: '#94a3b8', text: '离线', dot: '#94a3b8' },
  busy: { color: '#d97706', text: '忙碌', dot: '#d97706' },
}

const tagColorMap: Record<string, { bg: string; color: string }> = {
  amber: { bg: '#fef3c7', color: '#92400e' },
  green: { bg: '#f0fdf4', color: '#16a34a' },
  blue: { bg: '#dbeafe', color: '#2563eb' },
  cyan: { bg: '#ecfeff', color: '#0891b2' },
  violet: { bg: '#f3e8ff', color: '#7c3aed' },
  rose: { bg: '#fff1f2', color: '#e11d48' },
  orange: { bg: '#fffbeb', color: '#d97706' },
  slate: { bg: '#f1f5f9', color: '#475569' },
  // 兼容历史写死名称
  'VIP客户': { bg: '#fef3c7', color: '#92400e' },
  'VIP': { bg: '#fef3c7', color: '#92400e' },
  '新客户': { bg: '#f0fdf4', color: '#16a34a' },
  '活跃': { bg: '#dbeafe', color: '#2563eb' },
  '沉默': { bg: '#fffbeb', color: '#d97706' },
  '企业客户': { bg: '#ecfeff', color: '#0891b2' },
}

/** 浅底深字头像色，对齐效果图 */
const avatarPalettes = [
  { bg: '#dbeafe', color: '#2563eb' },
  { bg: '#fce7f3', color: '#be185d' },
  { bg: '#ede9fe', color: '#6d28d9' },
  { bg: '#d1fae5', color: '#047857' },
  { bg: '#fef3c7', color: '#b45309' },
  { bg: '#e0e7ff', color: '#4338ca' },
  { bg: '#ffedd5', color: '#c2410c' },
  { bg: '#f0fdf4', color: '#166534' },
]

function parseTags(tagsStr: string): string[] {
  try {
    const parsed = JSON.parse(tagsStr)
    return Array.isArray(parsed) ? parsed : []
  } catch {
    return tagsStr ? tagsStr.split(',').map(t => t.trim()).filter(Boolean) : []
  }
}

function relativeTime(iso?: string | null) {
  if (!iso) return '—'
  const diff = Date.now() - new Date(iso).getTime()
  const mins = Math.floor(diff / 60000)
  if (mins < 1) return '刚刚'
  if (mins < 60) return `${mins} 分钟前`
  const hours = Math.floor(mins / 60)
  if (hours < 24) return `${hours} 小时前`
  const days = Math.floor(hours / 24)
  if (days < 30) return `${days} 天前`
  return new Date(iso).toLocaleDateString('zh-CN')
}

function avatarPalette(name: string) {
  let h = 0
  for (let i = 0; i < name.length; i++) h = name.charCodeAt(i) + ((h << 5) - h)
  return avatarPalettes[Math.abs(h) % avatarPalettes.length]
}

function maskPhone(phone?: string) {
  if (!phone) return '—'
  const digits = phone.replace(/\D/g, '')
  if (digits.length === 11) return `${digits.slice(0, 3)}****${digits.slice(7)}`
  return phone
}

/** 左侧活跃度色条：在线偏亮，沉默偏灰 */
function activityBar(c: Customer): string {
  const tags = parseTags(c.tags)
  if (c.status === 'online') return 'linear-gradient(to top, #93c5fd, #2563eb)'
  if (tags.includes('沉默')) return 'linear-gradient(to top, #f1f5f9, #cbd5e1)'
  if (c.status === 'busy') return 'linear-gradient(to top, #fde68a, #d97706)'
  const t = c.last_contact_at ? Date.now() - new Date(c.last_contact_at).getTime() : Infinity
  if (t < 3600000) return 'linear-gradient(to top, #bfdbfe, #3b82f6)'
  if (t < 86400000) return 'linear-gradient(to top, #e2e8f0, #60a5fa)'
  return 'linear-gradient(to top, #f1f5f9, #cbd5e1)'
}

function sessionTopic(s: Session) {
  if (s.last_message && s.last_message.length > 0 && s.last_message.length <= 12 && !s.last_message.startsWith('http')) {
    return s.last_message
  }
  const map: Record<string, string> = {
    active: '进行中会话', waiting: '等待接入', ended: '已结束会话', archived: '归档会话',
  }
  return map[s.status] || `会话 #${s.id}`
}

const TagPill = ({ tag, catalog }: { tag: string; catalog?: CustomerTag[] }) => {
  const meta = catalog?.find(t => t.name === tag)
  const byColor = meta?.color ? tagColorMap[meta.color] : undefined
  const s = byColor || tagColorMap[tag] || { bg: '#f1f5f9', color: '#475569' }
  const label = tag === 'VIP客户' ? 'VIP' : tag
  return (
    <span
      className="inline-flex items-center px-2 py-0.5 rounded text-[11px] font-medium whitespace-nowrap"
      style={{ backgroundColor: s.bg, color: s.color }}
    >
      {label}
    </span>
  )
}

const StatusDot = ({ status }: { status: string }) => {
  const s = statusMap[status] || statusMap.offline
  return (
    <span className="inline-flex items-center gap-1.5">
      <span className="w-2 h-2 rounded-full shrink-0" style={{ backgroundColor: s.dot }} />
      <span className="text-[12px] whitespace-nowrap" style={{ color: s.color }}>{s.text}</span>
    </span>
  )
}

const Customers = () => {
  const { user } = useAuth()
  const navigate = useNavigate()
  const canDelete = user?.role === 'admin' || user?.role === 'supervisor'
  const [customers, setCustomers] = useState<Customer[]>([])
  const [loading, setLoading] = useState(true)
  const [total, setTotal] = useState(0)
  const [page, setPage] = useState(1)
  const [pageSize, setPageSize] = useState(10)
  const [search, setSearch] = useState('')
  const [exporting, setExporting] = useState(false)
  const [tagFilter, setTagFilter] = useState('all')
  const [selectedCustomer, setSelectedCustomer] = useState<Customer | null>(null)
  const [editingId, setEditingId] = useState<number | null>(null)
  const [historySessions, setHistorySessions] = useState<Session[]>([])
  const [detailLoading, setDetailLoading] = useState(false)
  const [panelOpen, setPanelOpen] = useState(false)
  const [editOpen, setEditOpen] = useState(false)
  const [saving, setSaving] = useState(false)
  const [form] = Form.useForm()
  const [tagCatalog, setTagCatalog] = useState<CustomerTag[]>([])

  useEffect(() => {
    loadCustomers()
  }, [page, pageSize, search])

  useEffect(() => {
    getCustomerTags()
      .then(res => setTagCatalog(Array.isArray(res.data) ? res.data : []))
      .catch(() => setTagCatalog([]))
  }, [])

  const filterChips = useMemo(() => {
    const chips = [{ key: 'all', label: '全部' }]
    tagCatalog.forEach(t => {
      chips.push({
        key: t.name,
        label: t.name === 'VIP客户' ? 'VIP' : t.name,
      })
    })
    return chips
  }, [tagCatalog])

  const tagSelectOptions = useMemo(
    () => tagCatalog.map(t => ({ value: t.name, label: t.name })),
    [tagCatalog],
  )

  const loadCustomers = async () => {
    setLoading(true)
    try {
      const res = await getCustomers({ search, page, pageSize })
      setCustomers(res.list)
      setTotal(res.total)
    } catch {
      setCustomers([])
    } finally {
      setLoading(false)
    }
  }

  const displayed = useMemo(() => {
    if (tagFilter === 'all') return customers
    return customers.filter(c =>
      parseTags(c.tags).some(t => t === tagFilter || (tagFilter === 'VIP客户' && (t === 'VIP' || t === 'VIP客户'))),
    )
  }, [customers, tagFilter])

  const openDetail = async (record: Customer) => {
    setSelectedCustomer(record)
    setPanelOpen(true)
    setHistorySessions([])
    setDetailLoading(true)
    try {
      const res = await getCustomer(record.id)
      setSelectedCustomer(res.data.customer)
      setHistorySessions(Array.isArray(res.data.sessions) ? res.data.sessions : [])
    } catch {
      // keep list snapshot
    } finally {
      setDetailLoading(false)
    }
  }

  const closePanel = () => {
    setPanelOpen(false)
  }

  const openCreate = () => {
    setEditingId(null)
    form.resetFields()
    form.setFieldsValue({ status: 'offline', source: '手动录入', tags: [] })
    setEditOpen(true)
  }

  const openEdit = (customer: Customer) => {
    setEditingId(customer.id)
    form.setFieldsValue({
      name: customer.name,
      phone: customer.phone,
      email: customer.email,
      source: customer.source,
      status: customer.status,
      tags: parseTags(customer.tags),
    })
    setEditOpen(true)
  }

  const handleSave = async (values: {
    name: string; phone?: string; email?: string; source?: string; status?: string; tags?: string[]
  }) => {
    setSaving(true)
    try {
      const payload = {
        name: values.name.trim(),
        phone: values.phone?.trim() || '',
        email: values.email?.trim() || '',
        source: values.source?.trim() || '手动录入',
        status: values.status || 'offline',
        tags: JSON.stringify(values.tags || []),
      }
      if (editingId) {
        const res = await updateCustomer(editingId, payload)
        message.success('客户已更新')
        setSelectedCustomer(res.data)
        setEditOpen(false)
        await loadCustomers()
        if (panelOpen) await openDetail(res.data)
      } else {
        await createCustomer(payload)
        message.success('客户已创建')
        setEditOpen(false)
        setPage(1)
        await loadCustomers()
      }
    } catch (e) {
      message.error(e instanceof Error ? e.message : '保存失败')
    } finally {
      setSaving(false)
    }
  }

  const handleDelete = async (id: number) => {
    try {
      await deleteCustomer(id)
      message.success('已删除')
      if (selectedCustomer?.id === id) {
        setPanelOpen(false)
        setSelectedCustomer(null)
      }
      await loadCustomers()
    } catch (e) {
      message.error(e instanceof Error ? e.message : '删除失败')
    }
  }

  const pendingCount = historySessions.filter(s => s.status === 'waiting' || s.status === 'active').length
  const avgSatisfaction = (() => {
    const scores = historySessions
      .map(s => s.satisfaction_score)
      .filter((n): n is number => typeof n === 'number' && n > 0)
    if (scores.length === 0) return '—'
    return (scores.reduce((a, b) => a + b, 0) / scores.length).toFixed(1)
  })()

  return (
    <div className="h-full flex flex-col min-h-0 bg-neutral-50 overflow-hidden">
      {/* 顶栏标题 — 对齐设计稿 header */}
      <header className="shrink-0 h-14 px-6 flex items-center justify-between bg-white border-b border-neutral-200">
        <h1 className="text-base font-semibold text-neutral-800 m-0">客户管理</h1>
      </header>

      <div className="flex flex-1 min-h-0 overflow-hidden">
        {/* 主内容区 */}
        <div className="flex-1 flex flex-col min-w-0 overflow-hidden">
          {/* 工具栏：搜索 + 筛选 + 操作 同一行 */}
          <div className="shrink-0 px-6 py-4 bg-white">
            <div className="flex items-center gap-3 flex-wrap">
              <div
                className="flex items-center gap-2 px-3 h-9 rounded-lg max-w-xs w-full sm:w-64 border border-neutral-200"
                style={{ backgroundColor: 'var(--neutral-100)' }}
              >
                <SearchOutlined className="text-neutral-400 shrink-0 text-sm" />
                <input
                  type="text"
                  placeholder="搜索客户名称、手机号、邮箱..."
                  value={search}
                  onChange={e => { setSearch(e.target.value); setPage(1) }}
                  className="flex-1 bg-transparent outline-none text-[13px] min-w-0 text-neutral-700 placeholder:text-neutral-400 border-0"
                />
              </div>

              <div className="flex items-center gap-1.5 flex-wrap">
                {filterChips.map(chip => {
                  const active = tagFilter === chip.key
                  return (
                    <button
                      key={chip.key}
                      type="button"
                      onClick={() => setTagFilter(chip.key)}
                      className={`px-3 py-1.5 rounded-md text-[13px] font-medium whitespace-nowrap border-0 cursor-pointer transition-colors ${
                        active
                          ? 'bg-[#2563eb] text-white'
                          : 'bg-transparent text-neutral-600 hover:bg-neutral-100'
                      }`}
                    >
                      {chip.label}
                    </button>
                  )
                })}
              </div>

              <div className="flex items-center gap-2 ml-auto">
                <Button
                  icon={<ExportOutlined />}
                  loading={exporting}
                  className="!text-[13px] !h-8 !px-3 !font-medium !text-neutral-600 !border-neutral-200"
                  onClick={async () => {
                    setExporting(true)
                    try {
                      await exportCustomersCSV({ search: search || undefined })
                      message.success('客户列表已导出')
                    } catch (e) {
                      message.error(e instanceof Error ? e.message : '导出失败')
                    } finally {
                      setExporting(false)
                    }
                  }}
                >
                  导出
                </Button>
                <Button
                  type="primary"
                  icon={<PlusOutlined />}
                  className="!text-[13px] !h-8 !px-3 !font-medium !bg-[#2563eb]"
                  onClick={openCreate}
                >
                  添加客户
                </Button>
              </div>
            </div>
          </div>

          {/* 表格 + 分页 */}
          <div className="flex-1 min-h-0 overflow-auto px-6 pb-4">
            <div className="rounded-lg overflow-hidden border border-neutral-200 bg-white">
              {loading ? (
                <div className="py-24 flex justify-center"><Spin /></div>
              ) : displayed.length === 0 ? (
                <Empty className="py-16" description="暂无客户数据" image={Empty.PRESENTED_IMAGE_SIMPLE} />
              ) : (
                <div className="overflow-x-auto">
                  <table className="w-full" style={{ minWidth: 960 }}>
                    <thead>
                      <tr className="bg-neutral-50">
                        {['客户', '手机号', '邮箱', '来源渠道', '标签', '最后对话', '状态', '操作'].map((h, i) => (
                          <th
                            key={h}
                            className={`py-3 px-3 text-[12px] font-medium uppercase tracking-wide whitespace-nowrap text-neutral-500 ${
                              i === 7 ? 'text-right' : 'text-left'
                            }`}
                            style={{
                              width: [200, 120, 160, 100, 130, 110, 80, 110][i],
                            }}
                          >
                            {h}
                          </th>
                        ))}
                      </tr>
                    </thead>
                    <tbody>
                      {displayed.map(record => {
                        const pal = avatarPalette(record.name || '?')
                        const selected = panelOpen && selectedCustomer?.id === record.id
                        return (
                          <tr
                            key={record.id}
                            onClick={() => openDetail(record)}
                            className={`group cursor-pointer border-t border-neutral-100 transition-colors ${
                              selected ? 'bg-blue-50/50' : 'hover:bg-neutral-50'
                            }`}
                          >
                            <td className="py-3 px-3 relative">
                              <div
                                className="absolute left-0 top-0 bottom-0 w-[3px]"
                                style={{ background: activityBar(record) }}
                              />
                              <div className="flex items-center gap-2.5 min-w-0 pl-1">
                                <div
                                  className="w-8 h-8 rounded-full flex items-center justify-center text-xs font-semibold shrink-0"
                                  style={{ backgroundColor: pal.bg, color: pal.color }}
                                >
                                  {(record.name || '?').slice(0, 1)}
                                </div>
                                <div className="min-w-0">
                                  <div className="text-[13px] font-medium text-neutral-800 truncate">{record.name}</div>
                                  <div className="text-[11px] text-neutral-400 truncate">
                                    ID: C{String(record.id).padStart(5, '0')}
                                  </div>
                                </div>
                              </div>
                            </td>
                            <td className="py-3 px-3 text-[13px] text-neutral-600 whitespace-nowrap">
                              {maskPhone(record.phone)}
                            </td>
                            <td className="py-3 px-3 text-[13px] text-neutral-600 max-w-[160px] truncate">
                              {record.email || '—'}
                            </td>
                            <td className="py-3 px-3 text-[13px] text-neutral-600 whitespace-nowrap">
                              {record.source || '—'}
                            </td>
                            <td className="py-3 px-3">
                              <div className="flex items-center gap-1.5 flex-wrap">
                                {parseTags(record.tags).length === 0
                                  ? <span className="text-neutral-300 text-xs">—</span>
                                  : parseTags(record.tags).map(t => <TagPill key={t} tag={t} catalog={tagCatalog} />)}
                              </div>
                            </td>
                            <td className="py-3 px-3 text-[13px] text-neutral-500 whitespace-nowrap">
                              {relativeTime(record.last_contact_at)}
                            </td>
                            <td className="py-3 px-3">
                              <StatusDot status={record.status} />
                            </td>
                            <td className="py-3 px-3 text-right" onClick={e => e.stopPropagation()}>
                              <div className="flex items-center justify-end gap-1">
                                <button
                                  type="button"
                                  className="px-2 py-1 rounded text-[12px] font-medium text-[#2563eb] hover:bg-blue-50 border-0 bg-transparent cursor-pointer"
                                  onClick={() => openDetail(record)}
                                >
                                  查看
                                </button>
                                <button
                                  type="button"
                                  className="px-2 py-1 rounded text-[12px] font-medium text-neutral-500 hover:bg-neutral-100 border-0 bg-transparent cursor-pointer"
                                  onClick={() => openEdit(record)}
                                >
                                  编辑
                                </button>
                              </div>
                            </td>
                          </tr>
                        )
                      })}
                    </tbody>
                  </table>
                </div>
              )}
            </div>

            {/* 分页 — 在表格卡片外 */}
            <div className="flex items-center justify-between mt-4 flex-wrap gap-3">
              <div className="text-[13px] text-neutral-500">
                共 <span className="font-medium text-neutral-700">{total}</span> 位客户
              </div>
              <Pagination
                current={page}
                total={total}
                pageSize={pageSize}
                showSizeChanger
                pageSizeOptions={[10, 20, 50]}
                onChange={(p, ps) => {
                  setPage(p)
                  if (ps !== pageSize) {
                    setPageSize(ps)
                    setPage(1)
                  }
                }}
                size="small"
              />
            </div>
          </div>
        </div>

        {/* 右侧详情面板 — 内嵌 360px，非遮罩 Drawer */}
        {panelOpen && selectedCustomer && (
          <aside className="w-[360px] shrink-0 flex flex-col bg-white border-l border-neutral-200 overflow-hidden">
            <div className="flex items-center justify-between px-5 py-4 shrink-0 border-b border-neutral-200">
              <h2 className="text-[15px] font-semibold text-neutral-800 m-0">客户详情</h2>
              <button
                type="button"
                className="w-7 h-7 rounded-md flex items-center justify-center text-neutral-400 hover:bg-neutral-100 border-0 bg-transparent cursor-pointer"
                onClick={closePanel}
              >
                <CloseOutlined className="text-xs" />
              </button>
            </div>

            {detailLoading ? (
              <div className="flex-1 flex items-center justify-center"><Spin /></div>
            ) : (
              <div className="flex-1 overflow-y-auto">
                {/* 头像区 */}
                {(() => {
                  const pal = avatarPalette(selectedCustomer.name)
                  return (
                    <div className="px-5 py-5 text-center border-b border-neutral-100">
                      <div
                        className="w-16 h-16 rounded-full flex items-center justify-center text-xl font-bold mx-auto mb-3"
                        style={{ backgroundColor: pal.bg, color: pal.color }}
                      >
                        {selectedCustomer.name.slice(0, 1)}
                      </div>
                      <div className="text-base font-semibold text-neutral-800 mb-0.5">{selectedCustomer.name}</div>
                      <div className="text-[13px] text-neutral-500 mb-2">
                        ID: C{String(selectedCustomer.id).padStart(5, '0')}
                      </div>
                      <div className="flex items-center justify-center">
                        <StatusDot status={selectedCustomer.status} />
                      </div>
                    </div>
                  )
                })()}

                {/* 标签 */}
                <div className="px-5 py-3 border-b border-neutral-100">
                  <div className="text-[11px] font-medium uppercase tracking-wide text-neutral-400 mb-2">标签</div>
                  <div className="flex flex-wrap gap-1.5">
                    {parseTags(selectedCustomer.tags).length === 0 ? (
                      <span className="text-xs text-neutral-400">暂无标签</span>
                    ) : parseTags(selectedCustomer.tags).map(t => <TagPill key={t} tag={t} catalog={tagCatalog} />)}
                  </div>
                </div>

                {/* 联系方式 */}
                <div className="px-5 py-3 border-b border-neutral-100">
                  <div className="text-[11px] font-medium uppercase tracking-wide text-neutral-400 mb-2">联系方式</div>
                  <div className="space-y-2">
                    <div className="flex items-center gap-2.5">
                      <PhoneOutlined className="text-neutral-400 text-[13px]" />
                      <span className="text-[13px] text-neutral-700">
                        {selectedCustomer.phone || '—'}
                      </span>
                    </div>
                    <div className="flex items-center gap-2.5 min-w-0">
                      <MailOutlined className="text-neutral-400 text-[13px] shrink-0" />
                      <span className="text-[13px] text-neutral-700 truncate">
                        {selectedCustomer.email || '—'}
                      </span>
                    </div>
                    <div className="flex items-center gap-2.5">
                      <GlobalOutlined className="text-neutral-400 text-[13px]" />
                      <span className="text-[13px] text-neutral-700 whitespace-nowrap">
                        来源: {selectedCustomer.source || '—'}
                      </span>
                    </div>
                  </div>
                </div>

                {/* 活跃数据 — 三列 */}
                <div className="px-5 py-3 border-b border-neutral-100">
                  <div className="text-[11px] font-medium uppercase tracking-wide text-neutral-400 mb-2">活跃数据</div>
                  <div className="grid grid-cols-3 gap-2">
                    {[
                      { value: selectedCustomer.conversation_count, label: '对话次数' },
                      { value: avgSatisfaction, label: '满意度' },
                      { value: pendingCount, label: '待处理' },
                    ].map(item => (
                      <div key={item.label} className="text-center py-2 rounded-md bg-neutral-50">
                        <div className="text-lg font-bold text-[#2563eb]">{item.value}</div>
                        <div className="text-[11px] text-neutral-500">{item.label}</div>
                      </div>
                    ))}
                  </div>
                </div>

                {/* 最近对话 */}
                <div className="px-5 py-3 border-b border-neutral-100">
                  <div className="text-[11px] font-medium uppercase tracking-wide text-neutral-400 mb-2">最近对话</div>
                  <div className="space-y-2.5">
                    {historySessions.length === 0 ? (
                      <div className="text-xs text-neutral-400 py-3 text-center">暂无会话记录</div>
                    ) : historySessions.slice(0, 6).map(s => (
                      <div key={s.id} className="flex items-start gap-2.5">
                        <div className="w-6 h-6 rounded-full flex items-center justify-center text-[10px] font-semibold shrink-0 mt-0.5 bg-[#dbeafe] text-[#2563eb]">
                          客
                        </div>
                        <div className="flex-1 min-w-0">
                          <div className="flex items-center justify-between gap-2">
                            <span className="text-[12px] font-medium text-neutral-700 truncate">
                              {sessionTopic(s)}
                            </span>
                            <span className="text-[11px] text-neutral-400 whitespace-nowrap shrink-0">
                              {relativeTime(s.last_message_at || s.created_at)}
                            </span>
                          </div>
                          <p className="text-[12px] mt-0.5 text-neutral-500 line-clamp-2 m-0">
                            {s.last_message || statusMap[s.status]?.text || s.status}
                          </p>
                        </div>
                      </div>
                    ))}
                  </div>
                </div>
              </div>
            )}

            {/* 底部操作 — 发起对话 + 编辑信息 */}
            <div className="px-5 py-4 shrink-0 mt-auto border-t border-neutral-100">
              <div className="flex gap-2">
                <button
                  type="button"
                  className="flex-1 flex items-center justify-center gap-1.5 px-3 py-2 rounded-md text-[13px] font-medium bg-[#2563eb] text-white border-0 cursor-pointer hover:bg-[#1d4ed8] transition-colors"
                  onClick={() => {
                    message.info('请在工作台接待访客会话')
                    navigate('/agent/dashboard')
                  }}
                >
                  <MessageOutlined className="text-sm" />
                  发起对话
                </button>
                <button
                  type="button"
                  className="flex-1 flex items-center justify-center gap-1.5 px-3 py-2 rounded-md text-[13px] font-medium border border-neutral-200 text-neutral-600 bg-white cursor-pointer hover:bg-neutral-50 transition-colors"
                  onClick={() => openEdit(selectedCustomer)}
                >
                  <EditOutlined className="text-sm" />
                  编辑信息
                </button>
              </div>
              {canDelete && (
                <Popconfirm title="确认删除该客户？" onConfirm={() => handleDelete(selectedCustomer.id)}>
                  <button
                    type="button"
                    className="w-full mt-2 flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-md text-[12px] text-red-500 border-0 bg-transparent cursor-pointer hover:bg-red-50"
                  >
                    <DeleteOutlined />
                    删除客户
                  </button>
                </Popconfirm>
              )}
            </div>
          </aside>
        )}
      </div>

      <Modal
        title={editingId ? '编辑客户' : '添加客户'}
        open={editOpen}
        onCancel={() => setEditOpen(false)}
        onOk={() => form.submit()}
        confirmLoading={saving}
        destroyOnClose
        okText="保存"
      >
        <Form form={form} layout="vertical" className="mt-3" onFinish={handleSave}>
          <Form.Item name="name" label="客户名称" rules={[{ required: true, message: '请输入名称' }, { min: 2, max: 50, message: '2-50 个字符' }]}>
            <Input maxLength={50} placeholder="姓名或昵称" />
          </Form.Item>
          <div className="grid grid-cols-2 gap-3">
            <Form.Item name="phone" label="手机号" rules={[{ pattern: /^$|^1[3-9]\d{9}$/, message: '手机号格式不正确' }]}>
              <Input maxLength={20} placeholder="可选" />
            </Form.Item>
            <Form.Item name="status" label="状态">
              <Select options={Object.entries(statusMap).map(([k, v]) => ({ value: k, label: v.text }))} />
            </Form.Item>
          </div>
          <Form.Item name="email" label="邮箱" rules={[{ type: 'email', message: '邮箱格式不正确' }]}>
            <Input maxLength={100} placeholder="可选" />
          </Form.Item>
          <Form.Item name="source" label="来源渠道">
            <Input maxLength={30} placeholder="如：官网咨询、微信、APP" />
          </Form.Item>
          <Form.Item
            name="tags"
            label="标签"
            extra={
              tagSelectOptions.length === 0
                ? '暂无标签库，请管理员在「系统设置 → 客户标签」中创建'
                : '仅可从标签库中选择（由管理员维护）'
            }
          >
            <Select
              mode="multiple"
              maxCount={10}
              allowClear
              options={tagSelectOptions}
              placeholder={tagSelectOptions.length === 0 ? '请先配置标签库' : '选择标签'}
              disabled={tagSelectOptions.length === 0}
              optionFilterProp="label"
            />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  )
}

export default Customers
