import { useState, useEffect, useCallback, useMemo, useRef } from 'react';
import { motion, AnimatePresence } from 'motion/react';
import {
  Truck, Filter, ChevronDown,
  Maximize2, Minimize2, RotateCcw,
  ArrowUp, ArrowDown, ChevronsUp, Download, Check, CalendarDays,
  RefreshCw,
} from 'lucide-react';
import { BarChart, Bar, ResponsiveContainer, Tooltip, ReferenceLine, XAxis } from 'recharts';
import type { MonitoringVehicle, MonitoringStats, MonitoringFilters } from './types';
import { fetchMonitoring } from './api';
import Blur from '../../components/Blur';
import PlateMultiSelect from './PlateMultiSelect';
import { exportMileageXlsx } from './xlsx-export';
import VehicleDetailModal from './VehicleDetailModal';

const HIGH_MILEAGE_ALERT_TARGETS = new Set([
  '交投40辆4.5T普货',
  '交投190辆4.5T冷链车',
]);
const HIGH_MILEAGE_ALERT_KM = 800;

function defaultMileageDate(): string {
  const now = new Date();
  if (now.getHours() < 5) now.setDate(now.getDate() - 1);
  return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
}

function parseOneOsTime(value: string | null | undefined): number | null {
  if (!value) return null;
  let normalized = value.trim().replace(' ', 'T');
  if (!/(?:Z|[+-]\d{2}:?\d{2})$/i.test(normalized)) normalized += '+08:00';
  const timestamp = Date.parse(normalized);
  return Number.isFinite(timestamp) ? timestamp : null;
}

function formatAbsoluteTime(value: string | null | undefined): string | null {
  const timestamp = parseOneOsTime(value);
  if (timestamp === null) return null;
  return new Intl.DateTimeFormat('zh-CN', {
    timeZone: 'Asia/Shanghai',
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    hour12: false,
  }).format(new Date(timestamp));
}

function vehicleStatisticTime(vehicle: MonitoringVehicle, nowMs: number): {
  label: string;
  title: string;
  color: string;
} {
  const primaryTime = vehicle.dataTime || vehicle.updatedAt || vehicle.calculatedAt;
  const timestamp = parseOneOsTime(primaryTime);
  if (timestamp === null) {
    return {
      label: vehicle.isDataSynced ? '统计时间待接口' : '无有效数据时间',
      title: 'OneOS 当前未返回车辆级数据时间',
      color: vehicle.isDataSynced ? 'text-amber-500' : 'text-slate-500',
    };
  }

  const deltaSeconds = Math.floor((nowMs - timestamp) / 1000);
  let label: string;
  if (deltaSeconds < -60) label = '时间异常';
  else if (deltaSeconds < 5) label = '刚刚';
  else if (deltaSeconds < 60) label = `${deltaSeconds}秒前`;
  else if (deltaSeconds < 3600) label = `${Math.floor(deltaSeconds / 60)}分钟前`;
  else if (deltaSeconds < 86400) label = `${Math.floor(deltaSeconds / 3600)}小时前`;
  else label = `${Math.floor(deltaSeconds / 86400)}天前`;

  const absoluteDataTime = formatAbsoluteTime(vehicle.dataTime);
  const absoluteCalculatedAt = formatAbsoluteTime(vehicle.calculatedAt);
  const absoluteUpdatedAt = formatAbsoluteTime(vehicle.updatedAt);
  const title = [
    absoluteDataTime ? `数据时间：${absoluteDataTime}` : null,
    absoluteCalculatedAt ? `计算时间：${absoluteCalculatedAt}` : null,
    absoluteUpdatedAt ? `更新时间：${absoluteUpdatedAt}` : null,
  ].filter(Boolean).join('\n');
  const ageSeconds = Math.max(0, deltaSeconds);
  const color = ageSeconds <= 300
    ? 'text-emerald-500'
    : ageSeconds <= 3600
      ? 'text-blue-500'
      : ageSeconds <= 86400
        ? 'text-amber-500'
        : 'text-rose-500';
  return { label, title, color };
}

function normalizeRangeLabel(start: string, end: string): string {
  if (!start && !end) return '最新数据';
  if (start && end && start === end) return start;
  return `${start || end} 至 ${end || start}`;
}

function fmtDate(date: Date): string {
  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
}

type RangePreset = 'today' | 'yesterday' | 'thisWeek' | 'thisMonth' | 'last7' | 'last15';

function getRangePreset(preset: RangePreset): { start: string; end: string } {
  const end = new Date(`${defaultMileageDate()}T00:00:00`);
  const start = new Date(end);
  if (preset === 'yesterday') {
    start.setDate(start.getDate() - 1);
    end.setDate(end.getDate() - 1);
  } else if (preset === 'thisWeek') {
    const day = start.getDay() || 7;
    start.setDate(start.getDate() - day + 1);
  } else if (preset === 'thisMonth') {
    start.setDate(1);
  } else if (preset === 'last7') {
    start.setDate(start.getDate() - 6);
  } else if (preset === 'last15') {
    start.setDate(start.getDate() - 14);
  }
  return { start: fmtDate(start), end: fmtDate(end) };
}

