'use client'
import { useState, useEffect, useCallback, useRef, Suspense } from 'react'
import Link from 'next/link'
import { useRouter, useSearchParams, usePathname } from 'next/navigation'
import { Button, Badge, Pagination } from '@/components/ui'
import { Search, Download, Eye, Pencil, Trash2, Filter, ArrowUpDown, ChevronsUpDown, ChevronUp, ChevronDown, Check, X, ExternalLink } from 'lucide-react'
import SelectWithInput from '@/components/ui/SelectWithInput'
import SlaCountdown from '@/components/tickets/SlaCountdown'
import { getTier1Deadline } from '@/lib/sla'

interface Ticket {
  id: number
  device_ip: string | null
  device_name: string | null
  content: string | null
  assign_time: string | null
  current_status: string
  fault_category: string | null
  parts_replaced: string | null
  counted_in_sla: number
}

const statusMap: Record<string, { label: string; variant: 'default' | 'info' | 'warning' | 'success' | 'danger' }> = {
  open: { label: '待处理', variant: 'info' },
  in_progress: { label: '处理中', variant: 'warning' },
  resolved: { label: '已解决', variant: 'success' },
  closed: { label: '已关闭', variant: 'default' },
}

const STATUS_OPTIONS = ['open', 'in_progress', 'resolved', 'closed']
const FAULT_CATEGORY_OPTIONS = ['硬件故障', '软件故障', '网络故障', '存储故障', '电源故障', '无故障', '其他']

const COLUMNS = [
  { key: 'id',    label: '工单号',     sortable: true,  filterable: true,  filterType: 'text' as const },
  { key: 'device_ip',   label: '业务IP',     sortable: true,  filterable: true,  filterType: 'multi' as const },
  { key: 'device_name', label: '节点名称',   sortable: true,  filterable: true,  filterType: 'multi' as const },
  { key: 'content',     label: '工单内容',   sortable: true,  filterable: true,  filterType: 'text' as const },
  { key: 'current_status', label: '状态',    sortable: true,  filterable: true,  filterType: 'multi' as const },
  { key: 'fault_category', label: '故障大类', sortable: true,  filterable: true,  filterType: 'multi' as const },
  { key: 'assign_time', label: '派单时间',   sortable: true,  filterable: true,  filterType: 'date' as const },
]

type FilterType = 'text' | 'multi' | 'date'

function BatchEditModal({ selected, onClose, onSuccess }: { selected: number[]; onClose: () => void; onSuccess: () => void }) {
  const [batchField, setBatchField] = useState<'fault_category' | 'current_status' | 'counted_in_sla'>('fault_category')
  const [faultCategory, setFaultCategory] = useState('')
  const [currentStatus, setCurrentStatus] = useState('')
  const [countedInSla, setCountedInSla] = useState<number | null>(null)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState('')

  async function handleSubmit() {
    if (!confirm(`确定要批量修改选中的 ${selected.length} 条工单吗？`)) return
    setLoading(true)
    setError('')
    try {
      const updates = selected.map(id => {
        const body: Record<string, unknown> = { id }
        if (batchField === 'fault_category' && faultCategory) body.fault_category = faultCategory
        if (batchField === 'current_status' && currentStatus) body.current_status = currentStatus
        if (batchField === 'counted_in_sla') body.counted_in_sla = countedInSla
        return body
      })
      const res = await fetch('/api/tickets/batch', {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ updates }),
      })
      if (!res.ok) {
        const d = await res.json()
        setError(d.error || '批量修改失败')
        return
      }
      onSuccess()
      onClose()
    } catch {
      setError('网络错误')
    } finally {
      setLoading(false)
    }
  }

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center">
      <div className="fixed inset-0 bg-black/50" onClick={onClose} />
      <div className="relative bg-white dark:bg-slate-900 rounded-xl shadow-xl border border-slate-200 dark:border-slate-700 w-full max-w-md mx-4">
        <div className="flex items-center justify-between px-6 py-4 border-b border-slate-200 dark:border-slate-700">
          <h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100">批量编辑</h3>
          <button onClick={onClose} className="text-slate-400 hover:text-slate-600 dark:hover:text-slate-300 text-xl leading-none">&times;</button>
        </div>
        <div className="p-6 space-y-4">
          <p className="text-sm text-slate-500 dark:text-slate-400">已选中 <strong>{selected.length}</strong> 条工单</p>
          <div className="space-y-1">
            <label className="block text-sm font-medium text-slate-700 dark:text-slate-300">修改字段</label>
            <div className="flex gap-2">
              <button onClick={() => setBatchField('fault_category')} className={`px-3 py-1.5 rounded-lg text-sm border ${batchField === 'fault_category' ? 'bg-blue-600 text-white border-blue-600' : 'border-slate-300 dark:border-slate-600 text-slate-700 dark:text-slate-300'}`}>故障大类</button>
              <button onClick={() => setBatchField('current_status')} className={`px-3 py-1.5 rounded-lg text-sm border ${batchField === 'current_status' ? 'bg-blue-600 text-white border-blue-600' : 'border-slate-300 dark:border-slate-600 text-slate-700 dark:text-slate-300'}`}>状态</button>
              <button onClick={() => setBatchField('counted_in_sla')} className={`px-3 py-1.5 rounded-lg text-sm border ${batchField === 'counted_in_sla' ? 'bg-blue-600 text-white border-blue-600' : 'border-slate-300 dark:border-slate-600 text-slate-700 dark:text-slate-300'}`}>SLA计数</button>
            </div>
          </div>
          {batchField === 'fault_category' && (
            <SelectWithInput label="新故障大类" value={faultCategory} onChange={setFaultCategory} options={FAULT_CATEGORY_OPTIONS} placeholder="请选择或输入..." />
          )}
          {batchField === 'current_status' && (
            <div className="space-y-1">
              <label className="block text-sm font-medium text-slate-700 dark:text-slate-300">新状态</label>
              <div className="flex gap-2">
                {STATUS_OPTIONS.map(s => (
                  <button key={s} onClick={() => setCurrentStatus(s)}
                    className={`px-3 py-1.5 rounded-lg text-sm border ${currentStatus === s ? 'bg-blue-600 text-white border-blue-600' : 'border-slate-300 dark:border-slate-600 text-slate-700 dark:text-slate-300'}`}>
                    {statusMap[s].label}
                  </button>
                ))}
              </div>
            </div>
          )}
          {batchField === 'counted_in_sla' && (
            <div className="space-y-1">
              <label className="block text-sm font-medium text-slate-700 dark:text-slate-300">SLA 计数</label>
              <div className="flex gap-2">
                <button onClick={() => setCountedInSla(1)} className={`px-4 py-1.5 rounded-lg text-sm border ${countedInSla === 1 ? 'bg-blue-600 text-white border-blue-600' : 'border-slate-300 dark:border-slate-600 text-slate-700 dark:text-slate-300'}`}>计入</button>
                <button onClick={() => setCountedInSla(0)} className={`px-4 py-1.5 rounded-lg text-sm border ${countedInSla === 0 ? 'bg-blue-600 text-white border-blue-600' : 'border-slate-300 dark:border-slate-600 text-slate-700 dark:text-slate-300'}`}>不计入</button>
              </div>
            </div>
          )}
          {error && <p className="text-sm text-red-500">{error}</p>}
        </div>
        <div className="px-6 py-4 border-t border-slate-200 dark:border-slate-700 flex justify-end gap-3">
          <Button variant="secondary" onClick={onClose}>取消</Button>
          <Button onClick={handleSubmit} disabled={loading}>
            {loading ? '保存中...' : `确认修改 ${selected.length} 条工单`}
          </Button>
        </div>
      </div>
    </div>
  )
}

interface TicketListInnerProps {
  onPaginationChange?: (pagination: { page: number; pageSize: number; total: number; totalPages: number }) => void
  defaultStatusFilter?: string[]
  showSlaColumn?: boolean
  showActions?: boolean
  hideDefaultFilterChips?: boolean
}