const SearchableSelect = ({
  options,
  value,
  onChange,
  placeholder
}: {
  options: string[],
  value: string,
  onChange: (val: string) => void,
  placeholder: string
}) => {
  const [isOpen, setIsOpen] = useState(false);
  const [search, setSearch] = useState('');

  const filtered = useMemo(() => {
    if (!search) return options;
    return options.filter(opt => opt.toLowerCase().includes(search.toLowerCase()));
  }, [options, search]);

  return (
    <div className="relative">
      <div className="relative">
        <input
          type="text"
          className="w-full bg-slate-50 border-none rounded-lg py-1.5 px-2 text-[10px] font-bold text-slate-600 outline-none focus:ring-1 focus:ring-blue-500/20 placeholder:text-slate-400"
          placeholder={value === 'All' ? placeholder : value === '__EMPTY__' ? '无值' : value}
          value={search}
          onFocus={() => setIsOpen(true)}
          onChange={(e) => setSearch(e.target.value)}
          onBlur={() => {
            // Delay to allow clicking an option
            setTimeout(() => setIsOpen(false), 200);
          }}
        />
        <ChevronDown size={10} className="absolute right-2 top-1/2 -translate-y-1/2 text-slate-400 pointer-events-none" />
      </div>

      <AnimatePresence>
        {isOpen && (
          <motion.div
            initial={{ opacity: 0, y: -5 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: -5 }}
            className="absolute z-50 left-0 right-0 mt-1 bg-white border border-slate-100 rounded-xl shadow-xl max-h-40 overflow-y-auto"
          >
            <div
              className="px-3 py-2 text-[10px] font-bold text-blue-600 hover:bg-slate-50 cursor-pointer"
              onClick={() => {
                onChange('All');
                setSearch('');
                setIsOpen(false);
              }}
            >
              无限制
            </div>
            {filtered.map((opt: string) => (
              <div
                key={opt}
                className="px-3 py-2 text-[10px] font-bold text-slate-600 hover:bg-slate-50 cursor-pointer border-t border-slate-50"
                onClick={() => {
                  onChange(opt);
                  setSearch('');
                  setIsOpen(false);
                }}
              >
                {opt === '__EMPTY__' ? '无值' : opt}
              </div>
            ))}
            {filtered.length === 0 && (
              <div className="px-3 py-2 text-[10px] font-bold text-slate-300 italic">
                无匹配项
              </div>
            )}
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
};

const BatchMultiSelect = ({
  options,
  selected,
  onChange,
  placeholder,
}: {
  options: string[],
  selected: string[],
  onChange: (val: string[]) => void,
  placeholder: string
}) => {
  const rootRef = useRef<HTMLDivElement>(null);
  const [isOpen, setIsOpen] = useState(false);
  const [search, setSearch] = useState('');

  const selectedSet = useMemo(() => new Set(selected), [selected]);
  const filtered = useMemo(() => {
    if (!search) return options;
    return options.filter(opt => opt.toLowerCase().includes(search.toLowerCase()));
  }, [options, search]);
  const label = selected.length === 0
    ? placeholder
    : selected.length === options.length
      ? '全部批次'
      : selected.length === 1
        ? selected[0]
        : `已选 ${selected.length} 个批次`;

  const toggle = (opt: string) => {
    if (selectedSet.has(opt)) {
      onChange(selected.filter(item => item !== opt));
    } else {
      onChange([...selected, opt]);
    }
  };

  useEffect(() => {
    if (!isOpen) return;
    const handlePointerDown = (event: PointerEvent) => {
      const target = event.target;
      if (target instanceof Node && !rootRef.current?.contains(target)) {
        setIsOpen(false);
        setSearch('');
      }
    };
    document.addEventListener('pointerdown', handlePointerDown);
    return () => document.removeEventListener('pointerdown', handlePointerDown);
  }, [isOpen]);

  return (
    <div ref={rootRef} className="relative">
      <button
        type="button"
        className="w-full bg-slate-50 border-none rounded-lg py-1.5 pl-2 pr-6 text-left text-[10px] font-bold text-slate-600 outline-none focus:ring-1 focus:ring-blue-500/20"
        onClick={() => setIsOpen(open => !open)}
      >
        <span className="block truncate">{label}</span>
        <ChevronDown size={10} className="absolute right-2 top-1/2 -translate-y-1/2 text-slate-400 pointer-events-none" />
      </button>

      <AnimatePresence>
        {isOpen && (
          <motion.div
            initial={{ opacity: 0, y: -5 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: -5 }}
            className="absolute z-50 left-0 right-0 mt-1 bg-white border border-slate-100 rounded-xl shadow-xl overflow-hidden"
          >
            <div className="p-2 border-b border-slate-50">
              <input
                type="text"
                className="w-full bg-slate-50 border-none rounded-lg py-1.5 px-2 text-[10px] font-bold text-slate-600 outline-none focus:ring-1 focus:ring-blue-500/20 placeholder:text-slate-400"
                placeholder="搜索批次"
                value={search}
                onChange={(e) => setSearch(e.target.value)}
              />
            </div>
            <div className="flex items-center gap-1 px-2 py-1.5 border-b border-slate-50">
              <button
                type="button"
                className="flex-1 px-2 py-1 text-[10px] font-bold text-blue-600 hover:bg-blue-50 rounded-lg"
                onClick={() => onChange(options)}
              >
                全选批次
              </button>
              <button
                type="button"
                className="flex-1 px-2 py-1 text-[10px] font-bold text-slate-400 hover:bg-slate-50 rounded-lg"
                onClick={() => onChange([])}
              >
                不限
              </button>
            </div>
            <div className="max-h-44 overflow-y-auto">
              {filtered.map((opt: string) => {
                const checked = selectedSet.has(opt);
                return (
                  <button
                    type="button"
                    key={opt}
                    className="w-full px-3 py-2 text-[10px] font-bold text-slate-600 hover:bg-slate-50 cursor-pointer border-t border-slate-50 flex items-center justify-between gap-2 text-left"
                    onClick={() => toggle(opt)}
                  >
                    <span className="truncate">{opt}</span>
                    <span className={`w-3.5 h-3.5 rounded border flex items-center justify-center flex-shrink-0 ${checked ? 'bg-blue-600 border-blue-600 text-white' : 'border-slate-200 text-transparent'}`}>
                      <Check size={10} />
                    </span>
                  </button>
                );
              })}
              {filtered.length === 0 && (
                <div className="px-3 py-2 text-[10px] font-bold text-slate-300 italic">
                  无匹配项
                </div>
              )}
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
};

export default function MonitoringView() {
  const [searchTerm, setSearchTerm] = useState('');
  const [filterDept, setFilterDept] = useState('All');
  const [sortBy, setSortBy] = useState<'today' | 'total'>('today');
  const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc');
  const [isFilterOpen, setIsFilterOpen] = useState(false);
  const [isFullscreen, setIsFullscreen] = useState(false);
  const [fullscreenVehicles, setFullscreenVehicles] = useState<MonitoringVehicle[]>([]);
  const [fullscreenStats, setFullscreenStats] = useState<MonitoringStats>({ totalToday: 0, totalAll: 0, vehicleCount: 0, yesterdayTotal: 0 });
  const [fullscreenRefresh, setFullscreenRefresh] = useState(0);
  const [fullscreenLoading, setFullscreenLoading] = useState(false);

  // New filters from image
  const [filterPlates, setFilterPlates] = useState<string[]>([]);
  const [filterCustomer, setFilterCustomer] = useState('All');
  const [filterProject, setFilterProject] = useState('All');
  const [filterEntity, setFilterEntity] = useState('All');
  const [filterRentStatus, setFilterRentStatus] = useState('All');
  const [filterPlatePrefix, setFilterPlatePrefix] = useState('All');
  const [filterTargetNames, setFilterTargetNames] = useState<string[]>([]);
  const [filterRegion, setFilterRegion] = useState('All');
  const [filterBrands, setFilterBrands] = useState<string[]>([]);
  const [filterMileageRange, setFilterMileageRange] = useState({ min: '', max: '' });
  const [appliedMileageRange, setAppliedMileageRange] = useState({ min: '', max: '' });
  const [exporting, setExporting] = useState(false);
  const [detailVehicle, setDetailVehicle] = useState<MonitoringVehicle | null>(null);
  const [rangeStart, setRangeStart] = useState(defaultMileageDate);
  const [rangeEnd, setRangeEnd] = useState(defaultMileageDate);

  const [vehicles, setVehicles] = useState<MonitoringVehicle[]>([]);
  const [stats, setStats] = useState<MonitoringStats>({ totalToday: 0, totalAll: 0, vehicleCount: 0, yesterdayTotal: 0 });
  const [filterOptions, setFilterOptions] = useState<MonitoringFilters>({ departments: [], customers: [], plates: [], projects: [], entities: [], rentStatuses: [], platePrefixes: [], targetNames: [], regions: [], brands: [] });
  const [rangeDailyTotals, setRangeDailyTotals] = useState<{ date: string; totalKm: number }[]>([]);
  const [effectiveRange, setEffectiveRange] = useState<{ start: string; end: string }>(() => ({ start: defaultMileageDate(), end: defaultMileageDate() }));
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(true);
  const [loadingMore, setLoadingMore] = useState(false);
  const [pageLoading, setPageLoading] = useState(true);
  const [manualRefreshing, setManualRefreshing] = useState(false);
  const [lastRefreshedAt, setLastRefreshedAt] = useState<Date | null>(null);
  const [showBackToTop, setShowBackToTop] = useState(false);
  const [relativeNow, setRelativeNow] = useState(() => Date.now());
  const PAGE_SIZE = 50;

  useEffect(() => {
    const timer = setInterval(() => setRelativeNow(Date.now()), 5000);
    return () => clearInterval(timer);
  }, []);

  const departments = filterOptions.departments;
  const plateNumbers = filterOptions.plates;
  const rangeLabel = normalizeRangeLabel(effectiveRange.start, effectiveRange.end);
  const isRangeMode = !!effectiveRange.start && !!effectiveRange.end && effectiveRange.start !== effectiveRange.end;
  const averageDailyKm = rangeDailyTotals.length > 0
    ? rangeDailyTotals.reduce((sum, item) => sum + item.totalKm, 0) / rangeDailyTotals.length
    : 0;
  const applyRangePreset = useCallback((preset: RangePreset) => {
    const range = getRangePreset(preset);
    setRangeStart(range.start);
    setRangeEnd(range.end);
  }, []);

  const isHighMileageAlert = useCallback((v: MonitoringVehicle) => {
    const inAlertTarget = v.targetNames?.some(name => HIGH_MILEAGE_ALERT_TARGETS.has(name))
      || filterTargetNames.some(name => HIGH_MILEAGE_ALERT_TARGETS.has(name));
    return inAlertTarget && Math.max(0, v.dailyKm || 0) >= HIGH_MILEAGE_ALERT_KM;
  }, [filterTargetNames]);

  // 加载首页数据
  const loadFirstPage = useCallback((showPageLoading = true) => {
    if (showPageLoading) setPageLoading(true);
    return fetchMonitoring({
      sortBy,
      sortOrder,
      limit: PAGE_SIZE,
      page: 1,
      search: searchTerm || undefined,
      dept: filterDept !== 'All' ? filterDept : undefined,
      customer: filterCustomer !== 'All' ? filterCustomer : undefined,
      project: filterProject !== 'All' ? filterProject : undefined,
      entity: filterEntity !== 'All' ? filterEntity : undefined,
      rentStatus: filterRentStatus !== 'All' ? filterRentStatus : undefined,
      platePrefix: filterPlatePrefix !== 'All' ? filterPlatePrefix : undefined,
      targetNames: filterTargetNames.length > 0 ? filterTargetNames : undefined,
      region: filterRegion !== 'All' ? filterRegion : undefined,
      plate: filterPlates.length > 0 ? filterPlates.join(',') : undefined,
      mileageMin: appliedMileageRange.min || undefined,
      mileageMax: appliedMileageRange.max || undefined,
      startDate: rangeStart || undefined,
      endDate: rangeEnd || undefined,
      brands: filterBrands.length > 0 ? filterBrands : undefined,
    }).then(d => {
      setVehicles(d.vehicles);
      setStats(d.stats);
      setFilterOptions(d.filters);
      setRangeDailyTotals(d.rangeDailyTotals || []);
      setEffectiveRange(d.dateRange || { start: rangeStart, end: rangeEnd });
      setTotal(d.total);
      setPage(1);
      setHasMore(d.page < d.totalPages);
      setLastRefreshedAt(new Date());
    }).catch(() => {}).finally(() => {
      if (showPageLoading) setPageLoading(false);
    });
  }, [sortBy, sortOrder, searchTerm, filterDept, filterCustomer, filterProject, filterEntity, filterRentStatus, filterPlatePrefix, filterTargetNames, filterRegion, filterPlates, appliedMileageRange, rangeStart, rangeEnd, filterBrands]);

  const handleManualRefresh = useCallback(async () => {
    if (manualRefreshing) return;
    setManualRefreshing(true);
    try {
      await loadFirstPage(false);
    } finally {
      setManualRefreshing(false);
    }
  }, [loadFirstPage, manualRefreshing]);

  // 加载更多
  const loadMore = useCallback(() => {
    if (loadingMore || !hasMore) return;
    const nextPage = page + 1;
    setLoadingMore(true);
    fetchMonitoring({
      sortBy,
      sortOrder,
      limit: PAGE_SIZE,
      page: nextPage,
      search: searchTerm || undefined,
      dept: filterDept !== 'All' ? filterDept : undefined,
      customer: filterCustomer !== 'All' ? filterCustomer : undefined,
      project: filterProject !== 'All' ? filterProject : undefined,
      entity: filterEntity !== 'All' ? filterEntity : undefined,
      rentStatus: filterRentStatus !== 'All' ? filterRentStatus : undefined,
      platePrefix: filterPlatePrefix !== 'All' ? filterPlatePrefix : undefined,
      targetNames: filterTargetNames.length > 0 ? filterTargetNames : undefined,
      region: filterRegion !== 'All' ? filterRegion : undefined,
      plate: filterPlates.length > 0 ? filterPlates.join(',') : undefined,
      mileageMin: appliedMileageRange.min || undefined,
      mileageMax: appliedMileageRange.max || undefined,
      startDate: rangeStart || undefined,
      endDate: rangeEnd || undefined,
      brands: filterBrands.length > 0 ? filterBrands : undefined,
    }).then(d => {
      setVehicles(prev => [...prev, ...d.vehicles]);
      setPage(nextPage);
      setHasMore(nextPage < d.totalPages);
    }).catch(() => {}).finally(() => setLoadingMore(false));
  }, [sortBy, sortOrder, searchTerm, filterDept, filterCustomer, filterProject, filterEntity, filterRentStatus, filterPlatePrefix, filterTargetNames, filterRegion, filterPlates, appliedMileageRange, rangeStart, rangeEnd, page, loadingMore, hasMore, filterBrands]);

  // 筛选/排序变化时重新加载
  useEffect(() => {
    loadFirstPage();
  }, [loadFirstPage]);

  // 区域级联：plate 选项收窄后，剔除已选但已不属于该区域的车牌
  useEffect(() => {
    if (filterPlates.length === 0) return;
    const valid = new Set(filterOptions.plates);
    const next = filterPlates.filter(p => valid.has(p));
    if (next.length !== filterPlates.length) setFilterPlates(next);
  }, [filterOptions.plates, filterPlates]);

  // 下载当前筛选结果为 xlsx
  const handleDownload = useCallback(async () => {
    if (exporting) return;
    setExporting(true);
    try {
      const d = await fetchMonitoring({
        sortBy,
        sortOrder,
        limit: 9999,
        page: 1,
        search: searchTerm || undefined,
        dept: filterDept !== 'All' ? filterDept : undefined,
        customer: filterCustomer !== 'All' ? filterCustomer : undefined,
        project: filterProject !== 'All' ? filterProject : undefined,
        entity: filterEntity !== 'All' ? filterEntity : undefined,
        rentStatus: filterRentStatus !== 'All' ? filterRentStatus : undefined,
        platePrefix: filterPlatePrefix !== 'All' ? filterPlatePrefix : undefined,
        targetNames: filterTargetNames.length > 0 ? filterTargetNames : undefined,
        region: filterRegion !== 'All' ? filterRegion : undefined,
        plate: filterPlates.length > 0 ? filterPlates.join(',') : undefined,
        mileageMin: appliedMileageRange.min || undefined,
        mileageMax: appliedMileageRange.max || undefined,
        startDate: rangeStart || undefined,
        endDate: rangeEnd || undefined,
        brands: filterBrands.length > 0 ? filterBrands : undefined,
      });
      exportMileageXlsx(d.vehicles, { startDate: d.dateRange?.start || rangeStart, endDate: d.dateRange?.end || rangeEnd, sortBy });
    } catch (err) {
      console.error('export failed', err);
    } finally {
      setExporting(false);
    }
  }, [exporting, sortBy, sortOrder, searchTerm, filterDept, filterCustomer, filterProject, filterEntity, filterRentStatus, filterPlatePrefix, filterTargetNames, filterRegion, filterPlates, appliedMileageRange, rangeStart, rangeEnd, filterBrands]);

  // 每分钟自动刷新
  useEffect(() => {
    const timer = setInterval(() => { void loadFirstPage(false); }, 60 * 1000);
    return () => clearInterval(timer);
  }, [loadFirstPage]);

  // 触底检测：用 IntersectionObserver 监听哨兵元素
  const loadMoreRef = useRef(loadMore);
  loadMoreRef.current = loadMore;
  const sentinelRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const sentinel = sentinelRef.current;
    if (!sentinel) return;
    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting) {
          loadMoreRef.current();
        }
      },
      { rootMargin: '200px' }
    );
    observer.observe(sentinel);
    return () => observer.disconnect();
  }, []);

  // 回到顶部按钮：用 IntersectionObserver 检测顶部哨兵是否离开视口
  const topSentinelRef = useRef<HTMLDivElement>(null);
  useEffect(() => {
    const el = topSentinelRef.current;
    if (!el) return;
    const observer = new IntersectionObserver(
      ([entry]) => setShowBackToTop(!entry.isIntersecting),
    );
    observer.observe(el);
    return () => observer.disconnect();
  }, []);

  const scrollToTop = () => {
    window.scrollTo(0, 0);
    document.documentElement.scrollTop = 0;
    document.body.scrollTop = 0;
  };

  const filteredVehicles = vehicles;

  const toggleFullscreen = () => {
    setIsFullscreen(!isFullscreen);
  };

  // 全屏时加载全部数据（无分页），筛选变化时重新加载
  useEffect(() => {
    if (!isFullscreen) return;
    setFullscreenLoading(true);
    fetchMonitoring({
      sortBy,
      sortOrder,
      limit: 9999,
      page: 1,
      search: searchTerm || undefined,
      dept: filterDept !== 'All' ? filterDept : undefined,
      customer: filterCustomer !== 'All' ? filterCustomer : undefined,
      rentStatus: filterRentStatus !== 'All' ? filterRentStatus : undefined,
      platePrefix: filterPlatePrefix !== 'All' ? filterPlatePrefix : undefined,
      targetNames: filterTargetNames.length > 0 ? filterTargetNames : undefined,
      region: filterRegion !== 'All' ? filterRegion : undefined,
      plate: filterPlates.length > 0 ? filterPlates.join(',') : undefined,
      startDate: rangeStart || undefined,
      endDate: rangeEnd || undefined,
      brands: filterBrands.length > 0 ? filterBrands : undefined,
    }).then(d => {
      setFullscreenVehicles(d.vehicles);
      setFullscreenStats(d.stats);
      setFilterOptions(d.filters);
    }).catch(() => {}).finally(() => setFullscreenLoading(false));
  }, [isFullscreen, sortBy, sortOrder, searchTerm, filterDept, filterCustomer, filterRentStatus, filterPlatePrefix, filterTargetNames, filterRegion, filterPlates, rangeStart, rangeEnd, fullscreenRefresh, filterBrands]);

  // 全屏时禁止背景滚动
  useEffect(() => {
    if (isFullscreen) {
      document.body.style.overflow = 'hidden';
    } else {
      document.body.style.overflow = '';
    }
    return () => { document.body.style.overflow = ''; };
  }, [isFullscreen]);

  // 检测是否在小程序 webview 中（微信/抖音/支付宝等），且当前是竖屏
  // 小程序 webview 无法调用系统旋转 API，只能用 CSS rotate 强制横屏
  const forceLandscape = useMemo(() => {
    if (typeof window === 'undefined') return false;
    const ua = navigator.userAgent || '';
    const isMiniProgram =
      /miniProgram/i.test(ua) ||
      /toutiaomicroapp/i.test(ua) ||
      /AlipayClient/i.test(ua) ||
      (window as any).__wxjs_environment === 'miniprogram';
    const isPortrait = window.innerHeight > window.innerWidth;
    return isMiniProgram && isPortrait;
  }, [isFullscreen]);

  return (
    <>
      {/* 顶部哨兵：离开视口时显示回到顶部按钮 */}
      <div ref={topSentinelRef} className="h-0" />

      {/* Fullscreen Landscape View Overlay */}
      <AnimatePresence>
        {isFullscreen && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="fixed z-[100] bg-slate-950 flex flex-col overflow-hidden"
            style={
              forceLandscape
                ? {
                    // 小程序 webview 无法真横屏，强制 CSS 旋转 90 度模拟横屏
                    top: 0,
                    left: '100vw',
                    width: '100vh',
                    height: '100vw',
                    transform: 'rotate(90deg)',
                    transformOrigin: 'top left',
                  }
                : { top: 0, left: 0, right: 0, bottom: 0 }
            }
          >
            {/* Top bar: compact inline KPI */}
            <div className="flex-shrink-0 px-3 py-2 border-b border-slate-800/60 flex items-center justify-between">
              <div className="flex items-center gap-4">
                <div className="flex items-center gap-2">
                  <div className="w-0.5 h-4 bg-blue-500 rounded-full"></div>
                  <h2 className="text-white font-bold text-xs">全屏监控</h2>
                </div>
                <div className="flex items-center gap-3 text-[10px]">
                  <span className="text-slate-500">区间 <span className="text-white font-black">{Math.round(fullscreenStats.totalToday).toLocaleString()}</span> <span className="text-blue-400">km</span></span>
                  <span className="text-slate-700">|</span>
                  <span className="text-slate-500">累计 <span className="text-white font-black">{Math.round(fullscreenStats.totalAll).toLocaleString()}</span> <span className="text-blue-400">km</span></span>
                  <span className="text-slate-700">|</span>
                  <span className="text-slate-500">车辆 <span className="text-white font-black">{fullscreenStats.vehicleCount}</span> 台</span>
                  <span className="text-slate-700">|</span>
                  <span className="text-slate-500">均 <span className="text-white font-black">{(fullscreenStats.vehicleCount > 0 ? (sortBy === 'today' ? fullscreenStats.totalToday : fullscreenStats.totalAll) / fullscreenStats.vehicleCount : 0).toFixed(0)}</span> <span className="text-blue-400">km</span></span>
                </div>
              </div>
              <div className="flex items-center gap-2">
                <button
                  onClick={() => { setFullscreenRefresh(n => n + 1); }}
                  className={`p-1.5 text-slate-500 hover:text-blue-400 transition-colors ${fullscreenLoading ? 'animate-spin' : ''}`}
                >
                  <RotateCcw size={13} />
                </button>
                <button onClick={toggleFullscreen} className="p-1.5 text-slate-500 hover:text-white transition-colors">
                  <Minimize2 size={14} />
                </button>
              </div>
            </div>

            {/* Batch selector + legend */}
            <div className="flex-shrink-0 px-3 py-1 border-b border-slate-800/60 flex items-center justify-between">
              <div className="flex items-center gap-1 overflow-x-auto no-scrollbar">
                <button
                  onClick={() => setFilterTargetNames([])}
                  className={`px-2 py-0.5 rounded text-[8px] font-bold transition-all whitespace-nowrap ${filterTargetNames.length === 0 ? 'bg-blue-600 text-white' : 'bg-slate-800 text-slate-400 hover:bg-slate-700'}`}
                >全部</button>
                {filterOptions.targetNames.map(n => (
                  <button
                    key={n}
                    onClick={() => setFilterTargetNames(prev => prev.includes(n) ? prev.filter(item => item !== n) : [...prev, n])}
                    className={`px-2 py-0.5 rounded text-[8px] font-bold transition-all whitespace-nowrap ${filterTargetNames.includes(n) ? 'bg-blue-600 text-white' : 'bg-slate-800 text-slate-400 hover:bg-slate-700'}`}
                  >{n.replace(/交投|羚牛|恒运/, '').replace(/辆/, '台')}</button>
                ))}
              </div>
              <div className="flex items-center gap-2 text-[8px] text-slate-500 flex-shrink-0 ml-2">
                <span className="flex items-center gap-0.5"><span className="w-1.5 h-1.5 rounded-full bg-green-500 inline-block"></span>在线</span>
                <span className="flex items-center gap-0.5"><span className="w-1.5 h-1.5 rounded-full bg-slate-500 inline-block"></span>离线</span>
                <span className="flex items-center gap-0.5"><span className="w-1.5 h-1.5 rounded-full bg-amber-400 inline-block"></span>未对接</span>
              </div>
            </div>

            {/* Table Area */}
            <div className="flex-1 overflow-hidden flex flex-col">

              <div className="flex-1 overflow-auto relative">
                {fullscreenLoading && (
                  <div className="absolute inset-0 bg-slate-950/60 z-20 flex items-center justify-center">
                    <div className="flex items-center gap-2 text-slate-400 text-xs font-bold">
                      <RotateCcw size={14} className="animate-spin" />
                      加载中...
                    </div>
                  </div>
                )}
                <table className="w-full text-left border-collapse">
                  <thead className="sticky top-0 bg-slate-900 z-10">
                    <tr className="border-b border-slate-800/60">
                      <th className="px-3 py-2 text-[10px] font-bold text-slate-500 uppercase w-12 text-center">状态</th>
                      <th className="px-3 py-2 text-[10px] font-bold text-slate-500 uppercase">
                        <div className="flex flex-col gap-1">
                          <span>车牌号</span>
                          <span className="text-[9px] text-slate-500 font-normal">
                            {filterPlates.length === 0 ? '全部' : `已选 ${filterPlates.length}`}
                          </span>
                        </div>
                      </th>
                      <th className="px-3 py-2 text-[10px] font-bold text-slate-500 uppercase">
                        <div className="flex flex-col gap-1">
                          <span>客户</span>
                          <input
                            type="text"
                            className="bg-slate-800 border-none rounded px-2 py-0.5 text-[9px] text-slate-300 outline-none focus:ring-1 focus:ring-blue-500/30 w-20"
                            placeholder={filterCustomer === 'All' ? '全部' : filterCustomer}
                            defaultValue=""
                            onBlur={(e) => {
                              const val = e.target.value.trim();
                              setFilterCustomer(val || 'All');
                              e.target.value = '';
                            }}
                            onKeyDown={(e) => {
                              if (e.key === 'Enter') {
                                const val = (e.target as HTMLInputElement).value.trim();
                                setFilterCustomer(val || 'All');
                                (e.target as HTMLInputElement).value = '';
                              }
                            }}
                          />
                        </div>
                      </th>
                      <th className="px-3 py-2 text-[10px] font-bold text-slate-500 uppercase">
                        <div className="flex flex-col gap-1">
                          <span>品牌</span>
                          <input
                            type="text"
                            className="bg-slate-800 border-none rounded px-2 py-0.5 text-[9px] text-slate-300 outline-none focus:ring-1 focus:ring-blue-500/30 w-16"
                            placeholder={filterBrands.length === 0 ? '全部' : `已选${filterBrands.length}`}
                            defaultValue=""
                            onBlur={(e) => {
                              const val = e.target.value.trim();
                              if (val) {
                                setFilterBrands(filterBrands.includes(val) ? filterBrands.filter(b => b !== val) : [...filterBrands, val]);
                              }
                              e.target.value = '';
                            }}
                            onKeyDown={(e) => {
                              if (e.key === 'Enter') {
                                const val = (e.target as HTMLInputElement).value.trim();
                                if (val) {
                                  setFilterBrands(filterBrands.includes(val) ? filterBrands.filter(b => b !== val) : [...filterBrands, val]);
                                }
                                (e.target as HTMLInputElement).value = '';
                              }
                            }}
                          />
                        </div>
                      </th>
                      <th className="px-3 py-2 text-[10px] font-bold text-slate-500 uppercase">
                        <div className="flex flex-col gap-1">
                          <span>租赁状态</span>
                          <select
                            className="bg-slate-800 border-none rounded px-2 py-0.5 text-[9px] text-slate-300 outline-none focus:ring-1 focus:ring-blue-500/30"
                            value={filterRentStatus}
                            onChange={(e) => setFilterRentStatus(e.target.value)}
                          >
                            <option value="All">全部状态</option>
                            {filterOptions.rentStatuses.map(s => <option key={s} value={s}>{s}</option>)}
                          </select>
                        </div>
                      </th>
                      <th className="px-3 py-2 text-[10px] font-bold text-slate-500 uppercase">
                        <div className="flex flex-col gap-1">
                          <span>部门</span>
                          <select
                            className="bg-slate-800 border-none rounded px-2 py-0.5 text-[9px] text-slate-300 outline-none focus:ring-1 focus:ring-blue-500/30"
                            value={filterDept}
                            onChange={(e) => setFilterDept(e.target.value)}
                          >
                            <option value="All">全部部门</option>
                            <option value="__EMPTY__">无值</option>
                            {departments.map(d => <option key={d} value={d}>{d.replace('业务', '')}</option>)}
                          </select>
                        </div>
                      </th>
                      <th
                        className="px-3 py-2 text-[10px] font-bold text-slate-500 uppercase text-right cursor-pointer hover:text-blue-400 transition-colors"
                        onClick={() => {
                          if (sortBy === 'today') {
                            setSortOrder(sortOrder === 'desc' ? 'asc' : 'desc');
                          } else {
                            setSortBy('today');
                            setSortOrder('desc');
                          }
                        }}
                      >
                        <div className="flex items-center justify-end gap-1">
                          <span>区间里程</span>
                          {sortBy === 'today' && (
                            sortOrder === 'desc' ? <ArrowDown size={10} /> : <ArrowUp size={10} />
                          )}
                        </div>
                      </th>
                      <th
                        className="px-3 py-2 text-[10px] font-bold text-slate-500 uppercase text-right cursor-pointer hover:text-blue-400 transition-colors"
                        onClick={() => {
                          if (sortBy === 'total') {
                            setSortOrder(sortOrder === 'desc' ? 'asc' : 'desc');
                          } else {
                            setSortBy('total');
                            setSortOrder('desc');
                          }
                        }}
                      >
                        <div className="flex items-center justify-end gap-1">
                          <span>累计里程</span>
                          {sortBy === 'total' && (
                            sortOrder === 'desc' ? <ArrowDown size={10} /> : <ArrowUp size={10} />
                          )}
                        </div>
                      </th>
                    </tr>
                  </thead>
                  <tbody className="divide-y divide-slate-800/30">
                    {fullscreenVehicles.map((v) => {
                      const highMileageAlert = isHighMileageAlert(v);
                      const statisticTime = vehicleStatisticTime(v, relativeNow);
                      return (
                      <tr key={v.plate} className="hover:bg-slate-800/20 transition-colors">
                        <td className="px-3 py-2 text-center">
                          <div className={`w-2 h-2 rounded-full mx-auto ${v.isOnline ? 'bg-green-500 shadow-[0_0_6px_rgba(34,197,94,0.4)]' : (v.isDataSynced || v.totalKm != null) ? 'bg-slate-600' : 'bg-amber-400 animate-pulse'}`}></div>
                        </td>
                        <td className="px-3 py-2">
                          <div className="text-xs font-bold text-white"><Blur>{v.plate}</Blur></div>
                          <div className={`mt-0.5 text-[8px] font-bold ${statisticTime.color}`} title={statisticTime.title}>
                            {statisticTime.label}
                          </div>
                        </td>
                        <td className="px-3 py-2 text-[11px] text-slate-400"><Blur>{v.customer || '-'}</Blur></td>
                        <td className="px-3 py-2 text-[11px] text-slate-400">{v.brand || '-'}</td>
                        <td className="px-3 py-2 text-[11px] text-slate-400">{v.rentStatus || '-'}</td>
                        <td className="px-3 py-2 text-[11px] text-slate-400">{v.department || '-'}</td>
                        <td className="px-3 py-2 text-right">
                          <span className={`text-xs font-mono font-bold ${(v.isDataSynced || v.totalKm != null) ? (highMileageAlert ? 'text-red-400' : 'text-blue-400') : 'text-amber-400'}`}>
                            {(v.isDataSynced || v.totalKm != null) ? <>{Math.max(0, v.dailyKm || 0).toLocaleString()} <span className={`text-[8px] ${highMileageAlert ? 'text-red-400/70' : 'text-slate-500'}`}>km</span></> : <span className="text-[8px] text-amber-500/50">未对接</span>}
                          </span>
                        </td>
                        <td className="px-3 py-2 text-right">
                          <span className={`text-xs font-mono font-bold ${v.isDataSynced ? 'text-slate-300' : 'text-slate-600'}`}>
                            {v.totalKm != null ? <>{v.totalKm.toLocaleString()} <span className="text-[8px] text-slate-500">km</span></> : <span className="text-[8px] text-amber-500/50">未对接</span>}
                          </span>
                        </td>
                      </tr>
                      );
                    })}
                  </tbody>
                </table>
              </div>
            </div>
          </motion.div>
        )}
      </AnimatePresence>

      <div className="flex flex-col gap-3 rounded-2xl border border-gray-100 bg-white p-3 shadow-sm">
        <div className="flex items-center justify-between gap-2">
          <div className="flex min-w-0 items-center gap-3">
            <div className="h-8 w-1 flex-shrink-0 rounded-full bg-blue-600" />
            <div className="min-w-0">
              <div className="flex items-center gap-2">
                <h1 className="truncate text-lg font-black leading-none text-slate-900">里程看板</h1>
                <button onClick={toggleFullscreen} className="p-1 text-slate-300 transition-colors hover:text-blue-600" title="全屏视图">
                  <Maximize2 size={14} />
                </button>
                <button onClick={handleDownload} disabled={exporting} className="p-1 text-slate-300 transition-colors hover:text-blue-600 disabled:text-slate-200" title="下载当前筛选结果">
                  {exporting ? <RotateCcw size={14} className="animate-spin" /> : <Download size={14} />}
                </button>
              </div>
              <div className="mt-1 flex items-center gap-1.5">
                <span className="h-1.5 w-1.5 rounded-full bg-blue-500" />
                <span className="text-[9px] font-bold uppercase tracking-tight text-slate-400">数据监控 • OneOS 实时查询</span>
              </div>
            </div>
          </div>

          <div className="flex flex-shrink-0 items-center gap-1.5">
            <span className="hidden text-[9px] font-bold tabular-nums text-slate-400 sm:inline">
              {lastRefreshedAt ? lastRefreshedAt.toLocaleTimeString('zh-CN', { hour12: false }) : '--:--:--'}
            </span>
            <button
              type="button"
              onClick={handleManualRefresh}
              disabled={manualRefreshing}
              className="flex h-7 items-center gap-1 rounded-lg border border-blue-100 bg-blue-50 px-2 text-[9px] font-bold text-blue-600 disabled:cursor-wait disabled:opacity-60"
              title="仅刷新当前筛选结果"
            >
              <RefreshCw size={11} className={manualRefreshing ? 'animate-spin' : ''} />
              <span className="hidden sm:inline">{manualRefreshing ? '刷新中' : '刷新'}</span>
            </button>
            <div className="flex items-center gap-1 rounded-lg bg-slate-100 p-0.5">
              <button onClick={() => setSortBy('today')} className={`rounded-md px-2 py-1 text-[9px] font-bold transition-all ${sortBy === 'today' ? 'bg-white text-blue-600 shadow-sm' : 'text-slate-400'}`}>区间</button>
              <button onClick={() => setSortBy('total')} className={`rounded-md px-2 py-1 text-[9px] font-bold transition-all ${sortBy === 'total' ? 'bg-white text-blue-600 shadow-sm' : 'text-slate-400'}`}>累计</button>
              <button onClick={() => setSortOrder(sortOrder === 'desc' ? 'asc' : 'desc')} className="rounded-md p-1 text-blue-600 transition-all hover:bg-white">
                {sortOrder === 'desc' ? <ArrowDown size={12} /> : <ArrowUp size={12} />}
              </button>
            </div>
          </div>
        </div>

        <div className="flex items-center gap-2">
          <div className="grid flex-1 grid-cols-3 gap-1.5">
            <BatchMultiSelect options={filterOptions.targetNames} selected={filterTargetNames} onChange={setFilterTargetNames} placeholder="批次型号" />
            <SearchableSelect options={filterOptions.regions} value={filterRegion} onChange={setFilterRegion} placeholder="运营区域" />
            <PlateMultiSelect allPlates={plateNumbers} selected={filterPlates} onChange={setFilterPlates} placeholder="按车牌" />
          </div>
          <button
            onClick={() => setIsFilterOpen(!isFilterOpen)}
            className={`flex-shrink-0 rounded-lg border p-1.5 transition-all ${isFilterOpen || searchTerm || filterDept !== 'All' || filterCustomer !== 'All' || filterRentStatus !== 'All' || filterPlates.length > 0 || filterProject !== 'All' || filterTargetNames.length > 0 || filterBrands.length > 0 ? 'border-blue-100 bg-blue-50 text-blue-600' : 'border-transparent bg-slate-50 text-slate-400'}`}
            title="高级筛选"
          >
            <Filter size={16} />
          </button>
        </div>

        <div className="flex items-center gap-1.5 overflow-x-auto no-scrollbar">
          {([
            ['today', '今天'],
            ['yesterday', '昨天'],
            ['thisWeek', '本周'],
            ['thisMonth', '本月'],
            ['last15', '近15天'],
          ] as Array<[RangePreset, string]>).map(([preset, label]) => {
            const range = getRangePreset(preset);
            const active = rangeStart === range.start && rangeEnd === range.end;
            return (
              <button
                key={preset}
                type="button"
                onClick={() => applyRangePreset(preset)}
                className={`shrink-0 rounded-lg border px-2.5 py-1.5 text-[10px] font-black transition-all ${active ? 'border-blue-200 bg-blue-50 text-blue-600 shadow-sm' : 'border-slate-100 bg-slate-50 text-slate-500 hover:border-blue-100 hover:bg-blue-50 hover:text-blue-600'}`}
              >
                {label}
              </button>
            );
          })}
          <span className="ml-auto shrink-0 rounded-lg bg-slate-50 px-2 py-1 text-[10px] font-bold text-slate-400">{rangeLabel}</span>
        </div>
      </div>

      {/* Expandable Filter Panel */}
      <AnimatePresence>
        {isFilterOpen && (
          <motion.div
            initial={{ height: 0, opacity: 0 }}
            animate={{ height: 'auto', opacity: 1 }}
            exit={{ height: 0, opacity: 0 }}
            className="overflow-hidden"
          >
            <div className="bg-white p-4 rounded-2xl border border-gray-100 shadow-sm mb-2 space-y-4">
              {/* Date range */}
              <div className="space-y-1.5">
                <label className="text-[10px] font-bold text-slate-400 uppercase tracking-wider">查询时间区间</label>
                <div className="grid grid-cols-[1fr_auto_1fr] items-center gap-2">
                  <input
                    type="date"
                    className="w-full bg-slate-50 border-none rounded-xl py-2 px-3 text-xs focus:ring-2 focus:ring-blue-500/20 outline-none"
                    value={rangeStart}
                    onChange={(e) => setRangeStart(e.target.value)}
                  />
                  <span className="text-[10px] font-bold text-slate-300">至</span>
                  <input
                    type="date"
                    className="w-full bg-slate-50 border-none rounded-xl py-2 px-3 text-xs focus:ring-2 focus:ring-blue-500/20 outline-none"
                    value={rangeEnd}
                    onChange={(e) => setRangeEnd(e.target.value)}
                  />
                </div>
                <div className="flex items-center gap-1.5 pt-1">
                  {([
                    ['today', '今天'],
                    ['yesterday', '昨天'],
                    ['thisWeek', '本周'],
                    ['thisMonth', '本月'],
                    ['last7', '近7天'],
                    ['last15', '近15天'],
                  ] as Array<[RangePreset, string]>).map(([preset, label]) => (
                    <button
                      key={preset}
                      type="button"
                      className="rounded-lg bg-slate-50 px-2 py-1 text-[10px] font-bold text-slate-500 hover:bg-blue-50 hover:text-blue-600"
                      onClick={() => applyRangePreset(preset)}
                    >
                      {label}
                    </button>
                  ))}
                </div>
              </div>

              <div className="grid grid-cols-2 gap-3">
                {/* Department */}
                <div className="space-y-1.5">
                  <label className="text-[10px] font-bold text-slate-400 uppercase tracking-wider">按部门</label>
                  <select
                    className="w-full bg-slate-50 border-none rounded-xl py-2 px-3 text-xs focus:ring-2 focus:ring-blue-500/20 outline-none"
                    value={filterDept}
                    onChange={(e) => setFilterDept(e.target.value)}
                  >
                    <option value="All">无限制</option>
                    <option value="__EMPTY__">无值</option>
                    {departments.map(d => <option key={d} value={d}>{d}</option>)}
                  </select>
                </div>

                {/* Customer */}
                <div className="space-y-1.5">
                  <label className="text-[10px] font-bold text-slate-400 uppercase tracking-wider">按客户</label>
                  <SearchableSelect
                    options={filterOptions.customers}
                    value={filterCustomer}
                    onChange={setFilterCustomer}
                    placeholder="搜索客户"
                  />
                </div>
              </div>

              {/* Brand multi-select */}
              <div className="space-y-1.5">
                <label className="text-[10px] font-bold text-slate-400 uppercase tracking-wider">按品牌</label>
                <BatchMultiSelect
                  options={filterOptions.brands}
                  selected={filterBrands}
                  onChange={setFilterBrands}
                  placeholder="选择品牌"
                />
              </div>

              <div className="grid grid-cols-2 gap-3">
                {/* Project */}
                <div className="space-y-1.5">
                  <label className="text-[10px] font-bold text-slate-400 uppercase tracking-wider">项目</label>
                  <select
                    className="w-full bg-slate-50 border-none rounded-xl py-2 px-3 text-xs focus:ring-2 focus:ring-blue-500/20 outline-none"
                    value={filterProject}
                    onChange={(e) => setFilterProject(e.target.value)}
                  >
                    <option value="All">无限制</option>
                    {filterOptions.projects.map(p => <option key={p} value={p}>{p}</option>)}
                  </select>
                </div>

                {/* Rent Status */}
                <div className="space-y-1.5">
                  <label className="text-[10px] font-bold text-slate-400 uppercase tracking-wider">租赁状态</label>
                  <select
                    className="w-full bg-slate-50 border-none rounded-xl py-2 px-3 text-xs focus:ring-2 focus:ring-blue-500/20 outline-none"
                    value={filterRentStatus}
                    onChange={(e) => setFilterRentStatus(e.target.value)}
                  >
                    <option value="All">无限制</option>
                    {filterOptions.rentStatuses.map(s => <option key={s} value={s}>{s}</option>)}
                  </select>
                </div>
              </div>

              <div className="grid grid-cols-2 gap-3">
                {/* Entity */}
                <div className="space-y-1.5">
                  <label className="text-[10px] font-bold text-slate-400 uppercase tracking-wider">主体查询</label>
                  <select
                    className="w-full bg-slate-50 border-none rounded-xl py-2 px-3 text-xs focus:ring-2 focus:ring-blue-500/20 outline-none"
                    value={filterEntity}
                    onChange={(e) => setFilterEntity(e.target.value)}
                  >
                    <option value="All">无限制</option>
                    {filterOptions.entities.map(e => <option key={e} value={e}>{e}</option>)}
                  </select>
                </div>
              </div>

              {/* Plate Prefix */}
              <div className="space-y-1.5">
                <label className="text-[10px] font-bold text-slate-400 uppercase tracking-wider">车牌区域</label>
                <select
                  className="w-full bg-slate-50 border-none rounded-xl py-2 px-3 text-xs focus:ring-2 focus:ring-blue-500/20 outline-none"
                  value={filterPlatePrefix}
                  onChange={(e) => setFilterPlatePrefix(e.target.value)}
                >
                  <option value="All">无限制</option>
                  {filterOptions.platePrefixes.map(p => <option key={p.prefix} value={p.prefix}>{p.prefix}（{p.count}）</option>)}
                </select>
              </div>

              {/* Mileage Range */}
              <div className="grid grid-cols-2 gap-3">
                <div className="space-y-1.5">
                  <label className="text-[10px] font-bold text-slate-400 uppercase tracking-wider">里程 ≥ (KM)</label>
                  <input
                    type="number"
                    placeholder="不限"
                    className="w-full bg-slate-50 border-none rounded-xl py-2 px-3 text-xs focus:ring-2 focus:ring-blue-500/20 outline-none"
                    value={filterMileageRange.min}
                    onChange={(e) => setFilterMileageRange(prev => ({ ...prev, min: e.target.value }))}
                  />
                </div>
                <div className="space-y-1.5">
                  <label className="text-[10px] font-bold text-slate-400 uppercase tracking-wider">里程 ≤ (KM)</label>
                  <input
                    type="number"
                    placeholder="不限"
                    className="w-full bg-slate-50 border-none rounded-xl py-2 px-3 text-xs focus:ring-2 focus:ring-blue-500/20 outline-none"
                    value={filterMileageRange.max}
                    onChange={(e) => setFilterMileageRange(prev => ({ ...prev, max: e.target.value }))}
                  />
                </div>
              </div>

              <div className="flex justify-between items-center pt-4 border-t border-slate-50">
                <button
                  onClick={() => {
                    setSearchTerm('');
                    setFilterDept('All');
                    setFilterPlates([]);
                    setFilterCustomer('All');
                    setFilterProject('All');
                    setFilterEntity('All');
                    setFilterPlatePrefix('All');
                    setFilterTargetNames([]);
                    setFilterRegion('All');
                    setFilterMileageRange({ min: '', max: '' });
                    setAppliedMileageRange({ min: '', max: '' });
                    setFilterBrands([]);
                    const today = defaultMileageDate();
                    setRangeStart(today);
                    setRangeEnd(today);
                  }}
                  className="text-[10px] font-bold text-slate-400 hover:text-slate-600"
                >
                  重置所有
                </button>
                <button
                  onClick={() => {
                    setAppliedMileageRange({ ...filterMileageRange });
                    setIsFilterOpen(false);
                  }}
                  className="bg-blue-600 text-white px-6 py-2 rounded-xl text-xs font-bold shadow-lg shadow-blue-100"
                >
                  完成筛选
                </button>
              </div>
            </div>
          </motion.div>
        )}
      </AnimatePresence>

      {/* Active Filter Tags */}
      {(() => {
        const tags: { label: string; onClear: () => void }[] = [];
        if (filterTargetNames.length > 0) tags.push({
          label: filterTargetNames.length === filterOptions.targetNames.length ? '批次: 全部批次' : `批次: ${filterTargetNames.length === 1 ? filterTargetNames[0] : `${filterTargetNames[0]} 等${filterTargetNames.length}`}`,
          onClear: () => setFilterTargetNames([])
        });
        if (filterRegion !== 'All') tags.push({ label: `区域: ${filterRegion}`, onClear: () => setFilterRegion('All') });
        if (filterPlates.length > 0) tags.push({ label: `车牌: ${filterPlates.length === 1 ? filterPlates[0] : `${filterPlates[0]} 等${filterPlates.length}`}`, onClear: () => setFilterPlates([]) });
        if (filterRentStatus !== 'All') tags.push({ label: `状态: ${filterRentStatus}`, onClear: () => setFilterRentStatus('All') });
        if (filterDept !== 'All') tags.push({ label: `部门: ${filterDept === '__EMPTY__' ? '无值' : filterDept}`, onClear: () => setFilterDept('All') });
        if (filterCustomer !== 'All') tags.push({ label: `客户: ${filterCustomer === '__EMPTY__' ? '无值' : filterCustomer}`, onClear: () => setFilterCustomer('All') });
        if (filterBrands.length > 0) tags.push({
          label: `品牌: ${filterBrands.length === 1 ? filterBrands[0] : `${filterBrands[0]} 等${filterBrands.length}`}`,
          onClear: () => setFilterBrands([])
        });
        if (filterProject !== 'All') tags.push({ label: `项目: ${filterProject}`, onClear: () => setFilterProject('All') });
        if (filterEntity !== 'All') tags.push({ label: `主体: ${filterEntity}`, onClear: () => setFilterEntity('All') });
        if (searchTerm) tags.push({ label: `搜索: ${searchTerm}`, onClear: () => setSearchTerm('') });
        if (appliedMileageRange.min) tags.push({ label: `里程≥${appliedMileageRange.min}`, onClear: () => { setFilterMileageRange(prev => ({ ...prev, min: '' })); setAppliedMileageRange(prev => ({ ...prev, min: '' })); } });
        if (appliedMileageRange.max) tags.push({ label: `里程≤${appliedMileageRange.max}`, onClear: () => { setFilterMileageRange(prev => ({ ...prev, max: '' })); setAppliedMileageRange(prev => ({ ...prev, max: '' })); } });
        if (filterPlatePrefix !== 'All') tags.push({ label: `车牌段: ${filterPlatePrefix}`, onClear: () => setFilterPlatePrefix('All') });
        if (rangeStart || rangeEnd) tags.push({
          label: `区间: ${normalizeRangeLabel(rangeStart, rangeEnd)}`,
          onClear: () => {
            const today = defaultMileageDate();
            setRangeStart(today);
            setRangeEnd(today);
          }
        });
        if (tags.length === 0) return null;
        const clearAll = () => {
          setFilterDept('All'); setFilterCustomer('All'); setFilterRentStatus('All'); setFilterProject('All'); setFilterEntity('All');
          setFilterPlates([]); setSearchTerm(''); setFilterPlatePrefix('All'); setFilterTargetNames([]); setFilterRegion('All');
          setFilterMileageRange({ min: '', max: '' }); setAppliedMileageRange({ min: '', max: '' });
          setFilterBrands([]);
          const today = defaultMileageDate();
          setRangeStart(today); setRangeEnd(today);
        };
        return (
          <div className="flex flex-wrap items-center gap-1.5 rounded-xl border border-slate-200 bg-white px-3 py-2 shadow-sm">
            <span className="mr-1 text-[10px] font-black text-slate-500">已选条件</span>
            {tags.map((tag, i) => (
              <span key={i} className="inline-flex items-center gap-1 rounded-md bg-blue-50 px-2 py-1 text-[10px] font-bold text-blue-600">
                {tag.label}
                <button onClick={tag.onClear} className="hover:text-blue-800 ml-0.5">&times;</button>
              </span>
            ))}
            <button onClick={clearAll} className="text-[10px] font-bold text-rose-500 hover:text-rose-600 ml-auto">
              清除全部
            </button>
          </div>
        );
      })()}

      {/* Sticky header: KPI + 清单标题 */}
      <div className="sticky top-[44px] z-20 bg-[var(--app-bg)] pt-1 pb-1 space-y-2">
        <div className={`grid grid-cols-4 gap-2 transition-opacity ${pageLoading ? 'opacity-60' : ''}`}>
          <div className="relative col-span-2 flex min-h-[68px] flex-col justify-center overflow-hidden rounded-xl bg-slate-900 p-2.5 text-white">
            <div className="text-[7px] font-bold text-slate-500 uppercase tracking-wider">{sortBy === 'today' ? (isRangeMode ? '区间' : '当日') : '累计'}总里程</div>
            <div className="text-lg font-black tracking-tighter leading-tight flex items-baseline gap-1">
              {pageLoading ? <div className="h-5 w-20 bg-slate-700 rounded animate-pulse"></div> : <>{Math.round(sortBy === 'today' ? stats.totalToday : stats.totalAll).toLocaleString()} <span className="text-[8px] text-slate-400">km</span></>}
            </div>
            <div className="mt-0.5 truncate text-[8px] font-bold text-slate-500">{rangeLabel}</div>
          </div>
          <div className="flex min-h-[68px] flex-col justify-center rounded-xl border border-gray-100 bg-white p-2.5 shadow-sm">
            <div className="text-[7px] font-bold text-slate-400 uppercase">平均单车</div>
            <div className="text-sm font-black text-slate-800 leading-tight">{pageLoading ? <div className="h-4 w-8 bg-slate-100 rounded animate-pulse"></div> : (stats.vehicleCount > 0 ? (sortBy === 'today' ? stats.totalToday : stats.totalAll) / stats.vehicleCount : 0).toFixed(0)}</div>
            <div className="text-[7px] text-slate-400">km/台</div>
          </div>
          <div className="flex min-h-[68px] flex-col justify-center rounded-xl border border-gray-100 bg-white p-2.5 shadow-sm">
            <div className="text-[7px] font-bold text-slate-400 uppercase">监控台数</div>
            <div className="text-sm font-black text-slate-800 leading-tight">{pageLoading ? <div className="h-4 w-8 bg-slate-100 rounded animate-pulse"></div> : stats.vehicleCount}</div>
            <div className="text-[7px] text-slate-400">台</div>
          </div>
        </div>
        <div className="rounded-xl border border-slate-100 bg-white shadow-sm overflow-hidden">
          {pageLoading ? (
            <div className="h-[74px] bg-slate-50 animate-pulse" />
          ) : isRangeMode ? (
            <div className="grid grid-cols-[92px_minmax(0,1fr)_62px] items-center gap-2 px-2 py-2">
              <div className="min-w-0">
                <div className="flex items-center gap-1 text-[10px] font-black text-slate-700">
                  <CalendarDays size={12} className="text-blue-500" />
                  区间走势
                </div>
                <div className="mt-1 text-[9px] font-bold text-slate-400">{rangeDailyTotals.length} 天 · km</div>
              </div>
              <div className="h-[58px] min-w-0">
                {rangeDailyTotals.length === 0 ? (
                  <div className="flex h-full items-center justify-center rounded-lg bg-slate-50 text-[10px] font-bold text-slate-300">暂无趋势</div>
                ) : (
                  <ResponsiveContainer width="100%" height={58} minWidth={0}>
                    <BarChart data={rangeDailyTotals} margin={{ top: 4, right: 2, bottom: 0, left: 2 }}>
                      <XAxis dataKey="date" hide />
                      <Tooltip
                        formatter={(value) => [`${Number(value ?? 0).toLocaleString('zh-CN', { maximumFractionDigits: 2 })} km`, '当日里程']}
                        labelFormatter={(label) => `日期 ${String(label)}`}
                        contentStyle={{ borderRadius: 10, borderColor: '#e2e8f0', fontSize: 11 }}
                        cursor={{ fill: 'rgba(37, 99, 235, 0.06)' }}
                      />
                      {averageDailyKm > 0 && <ReferenceLine y={averageDailyKm} stroke="#f59e0b" strokeDasharray="3 3" />}
                      <Bar dataKey="totalKm" radius={[3, 3, 0, 0]} fill="#38bdf8" />
                    </BarChart>
                  </ResponsiveContainer>
                )}
              </div>
              <div className="text-right">
                <div className="text-[9px] font-black text-slate-400">日均</div>
                <div className="text-xs font-black text-slate-800">{Math.round(averageDailyKm).toLocaleString()}</div>
                <div className="text-[9px] font-bold text-slate-400">km</div>
              </div>
            </div>
          ) : (
            <div className="grid min-h-[64px] grid-cols-[minmax(0,1fr)_86px_86px] items-stretch gap-2 px-3 py-2 md:grid-cols-[minmax(0,1fr)_110px_110px]">
              <div className="flex min-w-0 flex-col justify-center">
                <div className="flex items-center gap-1 text-[10px] font-black text-slate-700">
                  <CalendarDays size={12} className="text-blue-500" />
                  单日概览
                </div>
                <div className="mt-1 truncate text-[9px] font-bold text-slate-400">{rangeLabel} · 单位 km</div>
              </div>
              <div className="flex flex-col justify-center rounded-lg bg-blue-50 px-2 py-1.5 text-right">
                <div className="text-[9px] font-black text-blue-400">当日总计</div>
                <div className="mt-1 text-xs font-black tabular-nums text-blue-700">{Math.round(stats.totalToday).toLocaleString()}</div>
              </div>
              <div className="flex flex-col justify-center rounded-lg bg-slate-50 px-2 py-1.5 text-right">
                <div className="text-[9px] font-black text-slate-400">日均单车</div>
                <div className="mt-1 text-xs font-black tabular-nums text-slate-800">{stats.vehicleCount > 0 ? Math.round(stats.totalToday / stats.vehicleCount).toLocaleString() : 0}</div>
              </div>
            </div>
          )}
        </div>
        <div className="flex items-center justify-between px-1">
          <span className="text-[9px] font-black text-slate-400 uppercase tracking-widest">车辆详情清单</span>
          <span className="text-[9px] font-bold text-slate-300">{total} 条</span>
        </div>
        <div className="hidden grid-cols-[minmax(190px,1.1fr)_minmax(160px,1fr)_130px_130px] items-center gap-3 rounded-lg border border-slate-200 bg-white px-4 py-2 text-[10px] font-bold text-slate-400 md:grid">
          <span>车牌 / 数据状态</span>
          <span>客户 / 归属</span>
          <span className="text-right">{isRangeMode ? '区间里程' : '当日里程'}</span>
          <span className="text-right">累计里程</span>
        </div>
      </div>

      {/* Vehicle List */}
      <div className="space-y-1.5">

        {pageLoading && (
          <div className="space-y-1.5">
            {Array.from({ length: 6 }).map((_, i) => (
              <div key={i} className="bg-white px-3 py-3 rounded-xl border border-slate-50 shadow-sm flex items-center justify-between animate-pulse">
                <div className="flex items-center gap-3 flex-1">
                  <div className="w-8 h-8 rounded-lg bg-slate-100"></div>
                  <div className="space-y-1.5 flex-1">
                    <div className="h-3 bg-slate-100 rounded w-24"></div>
                    <div className="h-2 bg-slate-50 rounded w-36"></div>
                  </div>
                </div>
                <div className="space-y-1.5 text-right">
                  <div className="h-4 bg-slate-100 rounded w-16 ml-auto"></div>
                  <div className="h-2 bg-slate-50 rounded w-20 ml-auto"></div>
                </div>
              </div>
            ))}
          </div>
        )}

        <div className="grid grid-cols-1 gap-1.5">
          {filteredVehicles.map((v) => {
            const highMileageAlert = isHighMileageAlert(v);
            const statisticTime = vehicleStatisticTime(v, relativeNow);
            return (
            <motion.div
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              key={v.plate}
              className="grid cursor-pointer grid-cols-[minmax(0,1fr)_auto] items-center gap-3 rounded-xl border border-slate-200 bg-white px-3 py-2.5 shadow-sm transition-all hover:border-blue-200 hover:shadow-md active:bg-slate-50 md:grid-cols-[minmax(190px,1.1fr)_minmax(160px,1fr)_130px_130px] md:px-4"
              onClick={() => setDetailVehicle(v)}
            >
              <div className="flex min-w-0 items-center gap-3 overflow-hidden">
                <div className="relative flex-shrink-0">
                  <div className="w-8 h-8 rounded-lg bg-slate-50 flex items-center justify-center">
                    <Truck size={14} className="text-slate-400" />
                  </div>
                  <div className={`absolute -bottom-0.5 -right-0.5 w-2.5 h-2.5 rounded-full border-2 border-white ${v.isOnline ? 'bg-green-500' : 'bg-slate-300'}`} title={v.isOnline ? '在线' : '离线'}></div>
                </div>
                <div className="overflow-hidden flex-1">
                  <div className="flex items-center gap-1.5">
                    <span className="text-xs font-black text-slate-900 font-mono"><Blur>{v.plate}</Blur></span>
                    <span className={`text-[8px] px-1 rounded ${v.isOnline ? 'bg-green-50 text-green-600' : 'bg-slate-100 text-slate-400'} font-bold`}>
                      {v.isOnline ? '在线' : '离线'}
                    </span>
                  </div>
                  <div className={`text-[8px] font-bold ${statisticTime.color}`} title={statisticTime.title}>
                    {statisticTime.label}
                  </div>
                  <div className="flex items-center gap-1.5 md:hidden">
                    <span className="text-[8px] text-slate-300 font-bold">{v.rentStatus || ''}{v.department ? ` · ${v.department.replace('业务', '')}` : ''}</span>
                    <span className="text-[9px] font-bold text-slate-600 truncate"><Blur>{v.customer || '-'}</Blur></span>
                  </div>
                </div>
              </div>
              <div className="hidden min-w-0 md:block">
                <div className="truncate text-xs font-bold text-slate-700"><Blur>{v.customer || '-'}</Blur></div>
                <div className="mt-1 truncate text-[9px] font-medium text-slate-400">
                  {[v.rentStatus, v.department?.replace('业务', ''), v.project].filter(Boolean).join(' · ') || '暂无归属信息'}
                </div>
              </div>
              <div className="hidden text-right md:block">
                <div className={`text-sm font-black tabular-nums ${highMileageAlert ? 'text-red-600' : 'text-blue-600'}`}>
                  {Math.max(0, v.dailyKm || 0).toLocaleString()}
                  <span className="ml-1 text-[9px] font-bold text-slate-400">km</span>
                </div>
              </div>
              <div className="hidden text-right md:block">
                <div className="text-xs font-black tabular-nums text-slate-700">
                  {v.totalKm != null ? v.totalKm.toLocaleString() : '-'}
                  <span className="ml-1 text-[9px] font-bold text-slate-400">km</span>
                </div>
              </div>
              <div className="flex flex-shrink-0 flex-col items-end text-right md:hidden">
                <div className="flex items-center gap-1 mb-0.5">
                  {!v.isDataSynced && v.totalKm == null && (
                    <div className="w-2 h-2 rounded-full bg-amber-400 animate-pulse" title="未对接车机数据"></div>
                  )}
                  <span className="text-[7px] font-black text-blue-600/50 bg-blue-50 w-3 h-3 rounded flex items-center justify-center leading-none" title={isRangeMode ? '区间内里程' : '当日里程'}>区</span>
                  <div className={`text-sm font-black leading-none ${(v.isDataSynced || v.totalKm != null) ? (highMileageAlert ? 'text-red-600' : 'text-blue-600') : 'text-amber-600'}`}>
                    {(v.isDataSynced || v.totalKm != null) ? <>{Math.max(0, v.dailyKm || 0).toLocaleString()} <span className={`text-[8px] ${highMileageAlert ? 'text-red-400' : 'text-slate-400'}`}>km</span></> : <span className="text-[7px] text-amber-500/70">未对接</span>}
                  </div>
                </div>
                <div className="flex items-center gap-1">
                  <span className="text-[7px] font-black text-slate-400/60 bg-slate-100 w-3 h-3 rounded flex items-center justify-center leading-none">总</span>
                  <span className="text-[8px] font-bold text-slate-300">
                    {v.totalKm != null ? `${v.totalKm.toLocaleString()} km` : '未对接'}
                  </span>
                </div>
              </div>
            </motion.div>
            );
          })}
        </div>

        {filteredVehicles.length === 0 && !loadingMore && (
          <div className="py-10 text-center bg-white rounded-2xl border border-dashed border-slate-100">
            <p className="text-xs font-bold text-slate-300">未找到匹配数据</p>
          </div>
        )}

        {/* 加载更多提示 */}
        {loadingMore && (
          <div className="py-4 text-center">
            <span className="text-[10px] font-bold text-slate-400">加载中...</span>
          </div>
        )}
        {!hasMore && filteredVehicles.length > 0 && (
          <div className="py-4 text-center">
            <span className="text-[10px] font-bold text-slate-300">已加载全部 {total} 条</span>
          </div>
        )}
        {/* 哨兵元素：进入视口时触发加载更多 */}
        <div ref={sentinelRef} className="h-1" />
      </div>

      <VehicleDetailModal vehicle={detailVehicle} onClose={() => setDetailVehicle(null)} />

      {/* 回到顶部按钮 */}
      <AnimatePresence>
        {showBackToTop && (
          <motion.button
            initial={{ opacity: 0, scale: 0.8 }}
            animate={{ opacity: 1, scale: 1 }}
            exit={{ opacity: 0, scale: 0.8 }}
            onClick={scrollToTop}
            className="fixed bottom-20 right-4 md:bottom-6 md:right-6 z-40 w-10 h-10 bg-blue-600 text-white rounded-full shadow-lg shadow-blue-200 flex items-center justify-center active:scale-95 transition-transform"
          >
            <ChevronsUp size={18} />
          </motion.button>
        )}
      </AnimatePresence>
    </>
  );
}