function TicketListInner({ onPaginationChange, defaultStatusFilter, showSlaColumn, showActions = true, hideDefaultFilterChips }: TicketListInnerProps) {
  const router = useRouter()
  const searchParams = useSearchParams()
  const pathname = usePathname()
  const [tickets, setTickets] = useState<Ticket[]>([])
  const [pagination, setPagination] = useState({ page: 1, pageSize: 20, total: 0, totalPages: 0 })
  const [loading, setLoading] = useState(true)
  const [search, setSearch] = useState('')
  const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set())
  const [showBatchEdit, setShowBatchEdit] = useState(false)
  const [page, setPage] = useState(1)
  const [pageSize, setPageSize] = useState(20)
  const [sortKey, setSortKey] = useState('assign_time')
  const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc')
  const [tableMode, setTableMode] = useState<'sort' | 'filter'>('sort')
  const [openFilterColumn, setOpenFilterColumn] = useState<string | null>(null)
  const [columnFilterValues, setColumnFilterValues] = useState<Record<string, string[]>>({})
  const [columnTextFilter, setColumnTextFilter] = useState<Record<string, string>>({})
  const [dateFilter, setDateFilter] = useState<Record<string, { start: string; end: string }>>({})
  const [fieldOptions, setFieldOptions] = useState<Record<string, string[]>>({})
  const [ticketNoFilter, setTicketNoFilter] = useState('')
  const [permissions, setPermissions] = useState<string[]>([])
  const filterDropRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    fetch('/api/auth/me')
      .then(r => r.json())
      .then(u => { if (u.user?.permissions) setPermissions(u.user.permissions) })
      .catch(() => {})
  }, [])

  // 列宽拖拽调整
  const [colWidths, setColWidths] = useState<Record<string, number>>({})
  const [resizingCol, setResizingCol] = useState<string | null>(null)
  const [hasResized, setHasResized] = useState(false)
  const resizeRef = useRef<{ col: string; startX: number; startWidth: number } | null>(null)

  function snapAllColumns() {
    if (hasResized) return
    setHasResized(true)
    const widths: Record<string, number> = {}
    document.querySelectorAll('th[data-col-key]').forEach(th => {
      const key = th.getAttribute('data-col-key')
      if (key) widths[key] = th.getBoundingClientRect().width
    })
    setColWidths(widths)
  }

  function onResizeStart(colKey: string, e: React.MouseEvent) {
    e.preventDefault()
    e.stopPropagation()
    snapAllColumns()
    const th = (e.target as HTMLElement).closest('th')
    const startWidth = th?.getBoundingClientRect().width || 150
    resizeRef.current = { col: colKey, startX: e.clientX, startWidth }
    setResizingCol(colKey)
    document.body.style.userSelect = 'none'
    document.body.style.cursor = 'col-resize'
  }

  useEffect(() => {
    if (!resizingCol) return
    function onMouseMove(e: MouseEvent) {
      if (!resizeRef.current) return
      const { col, startX, startWidth } = resizeRef.current
      setColWidths(prev => ({ ...prev, [col]: Math.max(60, startWidth + (e.clientX - startX)) }))
    }
    function onMouseUp() {
      setResizingCol(null)
      resizeRef.current = null
      document.body.style.userSelect = ''
      document.body.style.cursor = ''
    }
    document.addEventListener('mousemove', onMouseMove)
    document.addEventListener('mouseup', onMouseUp)
    return () => {
      document.removeEventListener('mousemove', onMouseMove)
      document.removeEventListener('mouseup', onMouseUp)
    }
  }, [resizingCol])

  // 从 URL 初始化设备筛选
  useEffect(() => {
    function handleClick(e: MouseEvent) {
      if (filterDropRef.current && !filterDropRef.current.contains(e.target as Node)) {
        setOpenFilterColumn(null)
      }
    }
    document.addEventListener('mousedown', handleClick)
    return () => document.removeEventListener('mousedown', handleClick)
  }, [])
  useEffect(() => {
    const ip = searchParams.get('device_ip')
    const name = searchParams.get('device_name')
    const sn = searchParams.get('device_sn')
    if (ip) {
      setColumnFilterValues(prev => ({ ...prev, device_ip: [ip] }))
    }
    if (name) {
      setColumnFilterValues(prev => ({ ...prev, device_name: [name] }))
    }
    if (sn) {
      setColumnFilterValues(prev => ({ ...prev, device_sn: [sn] }))
    }
  }, [searchParams])

  // 应用 defaultStatusFilter prop 到列筛选状态
  useEffect(() => {
    if (defaultStatusFilter && defaultStatusFilter.length > 0) {
      setColumnFilterValues(prev => {
        if (prev.current_status && prev.current_status.length > 0) return prev
        return { ...prev, current_status: defaultStatusFilter }
      })
    }
  }, [defaultStatusFilter])

  const loadFieldOptions = useCallback(async () => {
    const fields = ['device_ip', 'device_name', 'fault_category', 'current_status']
    const params = new URLSearchParams()
    fields.forEach(f => params.append('field', f))
    try {
      const res = await fetch(`/api/tickets/field-values?${params}`)
      if (res.ok) {
        const data = await res.json()
        setFieldOptions(data)
      }
    } catch { /* silent */ }
  }, [])

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


  const fetchTickets = useCallback(async () => {
    setLoading(true)
    try {
      const params = new URLSearchParams({ page: String(page), pageSize: String(pageSize), sortBy: sortKey, sortOrder })
      if (search) params.set('search', search)
      if (ticketNoFilter) params.set('search', ticketNoFilter)
      for (const [field, values] of Object.entries(columnFilterValues)) {
        for (const v of values) params.append(`filter_${field}`, v)
      }
      for (const [field, text] of Object.entries(columnTextFilter)) {
        if (text) params.set(`filter_${field}`, text)
      }
      for (const [field, range] of Object.entries(dateFilter)) {
        if (range.start) params.set(`${field}_start`, range.start)
        if (range.end) params.set(`${field}_end`, range.end)
      }
      const res = await fetch(`/api/tickets?${params}`)
      const data = await res.json()
      if (res.ok) {
        setTickets(data.tickets)
        setPagination(data.pagination)
        onPaginationChange?.(data.pagination)
      }
    } catch { /* silent */ }
    finally { setLoading(false) }
  }, [page, pageSize, sortKey, sortOrder, search, columnFilterValues, columnTextFilter, dateFilter, ticketNoFilter, onPaginationChange])

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

  function handleColumnClick(key: string, sortable: boolean, filterable: boolean) {
    if (tableMode === 'sort') {
      if (!sortable) return
      if (sortKey === key) setSortOrder(prev => prev === 'asc' ? 'desc' : 'asc')
      else { setSortKey(key); setSortOrder('asc') }
      setPage(1)
    } else {
      if (!filterable) return
      setOpenFilterColumn(openFilterColumn === key ? null : key)
    }
  }

  function toggleFilterValue(column: string, value: string) {
    setColumnFilterValues(prev => {
      const current = prev[column] || []
      const next = current.includes(value) ? current.filter(v => v !== value) : [...current, value]
      return { ...prev, [column]: next }
    })
    setPage(1)
  }

  function clearColumnFilter(column: string) {
    setColumnFilterValues(prev => { const n = { ...prev }; delete n[column]; return n })
    setColumnTextFilter(prev => { const n = { ...prev }; delete n[column]; return n })
    setDateFilter(prev => { const n = { ...prev }; delete n[column]; return n })
    setPage(1)
  }

  function SortIcon({ colKey, colDef }: { colKey: string; colDef: (typeof COLUMNS)[0] }) {
    if (tableMode === 'filter' && !colDef.filterable) return null
    const icon = tableMode === 'filter'
      ? <Filter size={12} />
      : !colDef.sortable
        ? null
        : sortKey !== colKey
          ? <ChevronsUpDown size={13} />
          : sortOrder === 'asc'
            ? <ChevronUp size={13} className="text-blue-500" />
            : <ChevronDown size={13} className="text-blue-500" />
    if (!icon) return null
    return (
      <span
        onClick={(e) => { e.stopPropagation(); handleColumnClick(colKey, colDef.sortable, colDef.filterable) }}
        className={`ml-1 flex-shrink-0 rounded transition-colors cursor-pointer ${tableMode === 'sort' && sortKey === colKey ? 'text-blue-500' : 'text-slate-400 hover:text-slate-600 dark:hover:text-slate-300'}`}
        title={tableMode === 'sort' ? '点击排序' : '点击筛选'}
      >
        {icon}
      </span>
    )
  }

  function FilterIndicator({ colKey }: { colKey: string }) {
    const multi = columnFilterValues[colKey]
    const text = columnTextFilter[colKey]
    const date = dateFilter[colKey]
    const hasFilter = (multi && multi.length > 0) || (text && text.length > 0) || (date && (date.start || date.end))
    if (!hasFilter) return null
    const count = (multi?.length || 0) + (text ? 1 : 0) + ((date?.start || date?.end) ? 1 : 0)
    return <span className="ml-0.5 inline-flex items-center justify-center w-4 h-4 rounded-full bg-blue-600 text-white text-[10px] font-bold">{count}</span>
  }

  const hasActiveFilters =
    Object.values(columnFilterValues).some(v => v.length > 0) ||
    Object.values(columnTextFilter).some(v => v.length > 0) ||
    Object.values(dateFilter).some(v => v.start || v.end) ||
    ticketNoFilter.length > 0

  async function handleDelete(id: number) {
    if (!confirm('确定要删除此工单吗？')) return
    const res = await fetch(`/api/tickets/${id}`, { method: 'DELETE' })
    if (res.ok) fetchTickets()
  }

  function handleExport() {
    if (tickets.length === 0) {
      alert('当前列表没有可导出的工单')
      return
    }
    const hasSelection = selectedIds.size > 0
    const exportCount = hasSelection ? selectedIds.size : pagination.total
    const msg = hasSelection
      ? `确定要导出选中的 ${exportCount} 条工单吗？`
      : `确定要导出当前筛选的 ${exportCount} 条工单吗？`
    if (!confirm(msg)) return

    if (hasSelection) {
      const ids = Array.from(selectedIds).join(',')
      window.open(`/api/tickets/export?ids=${ids}`, '_blank')
      return
    }

    const params = new URLSearchParams()
    if (search) params.set('search', search)
    params.set('sortBy', sortKey)
    params.set('sortOrder', sortOrder)
    for (const [field, values] of Object.entries(columnFilterValues)) {
      for (const v of values) params.append(`filter_${field}`, v)
    }
    for (const [field, text] of Object.entries(columnTextFilter)) {
      if (text) params.set(`filter_${field}`, text)
    }
    for (const [field, range] of Object.entries(dateFilter)) {
      if (range.start) params.set(`${field}_start`, range.start)
      if (range.end) params.set(`${field}_end`, range.end)
    }
    window.open(`/api/tickets/export?${params}`, '_blank')
  }

  const activeDeviceFilter = (() => {
    if (columnFilterValues.device_ip?.length === 1 && columnFilterValues.device_name?.length === 1) {
      return { ip: columnFilterValues.device_ip[0], name: columnFilterValues.device_name[0] }
    }
    if (columnFilterValues.device_ip?.length === 1) return { ip: columnFilterValues.device_ip[0], name: null }
    if (columnFilterValues.device_name?.length === 1) return { ip: null, name: columnFilterValues.device_name[0] }
    return null
  })()

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <div className="flex-1 flex items-center gap-3">
          <div className="relative flex-1 max-w-sm">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 text-slate-400" size={16} />
            <input className="w-full pl-9 pr-3 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 text-sm text-slate-900 dark:text-white placeholder:text-slate-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
              placeholder="快速搜索..." value={search}
              onChange={e => setSearch(e.target.value)}
              onKeyDown={e => { if (e.key === 'Enter') { setPage(1); fetchTickets() } }} />
          </div>
          <Button variant="secondary" size="sm" onClick={() => { setPage(1); fetchTickets() }}>搜索</Button>
        </div>
        <div className="flex items-center gap-2">
          {(permissions.includes('*') || permissions.includes('tickets:export')) && (
            <Button variant="secondary" size="sm" onClick={handleExport}><Download size={14} />导出</Button>
          )}
        </div>
      </div>

      {activeDeviceFilter && (
        <div className="flex items-center gap-2 px-4 py-3 rounded-lg bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 text-sm">
          <ExternalLink size={14} className="text-blue-600 dark:text-blue-400" />
          <span className="text-blue-700 dark:text-blue-300">
            当前显示设备
            {activeDeviceFilter.ip && <> <strong>{activeDeviceFilter.ip}</strong></>}
            {activeDeviceFilter.name && <>（{activeDeviceFilter.name}）</>}
            的所有工单，共 {pagination.total} 条
          </span>
          <button
            onClick={() => {
              setColumnFilterValues(prev => {
                const n = { ...prev }
                delete n.device_ip; delete n.device_name
                return n
              })
              setPage(1)
            }}
            className="ml-2 text-xs text-blue-600 dark:text-blue-400 hover:underline flex items-center gap-1">
            <X size={12} />清除筛选
          </button>
        </div>
      )}

      {hasActiveFilters && !activeDeviceFilter && (
        <div className="flex flex-wrap items-center gap-2">
          <span className="text-xs text-slate-500">列筛选:</span>
          {ticketNoFilter && (
            <span className="inline-flex items-center gap-1 px-2 py-1 rounded bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-400 text-xs">
              <span className="font-medium">工单号</span>: {ticketNoFilter}
              <button onClick={() => { setTicketNoFilter(''); setPage(1) }} className="ml-0.5 hover:text-blue-900 dark:hover:text-blue-200"><X size={12} /></button>
            </span>
          )}
          {Object.entries(columnFilterValues).filter(([, v]) => v.length > 0).map(([col, vals]) => {
            // 隐藏默认状态筛选标签
            if (hideDefaultFilterChips && col === 'current_status' && defaultStatusFilter) {
              const isDefaultOnly = vals.length === defaultStatusFilter.length && vals.every(v => defaultStatusFilter.includes(v))
              if (isDefaultOnly) return null
            }
            const colDef = COLUMNS.find(c => c.key === col)
            const displayVals = vals.map(v => statusMap[v]?.label || v)
            return (
              <span key={col} className="inline-flex items-center gap-1 px-2 py-1 rounded bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-400 text-xs">
                <span className="font-medium">{colDef?.label || col}</span>: {displayVals.join(', ')}
                <button onClick={() => { setColumnFilterValues(prev => { const n = { ...prev }; delete n[col]; return n }); setPage(1) }} className="ml-0.5 hover:text-blue-900 dark:hover:text-blue-200"><X size={12} /></button>
              </span>
            )
          })}
          {Object.entries(columnTextFilter).filter(([, v]) => v.length > 0).map(([col, text]) => {
            const colDef = COLUMNS.find(c => c.key === col)
            return (
              <span key={col} className="inline-flex items-center gap-1 px-2 py-1 rounded bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-400 text-xs">
                <span className="font-medium">{colDef?.label || col}</span>: {text}
                <button onClick={() => { setColumnTextFilter(prev => { const n = { ...prev }; delete n[col]; return n }); setPage(1) }} className="ml-0.5 hover:text-blue-900 dark:hover:text-blue-200"><X size={12} /></button>
              </span>
            )
          })}
          {Object.entries(dateFilter).filter(([, v]) => v.start || v.end).map(([col, range]) => {
            const colDef = COLUMNS.find(c => c.key === col)
            return (
              <span key={col} className="inline-flex items-center gap-1 px-2 py-1 rounded bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-400 text-xs">
                <span className="font-medium">{colDef?.label || col}</span>: {range.start || '*'} ~ {range.end || '*'}
                <button onClick={() => { setDateFilter(prev => { const n = { ...prev }; delete n[col]; return n }); setPage(1) }} className="ml-0.5 hover:text-blue-900 dark:hover:text-blue-200"><X size={12} /></button>
              </span>
            )
          })}
          <button onClick={() => { setColumnFilterValues({}); setColumnTextFilter({}); setDateFilter({}); setTicketNoFilter(''); setPage(1) }} className="text-xs text-slate-400 hover:text-slate-600 dark:hover:text-slate-300">清除全部</button>
        </div>
      )}

      <div className="flex items-center justify-end mb-2">
        <div className="flex items-center gap-1.5">
          <span className="text-xs text-slate-500 dark:text-slate-400">每页</span>
          <div className="flex rounded-lg border border-slate-300 dark:border-slate-600 overflow-hidden">
            {[20, 50, 100].map(s => (
              <button key={s} onClick={() => { setPageSize(s); setPage(1) }}
                className={`px-3 py-1 text-xs font-medium transition-colors ${pageSize === s ? 'bg-blue-600 text-white' : 'bg-white dark:bg-slate-800 text-slate-600 dark:text-slate-400 hover:bg-slate-50 dark:hover:bg-slate-700'}`}>{s}</button>
            ))}
          </div>
          <span className="text-xs text-slate-500 dark:text-slate-400">行</span>
        </div>
      </div>

      <div className="overflow-x-auto rounded-lg border border-slate-200 dark:border-slate-700">
        <table className="w-full text-sm" style={{ tableLayout: hasResized ? 'fixed' : 'auto' }}>
          <thead className="bg-slate-50 dark:bg-slate-800">
            <tr>
              <th className="px-4 py-3 w-10">
                <input
                  type="checkbox"
                  className="w-4 h-4 rounded border-slate-300 dark:border-slate-600 text-blue-600 focus:ring-blue-500 cursor-pointer"
                  checked={tickets.length > 0 && tickets.every(t => selectedIds.has(t.id))}
                  onChange={e => {
                    if (e.target.checked) setSelectedIds(prev => { const n = new Set(prev); tickets.forEach(t => n.add(t.id)); return n })
                    else setSelectedIds(prev => { const n = new Set(prev); tickets.forEach(t => n.delete(t.id)); return n })
                  }}
                />
              </th>
              {COLUMNS.map(col => (
                <th key={col.key} data-col-key={col.key} className="px-4 py-3 text-center relative" style={colWidths[col.key] ? { width: colWidths[col.key] } : undefined}>
                  <div className="relative flex flex-col">
                    <div className="flex items-center justify-center gap-1">
                      {col.filterable && (
                        <button
                          onClick={() => setTableMode(tableMode === 'sort' ? 'filter' : 'sort')}
                          className="p-0.5 rounded transition-colors text-slate-400 hover:bg-slate-100 dark:hover:bg-slate-700 cursor-pointer"
                          title={tableMode === 'sort' ? '切换到筛选' : '切换到排序'}>
                          <ArrowUpDown size={12} />
                        </button>
                      )}
                      <button
                        className={`flex items-center justify-center gap-0.5 font-medium cursor-pointer hover:text-slate-900 dark:hover:text-slate-100 ${openFilterColumn === col.key ? 'text-blue-600 dark:text-blue-400' : 'text-slate-600 dark:text-slate-300'}`}
                        onClick={() => handleColumnClick(col.key, col.sortable, col.filterable)}>
                        {col.label}
                        <SortIcon colKey={col.key} colDef={col} />
                        <FilterIndicator colKey={col.key} />
                      </button>
                    </div>
                    {openFilterColumn === col.key && (
                      <div ref={filterDropRef}>
                        <div className="absolute top-full left-0 z-50 mt-1 rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 shadow-xl w-fit min-w-48 max-w-80">
                          {col.filterType === 'text' ? (
                            <div className="p-2 border-b border-slate-100 dark:border-slate-700">
                              <input
                                autoFocus
                                type="text"
                                value={columnTextFilter[col.key] || ''}
                                onChange={e => setColumnTextFilter(prev => ({ ...prev, [col.key]: e.target.value }))}
                                onKeyDown={e => { if (e.key === 'Enter') { setPage(1); setOpenFilterColumn(null) } }}
                                placeholder={`输入${col.label}...`}
                                className="w-full px-2 py-1 rounded border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-xs text-slate-900 dark:text-slate-100 placeholder:text-slate-400 focus:outline-none focus:ring-1 focus:ring-blue-500"
                              />
                            </div>
                          ) : col.filterType === 'date' ? (
                            <div className="p-3">
                              <p className="text-xs text-slate-500 mb-2">派单时间范围</p>
                              <div className="flex gap-2">
                                <div className="flex-1">
                                  <label className="text-xs text-slate-400">开始</label>
                                  <input type="date" autoFocus value={dateFilter[col.key]?.start || ''}
                                    onChange={e => setDateFilter(prev => ({ ...prev, [col.key]: { ...(prev[col.key] || { start: '', end: '' }), start: e.target.value } }))}
                                    className="w-full px-2 py-1 rounded border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-xs text-slate-900 dark:text-slate-100 mt-0.5" />
                                </div>
                                <div className="flex-1">
                                  <label className="text-xs text-slate-400">结束</label>
                                  <input type="date" value={dateFilter[col.key]?.end || ''}
                                    onChange={e => setDateFilter(prev => ({ ...prev, [col.key]: { ...(prev[col.key] || { start: '', end: '' }), end: e.target.value } }))}
                                    className="w-full px-2 py-1 rounded border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-xs text-slate-900 dark:text-slate-100 mt-0.5" />
                                </div>
                              </div>
                            </div>
                          ) : (
                            <div className="max-h-56 overflow-y-auto">
                              {(fieldOptions[col.key] || []).length === 0 && <p className="px-3 py-3 text-xs text-slate-400 text-center">无可用选项</p>}
                              {(fieldOptions[col.key] || []).map(opt => {
                                const checked = (columnFilterValues[col.key] || []).includes(opt)
                                const label = statusMap[opt]?.label || opt
                                return (
                                  <button key={opt} onClick={() => { toggleFilterValue(col.key, opt); setPage(1) }}
                                    className={`w-full flex items-center gap-2 px-3 py-1.5 text-xs text-left transition-colors ${checked ? 'bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-300' : 'text-slate-700 dark:text-slate-300 hover:bg-slate-50 dark:hover:bg-slate-700'}`}>
                                    <span className={`w-4 h-4 rounded border flex items-center justify-center flex-shrink-0 ${checked ? 'bg-blue-600 border-blue-600' : 'border-slate-300 dark:border-slate-600'}`}>
                                      {checked && <Check size={10} className="text-white" />}
                                    </span>
                                    <span className="truncate">{label || '(空)'}</span>
                                  </button>
                                )
                              })}
                            </div>
                          )}
                          <div className="px-2 py-1.5 border-t border-slate-100 dark:border-slate-700 flex items-center justify-between">
                            <span className="text-[10px] text-slate-400">
                              {(columnFilterValues[col.key] || []).length > 0
                                ? `已选 ${(columnFilterValues[col.key] || []).length} 项`
                                : `${(fieldOptions[col.key] || []).length} 个值`}
                            </span>
                            <button onClick={() => { clearColumnFilter(col.key); setOpenFilterColumn(null) }}
                              className="text-[10px] text-blue-600 dark:text-blue-400 hover:underline">清除</button>
                          </div>
                        </div>
                      </div>
                    )}
                  </div>
                  <div
                    className="absolute top-1/2 right-0 -translate-y-1/2 h-4 w-2 cursor-col-resize z-10 flex items-center justify-center group"
                    onMouseDown={(e) => onResizeStart(col.key, e)}
                  >
                    <div className="w-px h-full bg-slate-300 dark:bg-slate-600 group-hover:bg-blue-400 transition-colors" />
                  </div>
                </th>
              ))}
              {showSlaColumn && <th className="px-4 py-3 text-center font-medium text-slate-600 dark:text-slate-300">超时时间</th>}
              {showSlaColumn && <th className="px-4 py-3 text-center font-medium text-slate-600 dark:text-slate-300">SLA 倒计时</th>}
              {showActions && <th className="px-4 py-3 text-left font-medium text-slate-600 dark:text-slate-300">操作</th>}
            </tr>
          </thead>
          <tbody className="divide-y divide-slate-200 dark:divide-slate-700">
            {loading ? (
              <tr><td colSpan={COLUMNS.length + (showSlaColumn ? 4 : 2)} className="px-4 py-12 text-center text-slate-500 dark:text-slate-400">加载中...</td></tr>
            ) : tickets.length === 0 ? (
              <tr><td colSpan={COLUMNS.length + (showSlaColumn ? 4 : 2)} className="px-4 py-12 text-center text-slate-500 dark:text-slate-400">暂无工单数据</td></tr>
            ) : tickets.map(t => (
              <tr key={t.id} className={`hover:bg-slate-50 dark:hover:bg-slate-800/50 transition-colors ${selectedIds.has(t.id) ? 'bg-blue-50 dark:bg-blue-900/10' : ''}`}>
                <td className="px-4 py-3">
                  <input
                    type="checkbox"
                    className="w-4 h-4 rounded border-slate-300 dark:border-slate-600 text-blue-600 focus:ring-blue-500 cursor-pointer"
                    checked={selectedIds.has(t.id)}
                    onChange={e => {
                      setSelectedIds(prev => {
                        const n = new Set(prev)
                        if (e.target.checked) n.add(t.id)
                        else n.delete(t.id)
                        return n
                      })
                    }}
                  />
                </td>
                <td className="px-4 py-3 font-medium"><Link href={`/tickets/${t.id}`} className="text-blue-600 dark:text-blue-400 hover:underline">{t.id}</Link></td>
                <td className="px-4 py-3">
                  {t.device_ip ? (
                    <Link href={`${pathname}?device_ip=${encodeURIComponent(t.device_ip)}`} className="text-blue-600 dark:text-blue-400 hover:underline">{t.device_ip}</Link>
                  ) : '-'}
                </td>
                <td className="px-4 py-3">
                  {t.device_name ? (
                    <Link href={`${pathname}?device_name=${encodeURIComponent(t.device_name)}`} className="text-blue-600 dark:text-blue-400 hover:underline">{t.device_name}</Link>
                  ) : '-'}
                </td>
                <td className="px-4 py-3 text-slate-700 dark:text-slate-300 max-w-xs truncate">{t.content || '-'}</td>
                <td className="px-4 py-3"><Badge variant={statusMap[t.current_status]?.variant || 'default'}>{statusMap[t.current_status]?.label || t.current_status}</Badge></td>
                <td className="px-4 py-3 text-slate-700 dark:text-slate-300">{t.fault_category || '-'}</td>
                <td className="px-4 py-3 text-slate-500 dark:text-slate-400 text-sm">{t.assign_time ? new Date(t.assign_time).toLocaleString('zh-CN') : '-'}</td>
                {showSlaColumn && (
                  <td className="px-4 py-3 text-sm text-slate-500 dark:text-slate-400">
                    {t.assign_time && t.counted_in_sla !== 0
                      ? getTier1Deadline(t.assign_time).toLocaleString('zh-CN', { hourCycle: 'h23' })
                      : '-'}
                  </td>
                )}
                {showSlaColumn && (
                  <td className="px-4 py-3">
                    <SlaCountdown assignTime={t.assign_time || ''} countedInSla={t.counted_in_sla} />
                  </td>
                )}
                {showActions && (
                <td className="px-4 py-3">
                  <div className="flex items-center gap-1">
                    <Link href={`/tickets/${t.id}`}><Button variant="ghost" size="sm"><Eye size={14} /></Button></Link>
                    <Link href={`/tickets/${t.id}/edit`}><Button variant="ghost" size="sm"><Pencil size={14} /></Button></Link>
                    <Button variant="ghost" size="sm" onClick={() => handleDelete(t.id)}><Trash2 size={14} className="text-red-500" /></Button>
                  </div>
                </td>
                )}
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <Pagination page={pagination.page} totalPages={pagination.totalPages} onPageChange={p => setPage(p)} />

      {showBatchEdit && (
        <BatchEditModal
          selected={Array.from(selectedIds)}
          onClose={() => setShowBatchEdit(false)}
          onSuccess={() => { setSelectedIds(new Set()); fetchTickets() }}
        />
      )}

    </div>
  )
}

export default function TicketList({ onPaginationChange, defaultStatusFilter, showSlaColumn, showActions, hideDefaultFilterChips }: TicketListInnerProps) {
  return (
    <Suspense fallback={<div className="text-center py-12 text-slate-500">加载中...</div>}>
      <TicketListInner onPaginationChange={onPaginationChange} defaultStatusFilter={defaultStatusFilter} showSlaColumn={showSlaColumn} showActions={showActions} hideDefaultFilterChips={hideDefaultFilterChips} />
    </Suspense>
  )
}
