'use client';

import { Suspense, useCallback, useEffect, useMemo, useState } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { useTranslation } from '@/hooks/useTranslation';
import { useDebounce } from '@/hooks/useDebounce';
import { usePermissions } from '@/hooks/usePermissions';
import { Can } from '@/components/common/PermissionGuard';
import { PageState } from '@/components/common/feedback/PageState';
import { toast } from '@/lib/toast';
import { colors, typography } from '@/styles/theme';
import { translateApiError } from './_lib/translateApiError';
import { pickLabel } from './_lib/i18n';
import {
  ArrowUpDown,
  Columns,
  Copy,
  Download,
  Eye,
  Filter,
  MoreHorizontal,
  Plus,
  RefreshCw,
  Search,
  X,
} from 'lucide-react';
import {
  customerApi,
  excelApi,
  locationApi,
  modelApi,
  robotApi,
  skuApi,
  supplierApi,
  type RobotCustomer,
  type RobotLocation,
  type RobotModel,
  type RobotSku,
  type RobotStatus,
  type RobotSupplier,
  type RobotUnit,
} from './_lib/api';
import { FilterDrawer } from './_lib/FilterDrawer';
import { ColumnConfig } from './_lib/ColumnConfig';
import { useFieldDefs, getFieldLabel, isSkeletonField } from './_lib/useFieldDefs';
import { V3_FIELDS, formatV3Value } from './_lib/v3-field-accessors';
import { QrPrintDialog } from './_lib/QrPrintDialog';
import { QrCode } from 'lucide-react';
import { formatMoney } from './_lib/formatMoney';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Badge } from '@/components/ui/badge';
import { Checkbox } from '@/components/ui/checkbox';
import { Skeleton } from '@/components/ui/skeleton';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';

// ============================================================
// v3 状态色板 — 按 6 部门分色 + 3 终态
// 与后端 stage-transitions.constants.ts:STAGE_TRANSITIONS 同步
// 部门色：SUPPLY=蓝 / LOGISTICS=橙 / WAREHOUSE=紫 / SALES=黄 / DELIVERY=绿 / RENTAL=青 / AFTERSALES=红 / TERMINAL=灰
// ============================================================
const STATUS_COLORS: Record<string, { bg: string; text: string }> = {
  // 采购供应链 — 蓝
  SUPPLY_PO_CREATED: { bg: '#e8f3ff', text: '#3370ff' },
  SUPPLY_IN_PRODUCTION: { bg: '#dde9ff', text: '#2655d6' },
  SUPPLY_READY_TO_SHIP: { bg: '#cce0ff', text: '#1a47b8' },
  // 物流 — 橙
  LOGISTICS_IN_TRANSIT: { bg: '#fff7e8', text: '#ff7d00' },
  LOGISTICS_BONDED: { bg: '#ffeece', text: '#d96900' },
  LOGISTICS_CUSTOMS_CLEARED: { bg: '#ffe5b3', text: '#b35900' },
  // 仓储/PDI/改装 — 紫
  WAREHOUSE_RECEIVED: { bg: '#f0e8ff', text: '#7b61ff' },
  WAREHOUSE_AT_W1_PDI: { bg: '#e8dcff', text: '#5e3fd9' },
  WAREHOUSE_MODIFICATION: { bg: '#ddc8ff', text: '#4a2db8' },
  WAREHOUSE_AT_W2: { bg: '#d0b3ff', text: '#3d1f99' },
  WAREHOUSE_AT_W2_RLE: { bg: '#c89dff', text: '#33167a' },
  WAREHOUSE_BRANDED_READY: { bg: '#e0c7ff', text: '#5e2bbf' },
  // 销售 — 黄
  SALES_RESERVED: { bg: '#fff8e6', text: '#d4a017' },
  SALES_PAYMENT_VALIDATED: { bg: '#ffefb8', text: '#a87a00' },
  // 交付 — 绿
  DELIVERY_APPROVAL: { bg: '#e6fff0', text: '#0fc66e' },
  DELIVERY_PAYMENT_COLLECTED: { bg: '#ccffdf', text: '#08a85a' },
  DELIVERY_READY: { bg: '#b3ffce', text: '#068a48' },
  DELIVERY_DELIVERED: { bg: '#80ffae', text: '#046b37' },
  // 租赁 — 青
  RENTAL_ACTIVE: { bg: '#cffae6', text: '#00866b' },
  // 售后 — 红
  AFTERSALES_TICKET: { bg: '#ffece8', text: '#f53f3f' },
  AFTERSALES_RETURN_INITIATED: { bg: '#ffe0d8', text: '#d92e2e' },
  AFTERSALES_RETURN_RECEIVED: { bg: '#ffd1c4', text: '#b82424' },
  AFTERSALES_AT_W6: { bg: '#ffc4b3', text: '#992020' },
  AFTERSALES_UNDER_REPAIR: { bg: '#ffb09e', text: '#801c1c' },
  AFTERSALES_QUOTE_APPROVAL: { bg: '#ff9b85', text: '#661616' },
  AFTERSALES_REPAIRED: { bg: '#fff0e6', text: '#e8730a' },
  // 终态 — 灰
  CLOSED: { bg: '#f7f8fa', text: '#8f959e' },
  CANCELLED: { bg: '#eef0f2', text: '#6b6f76' },
  RETURNED: { bg: '#e6e8ea', text: '#4d5158' },
};

// v3 状态流转合法转换表 — 与后端 stage-transitions.constants.ts:STAGE_TRANSITIONS 完全一致
// 含 6 条反向边（PDI 退回 / 改装失败回检 / 客户违约回库 / 审批补件 / D2 退货 / 拒绝报价）
const CLIENT_VALID_TRANSITIONS: Record<string, string[]> = {
  SUPPLY_PO_CREATED: ['SUPPLY_IN_PRODUCTION', 'CANCELLED'],
  SUPPLY_IN_PRODUCTION: ['SUPPLY_READY_TO_SHIP', 'CANCELLED'],
  SUPPLY_READY_TO_SHIP: ['LOGISTICS_IN_TRANSIT', 'CANCELLED'],
  LOGISTICS_IN_TRANSIT: ['LOGISTICS_BONDED', 'LOGISTICS_CUSTOMS_CLEARED'],
  LOGISTICS_BONDED: ['LOGISTICS_CUSTOMS_CLEARED'],
  LOGISTICS_CUSTOMS_CLEARED: ['WAREHOUSE_RECEIVED'],
  WAREHOUSE_RECEIVED: ['WAREHOUSE_AT_W1_PDI'],
  WAREHOUSE_AT_W1_PDI: ['WAREHOUSE_MODIFICATION', 'WAREHOUSE_AT_W2_RLE', 'WAREHOUSE_AT_W2', 'RETURNED'],
  WAREHOUSE_MODIFICATION: ['WAREHOUSE_AT_W2', 'WAREHOUSE_BRANDED_READY', 'WAREHOUSE_AT_W1_PDI'],
  WAREHOUSE_AT_W2: ['WAREHOUSE_BRANDED_READY'],
  WAREHOUSE_AT_W2_RLE: ['WAREHOUSE_BRANDED_READY'],
  WAREHOUSE_BRANDED_READY: ['SALES_RESERVED', 'CANCELLED'],
  SALES_RESERVED: ['SALES_PAYMENT_VALIDATED', 'CANCELLED', 'WAREHOUSE_BRANDED_READY'],
  SALES_PAYMENT_VALIDATED: ['DELIVERY_APPROVAL', 'DELIVERY_PAYMENT_COLLECTED'],
  DELIVERY_PAYMENT_COLLECTED: ['DELIVERY_APPROVAL'],
  DELIVERY_APPROVAL: ['DELIVERY_READY', 'SALES_PAYMENT_VALIDATED'],
  DELIVERY_READY: ['DELIVERY_DELIVERED'],
  DELIVERY_DELIVERED: ['AFTERSALES_TICKET', 'RENTAL_ACTIVE', 'RETURNED', 'CLOSED'],
  RENTAL_ACTIVE: ['AFTERSALES_AT_W6', 'AFTERSALES_TICKET', 'CLOSED'],
  AFTERSALES_TICKET: ['AFTERSALES_RETURN_INITIATED', 'AFTERSALES_UNDER_REPAIR', 'DELIVERY_DELIVERED', 'RENTAL_ACTIVE'],
  AFTERSALES_RETURN_INITIATED: ['AFTERSALES_RETURN_RECEIVED'],
  AFTERSALES_RETURN_RECEIVED: ['AFTERSALES_AT_W6'],
  AFTERSALES_AT_W6: ['AFTERSALES_UNDER_REPAIR', 'AFTERSALES_QUOTE_APPROVAL', 'RETURNED', 'CLOSED'],
  AFTERSALES_UNDER_REPAIR: ['AFTERSALES_REPAIRED', 'AFTERSALES_QUOTE_APPROVAL'],
  AFTERSALES_QUOTE_APPROVAL: ['AFTERSALES_UNDER_REPAIR', 'RETURNED', 'CLOSED', 'DELIVERY_DELIVERED'],
  AFTERSALES_REPAIRED: ['DELIVERY_DELIVERED', 'WAREHOUSE_BRANDED_READY'],
  CLOSED: [],
  CANCELLED: ['SUPPLY_READY_TO_SHIP', 'WAREHOUSE_BRANDED_READY'],
  RETURNED: [],
};

// 6 部门 + 终态 — 用于状态筛选器 / Dashboard 漏斗按部门分组
export const STAGE_DEPARTMENTS = [
  { code: 'SUPPLY', color: '#3370ff', stages: ['SUPPLY_PO_CREATED', 'SUPPLY_IN_PRODUCTION', 'SUPPLY_READY_TO_SHIP'] },
  { code: 'LOGISTICS', color: '#ff7d00', stages: ['LOGISTICS_IN_TRANSIT', 'LOGISTICS_BONDED', 'LOGISTICS_CUSTOMS_CLEARED'] },
  { code: 'WAREHOUSE', color: '#7b61ff', stages: ['WAREHOUSE_RECEIVED', 'WAREHOUSE_AT_W1_PDI', 'WAREHOUSE_MODIFICATION', 'WAREHOUSE_AT_W2', 'WAREHOUSE_AT_W2_RLE', 'WAREHOUSE_BRANDED_READY'] },
  { code: 'SALES', color: '#d4a017', stages: ['SALES_RESERVED', 'SALES_PAYMENT_VALIDATED'] },
  { code: 'DELIVERY', color: '#0fc66e', stages: ['DELIVERY_APPROVAL', 'DELIVERY_PAYMENT_COLLECTED', 'DELIVERY_READY', 'DELIVERY_DELIVERED'] },
  { code: 'RENTAL', color: '#00866b', stages: ['RENTAL_ACTIVE'] },
  { code: 'AFTERSALES', color: '#f53f3f', stages: ['AFTERSALES_TICKET', 'AFTERSALES_RETURN_INITIATED', 'AFTERSALES_RETURN_RECEIVED', 'AFTERSALES_AT_W6', 'AFTERSALES_UNDER_REPAIR', 'AFTERSALES_QUOTE_APPROVAL', 'AFTERSALES_REPAIRED'] },
  { code: 'TERMINAL', color: '#8f959e', stages: ['CLOSED', 'CANCELLED', 'RETURNED'] },
] as const;

const ALL_STATUSES: RobotStatus[] = STAGE_DEPARTMENTS.flatMap((d) => d.stages) as RobotStatus[];

function toNum(v: number | string | null | undefined): number | null {
  if (v == null || v === '') return null;
  const n = Number(v);
  return Number.isFinite(n) ? n : null;
}

function formatDate(v: string | Date): string {
  const d = new Date(v);
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, '0');
  const day = String(d.getDate()).padStart(2, '0');
  return `${y}-${m}-${day}`;
}

const EMPTY_PLACEHOLDER = (
  <span style={{ color: '#bbbfc4' }}>-</span>
);

function RobotListPageContent() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const { t, locale } = useTranslation();
  const { hasPermission, isAdmin } = usePermissions();
  const rm = t.robotManager;
  const { fieldDefs, listFields } = useFieldDefs();

  // 所有可作为列显示的动态字段（不过滤 showInList；过滤骨架字段）
  const allDynamicFields = useMemo(
    () => fieldDefs.filter((d) => !isSkeletonField(d.key)).sort((a, b) => a.sortOrder - b.sortOrder),
    [fieldDefs],
  );

  // 默认可见列 = 固定列（除 FFSN 外都默认可见）+ showInList 为 true 的动态字段
  const defaultVisibleKeys = useMemo(
    () => [
      'ffsn',
      'model-sku',
      'currentStatus',
      'location',
      'supplier',
      'customer',
      ...listFields.map((d) => d.key),
      'grossMargin',
      'updatedAt',
    ],
    [listFields],
  );

  // 列显示偏好：存用户选中的 key 列表（localStorage）。为 null 表示未设置过 → 用默认
  const [visibleColsSet, setVisibleColsSet] = useState<Set<string> | null>(() => {
    if (typeof window === 'undefined') return null;
    try {
      const raw = localStorage.getItem('robotListVisibleCols');
      if (raw) return new Set(JSON.parse(raw));
    } catch {}
    return null;
  });

  const effectiveVisible = visibleColsSet ?? new Set(defaultVisibleKeys);
  const isVisible = (key: string) => effectiveVisible.has(key);
  const visibleListFields = allDynamicFields.filter((d) => isVisible(d.key));

  const [robots, setRobots] = useState<RobotUnit[]>([]);
  const [loading, setLoading] = useState(true);
  const [hasLoadedOnce, setHasLoadedOnce] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // 筛选偏好持久化 helper（含 search / status / model / supplier / sku / customer / location / pageSize）
  type FilterPrefs = {
    statusFilter?: string;
    modelIdFilter?: string;
    supplierIdFilter?: string;
    skuIdFilter?: string;
    customerIdFilter?: string;
    locationIdFilter?: string;
    pageSize?: number;
  };
  const FILTER_PREFS_KEY = 'robotListFilterPrefs';
  const FILTER_PREFS_VERSION = 1; // 加字段时 bump，旧 localStorage 静默丢弃避免反序列化错位
  const loadFilterPrefs = (): FilterPrefs => {
    if (typeof window === 'undefined') return {};
    try {
      const raw = localStorage.getItem(FILTER_PREFS_KEY);
      if (!raw) return {};
      const parsed = JSON.parse(raw);
      if (parsed?._v !== FILTER_PREFS_VERSION) return {};
      const { _v, ...prefs } = parsed;
      return prefs;
    } catch {
      return {};
    }
  };
  const initialPrefs = loadFilterPrefs();

  // filters
  const [searchTerm, setSearchTerm] = useState(searchParams.get('search') || '');
  const debouncedSearch = useDebounce(searchTerm, 300);
  const [statusFilter, setStatusFilter] = useState<string>(() => searchParams.get('status') || initialPrefs.statusFilter || '');
  const [modelIdFilter, setModelIdFilter] = useState(initialPrefs.modelIdFilter ?? '');
  const [supplierIdFilter, setSupplierIdFilter] = useState(initialPrefs.supplierIdFilter ?? '');
  const [skuIdFilter, setSkuIdFilter] = useState(initialPrefs.skuIdFilter ?? '');
  const [customerIdFilter, setCustomerIdFilter] = useState(initialPrefs.customerIdFilter ?? '');
  const [locationIdFilter, setLocationIdFilter] = useState(initialPrefs.locationIdFilter ?? '');
  const [filterDrawerOpen, setFilterDrawerOpen] = useState(false);

  // data for filter dropdowns
  const [models, setModels] = useState<RobotModel[]>([]);
  const [suppliers, setSuppliers] = useState<RobotSupplier[]>([]);
  const [skus, setSkus] = useState<RobotSku[]>([]);
  const [customers, setCustomers] = useState<RobotCustomer[]>([]);
  const [locations, setLocations] = useState<RobotLocation[]>([]);

  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());
  const [page, setPage] = useState(parseInt(searchParams.get('page') || '1'));
  const [pageSize, setPageSize] = useState<number>(initialPrefs.pageSize ?? 20);
  const [totalPages, setTotalPages] = useState(1);
  const [total, setTotal] = useState(0);

  // 持久化筛选 + 每页行数
  useEffect(() => {
    if (typeof window === 'undefined') return;
    const prefs = {
      _v: FILTER_PREFS_VERSION,
      statusFilter,
      modelIdFilter,
      supplierIdFilter,
      skuIdFilter,
      customerIdFilter,
      locationIdFilter,
      pageSize,
    };
    try {
      localStorage.setItem(FILTER_PREFS_KEY, JSON.stringify(prefs));
    } catch {}
  }, [statusFilter, modelIdFilter, supplierIdFilter, skuIdFilter, customerIdFilter, locationIdFilter, pageSize]);

  // bulk status change dialog
  const [showBulkDialog, setShowBulkDialog] = useState(false);
  const [bulkTargetStatus, setBulkTargetStatus] = useState<RobotStatus | ''>('');
  const [bulkRemark, setBulkRemark] = useState('');
  const [bulkProcessing, setBulkProcessing] = useState(false);
  const [showQrDialog, setShowQrDialog] = useState(false);

  const canChangeStatus = isAdmin || hasPermission('robot-manager:change-status');

  useEffect(() => {
    modelApi.list({ enabledOnly: 'true' }).then(setModels).catch(() => {});
    supplierApi.list({ enabledOnly: 'true' }).then(setSuppliers).catch(() => {});
    skuApi.list({ enabledOnly: 'true' }).then(setSkus).catch(() => {});
    customerApi.list({ enabledOnly: 'true' }).then(setCustomers).catch(() => {});
    locationApi.list({ enabledOnly: 'true' }).then(setLocations).catch(() => {});
  }, []);

  const loadRobots = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      const response = await robotApi.list({
        search: debouncedSearch || undefined,
        currentStage: statusFilter ? (statusFilter as RobotStatus) : undefined,
        modelId: modelIdFilter || undefined,
        supplierId: supplierIdFilter || undefined,
        skuId: skuIdFilter || undefined,
        customerId: customerIdFilter || undefined,
        locationId: locationIdFilter || undefined,
        page,
        limit: pageSize,
      });
      const items = response.items || [];
      setRobots(items);
      setTotalPages(response.totalPages || 1);
      setTotal(response.total || 0);
      // 存当前列表顺序，供详情页「上一台/下一台」导航
      if (typeof window !== 'undefined') {
        sessionStorage.setItem('robotNavIds', JSON.stringify(items.map((r) => r.id)));
      }
    } catch (err: any) {
      console.error('Failed to load robots:', err);
      setError(translateApiError(err, rm) || rm.messages.loadFailed);
      toast.error(translateApiError(err, rm) || rm.messages.loadFailed);
    } finally {
      setLoading(false);
      setHasLoadedOnce(true);
    }
  }, [page, pageSize, debouncedSearch, statusFilter, modelIdFilter, supplierIdFilter, skuIdFilter, customerIdFilter, locationIdFilter, rm.messages.loadFailed]);

  useEffect(() => {
    loadRobots();
  }, [loadRobots]);

  const handleClearFilters = () => {
    setSearchTerm('');
    setStatusFilter('');
    setModelIdFilter('');
    setSupplierIdFilter('');
    setSkuIdFilter('');
    setCustomerIdFilter('');
    setLocationIdFilter('');
    setPage(1);
  };

  const drawerActiveCount = [skuIdFilter, customerIdFilter, locationIdFilter].filter(Boolean).length;

  // 批量变更：计算对所有选中设备都合法的目标状态集合
  const validBulkTargets = (() => {
    if (selectedIds.size === 0) return new Set<RobotStatus>();
    const selectedStatuses = new Set(
      [...selectedIds]
        .map((id) => {
          const r = robots.find((r) => r.id === id);
          return (r?.snapshot?.currentStage ?? r?.currentStatus) as RobotStatus | undefined;
        })
        .filter((s): s is RobotStatus => !!s),
    );
    if (selectedStatuses.size === 0) return new Set<RobotStatus>();
    const iter = selectedStatuses.values().next().value as RobotStatus;
    let common = new Set<RobotStatus>(CLIENT_VALID_TRANSITIONS[iter] || []);
    for (const from of selectedStatuses) {
      const allowed = new Set(CLIENT_VALID_TRANSITIONS[from] || []);
      common = new Set([...common].filter((t) => allowed.has(t)));
    }
    return common;
  })();

  const activeFiltersCount = [
    searchTerm,
    statusFilter,
    modelIdFilter,
    supplierIdFilter,
    skuIdFilter,
    customerIdFilter,
    locationIdFilter,
  ].filter(Boolean).length;

  const handleSelectRow = (id: string) => {
    const next = new Set(selectedIds);
    if (next.has(id)) next.delete(id);
    else next.add(id);
    setSelectedIds(next);
  };

  const handleSelectAll = () => {
    if (selectedIds.size === robots.length) {
      setSelectedIds(new Set());
    } else {
      setSelectedIds(new Set(robots.map((r) => r.id)));
    }
  };

  const computeGrossMargin = (
    salesPrice: number | string | null | undefined,
    cost: number | string | null | undefined,
  ): string => {
    const sp = toNum(salesPrice);
    const c = toNum(cost);
    if (sp == null || c == null) return '-';
    return (sp - c).toFixed(2);
  };

  const handleBulkStatusChange = async () => {
    if (selectedIds.size === 0) {
      toast.error(rm.listPage.selectDevices);
      return;
    }
    if (!bulkTargetStatus) {
      toast.error(rm.listPage.selectTargetStatus);
      return;
    }
    if (bulkTargetStatus === 'CANCELLED' && !bulkRemark.trim()) {
      toast.error(rm.listPage.remarkRequired);
      return;
    }
    try {
      setBulkProcessing(true);
      const result = await robotApi.bulkStatusChange({
        robotUnitIds: Array.from(selectedIds),
        targetStatus: bulkTargetStatus as RobotStatus,
        remark: bulkRemark || undefined,
      });
      if (result.failed.length > 0) {
        toast.info(
          rm.listPage.bulkPartial
            .replace('{success}', String(result.success.length))
            .replace('{failed}', String(result.failed.length)),
        );
      } else {
        toast.success(
          rm.listPage.bulkSuccess.replace('{count}', String(result.success.length)),
        );
      }
      setShowBulkDialog(false);
      setBulkTargetStatus('');
      setBulkRemark('');
      setSelectedIds(new Set());
      loadRobots();
    } catch (err: any) {
      toast.error(translateApiError(err, rm) || rm.messages.bulkStatusChangeFailed);
    } finally {
      setBulkProcessing(false);
    }
  };

  const handleExport = async () => {
    try {
      await excelApi.export({
        currentStage: statusFilter ? (statusFilter as RobotStatus) : undefined,
        modelId: modelIdFilter || undefined,
        supplierId: supplierIdFilter || undefined,
      });
      toast.success(rm.messages.exportSuccess);
    } catch (err: any) {
      toast.error(translateApiError(err, rm) || rm.messages.exportFailed);
    }
  };

  const getStatusBadge = (status: RobotStatus) => {
    const style = STATUS_COLORS[status];
    return (
      <Badge
        variant="secondary"
        className="inline-flex items-center px-2 py-0.5 text-xs rounded"
        style={{ backgroundColor: style.bg, color: style.text }}
      >
        {rm.status[status]}
      </Badge>
    );
  };

  // 首次加载骨架屏
  if (loading && !hasLoadedOnce) {
    return (
      <div className="h-full flex flex-col" style={{ backgroundColor: colors.bgSecondary }}>
        <div className="bg-white border-b" style={{ borderColor: colors.border }}>
          <div className="px-6 h-12 flex items-center">
            <Skeleton className="h-6 w-48" />
          </div>
        </div>
        <div className="flex-1 overflow-auto p-6">
          <Skeleton className="h-10 w-full mb-4" />
          <Skeleton className="h-96 w-full" />
        </div>
      </div>
    );
  }

  return (
    <div className="h-full flex flex-col" style={{ backgroundColor: colors.bgSecondary }}>
      {/* 标题栏 h-12 */}
      <div className="bg-white border-b" style={{ borderColor: colors.border }}>
        <div className="px-6 h-12 flex items-center justify-between">
          <div className="flex items-center gap-3">
            <h1 className={typography.h4}>{rm.subtitle}</h1>
            <span className={typography.caption}>
              {rm.listPage.totalDevices}: {total}
            </span>
          </div>
          <div className="flex items-center gap-2">
            {activeFiltersCount > 0 && (
              <Button variant="ghost" size="sm" onClick={handleClearFilters}>
                <X className="w-4 h-4 mr-1" />
                {rm.filters.clearFilters} ({activeFiltersCount})
              </Button>
            )}
            <Button variant="outline" size="sm" onClick={loadRobots} disabled={loading}>
              <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />
            </Button>
            <Can permission="robot-manager:export">
              <Button variant="outline" size="sm" onClick={handleExport}>
                <Download className="w-4 h-4 mr-1" />
                {rm.actions.export}
              </Button>
            </Can>
            <Can permission="robot-manager:create">
              <Button
                size="sm"
                onClick={() => router.push('/robot-manager/create')}
                style={{ backgroundColor: colors.primary }}
              >
                <Plus className="w-4 h-4 mr-1" />
                {rm.actions.create}
              </Button>
            </Can>
          </div>
        </div>
      </div>

      {/* 内容区：筛选 + 表格合并成一张卡片 */}
      <div className="flex-1 overflow-auto p-6">
        <div
          className="bg-white rounded-lg shadow-sm overflow-hidden flex flex-col"
          style={{ border: `1px solid ${colors.border}` }}
        >
          {/* 筛选栏 */}
          <div
            className="px-4 py-3 flex items-center gap-3"
            style={{ borderBottom: `1px solid ${colors.border}` }}
          >
          {/* 搜索 */}
          <div className="flex-1 max-w-md relative">
            <Search
              className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4"
              style={{ color: colors.textTertiary }}
            />
            <Input
              value={searchTerm}
              onChange={(e) => {
                setSearchTerm(e.target.value);
                setPage(1);
              }}
              placeholder={rm.placeholders.search}
              className="w-full h-9 pl-9 pr-9 text-sm"
              data-hotkey-search="true"
            />
            {searchTerm && searchTerm !== debouncedSearch && (
              <div className="absolute right-3 top-1/2 -translate-y-1/2">
                <div
                  className="w-4 h-4 border-2 rounded-full animate-spin"
                  style={{ borderColor: colors.primary, borderTopColor: 'transparent' }}
                />
              </div>
            )}
          </div>

          {/* 状态筛选 */}
          <Select
            value={statusFilter || 'all'}
            onValueChange={(v) => {
              setStatusFilter(v === 'all' ? '' : v);
              setPage(1);
            }}
          >
            <SelectTrigger className="w-[170px] h-9 gap-1.5">
              <Filter className="w-3.5 h-3.5 shrink-0" style={{ color: colors.textTertiary }} />
              <span className="text-xs shrink-0" style={{ color: colors.textTertiary }}>
                {rm.fields.currentStatus}
              </span>
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">{rm.filters.all}</SelectItem>
              {ALL_STATUSES.map((s) => (
                <SelectItem key={s} value={s}>
                  {rm.status[s]}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>

          {/* 型号筛选 */}
          <Select
            value={modelIdFilter || 'all'}
            onValueChange={(v) => {
              setModelIdFilter(v === 'all' ? '' : v);
              setPage(1);
            }}
          >
            <SelectTrigger className="w-[200px] h-9 gap-1.5">
              <Filter className="w-3.5 h-3.5 shrink-0" style={{ color: colors.textTertiary }} />
              <span className="text-xs shrink-0" style={{ color: colors.textTertiary }}>
                {rm.fields.model}
              </span>
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">{rm.filters.all}</SelectItem>
              {models.map((m) => (
                <SelectItem key={m.id} value={m.id}>
                  {m.code} - {m.name}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>

          {/* 供应商筛选 */}
          <Select
            value={supplierIdFilter || 'all'}
            onValueChange={(v) => {
              setSupplierIdFilter(v === 'all' ? '' : v);
              setPage(1);
            }}
          >
            <SelectTrigger className="w-[200px] h-9 gap-1.5">
              <Filter className="w-3.5 h-3.5 shrink-0" style={{ color: colors.textTertiary }} />
              <span className="text-xs shrink-0" style={{ color: colors.textTertiary }}>
                {rm.purchase.supplier}
              </span>
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">{rm.filters.all}</SelectItem>
              {suppliers.map((s) => (
                <SelectItem key={s.id} value={s.id}>
                  {s.code} - {s.name}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>

          {/* 更多筛选（SKU / 客户 / 位置） */}
          <Button
            variant="outline"
            size="sm"
            className="h-9 gap-1.5 relative"
            onClick={() => setFilterDrawerOpen(true)}
          >
            <Filter className="w-3.5 h-3.5" />
            {rm.filters.moreFilters}
            {drawerActiveCount > 0 && (
              <span
                className="ml-1 inline-flex items-center justify-center min-w-[18px] h-[18px] rounded-full text-[10px] font-semibold px-1.5"
                style={{ backgroundColor: colors.primary, color: 'white' }}
              >
                {drawerActiveCount}
              </span>
            )}
          </Button>

          {/* 列配置：固定列 + 全部动态字段（包括 showInList:false 的）统一管理 */}
          <ColumnConfig
            storageKey="robotListVisibleCols"
            triggerLabel={rm.listPage.columnsConfig}
            value={[...effectiveVisible]}
            onChange={(visible) => {
              const next = new Set(visible);
              // FFSN 必选
              next.add('ffsn');
              setVisibleColsSet(next);
              try {
                localStorage.setItem('robotListVisibleCols', JSON.stringify([...next]));
              } catch {}
            }}
            options={[
              { key: 'ffsn', label: rm.fields.ffsn, alwaysVisible: true },
              { key: 'model-sku', label: `${rm.fields.model} / ${rm.fields.sku}` },
              { key: 'currentStatus', label: rm.fields.currentStatus },
              { key: 'location', label: rm.fields.location },
              { key: 'supplier', label: rm.purchase.supplier },
              { key: 'customer', label: rm.sales.customerName },
              ...allDynamicFields.map((d) => ({ key: d.key, label: getFieldLabel(d, locale) })),
              { key: 'grossMargin', label: rm.finance.grossMargin },
              { key: 'updatedAt', label: rm.fields.updatedAt },
              // v3 业务字段（82 个，业务术语命名；已有数据的会取值，未有数据 fallback "—"）
              ...V3_FIELDS
                // 排除已经在固定列里的（避免重复）
                .filter((f) => !['FF SN', 'FF SN (key)', 'Model (full)', 'Lifecycle Status', 'Location', 'Customer', 'Partner / Supplier'].includes(f.field))
                .map((f) => ({ key: `v3:${f.field}`, label: pickLabel(f, locale) })),
            ]}
          />
        </div>

        {/* 批量操作栏 */}
        {selectedIds.size > 0 && (
          <div
            className="px-4 py-2 flex items-center justify-between"
            style={{ backgroundColor: '#eef4ff', borderBottom: `1px solid ${colors.border}` }}
          >
            <span className="text-sm" style={{ color: colors.primary }}>
              {rm.listPage.selectedCount.replace('{count}', String(selectedIds.size))}
            </span>
            <div className="flex gap-2">
              <Button
                variant="outline"
                size="sm"
                disabled={selectedIds.size < 2 || selectedIds.size > 4}
                onClick={() => {
                  const ids = [...selectedIds].join(',');
                  router.push(`/robot-manager/compare?ids=${ids}`);
                }}
                title={selectedIds.size < 2 || selectedIds.size > 4 ? rm.compare.compareMinHint : undefined}
              >
                <Columns className="w-4 h-4 mr-1" />
                {rm.compare.compareButton}
              </Button>
              {canChangeStatus && (
                <Button variant="outline" size="sm" onClick={() => setShowBulkDialog(true)}>
                  <ArrowUpDown className="w-4 h-4 mr-1" />
                  {rm.actions.bulkChangeStatus}
                </Button>
              )}
              <Button variant="outline" size="sm" onClick={() => setShowQrDialog(true)}>
                <QrCode className="w-4 h-4 mr-1" />
                打印二维码
              </Button>
            </div>
          </div>
        )}

        {/* 批量打印二维码 Dialog */}
        <QrPrintDialog
          open={showQrDialog}
          onOpenChange={setShowQrDialog}
          robots={robots.filter((r) => selectedIds.has(r.id))}
        />

        {/* 表格区域 */}
        {error ? (
          <div className="p-6">
            <PageState
              variant="error"
              title={rm.messages.loadFailed}
              description={error}
              actionLabel={rm.actions.refresh}
              onAction={loadRobots}
            />
          </div>
        ) : robots.length === 0 && hasLoadedOnce && !loading ? (
          <div className="p-6">
            <PageState variant="empty" title={rm.messages.noDataMessage} />
          </div>
        ) : (
          <>
            <Table className="[&_th]:h-11 [&_th]:px-3 [&_th]:whitespace-nowrap [&_th]:text-xs [&_th]:font-semibold [&_td]:py-2.5 [&_td]:px-3 [&_td]:whitespace-nowrap [&_tbody_tr]:!border-0 [&_tbody_tr:nth-child(even)]:bg-[#fafbfc]">
              <TableHeader className="bg-[#f7f8fa] [&_tr]:border-b [&_tr]:border-[#ebedf0]">
                <TableRow className="hover:bg-transparent border-0">
                  <TableHead className="w-[40px]" style={{ color: colors.textSecondary }}>
                    <Checkbox
                      checked={selectedIds.size === robots.length && robots.length > 0}
                      onCheckedChange={handleSelectAll}
                    />
                  </TableHead>
                  <TableHead style={{ color: colors.textSecondary }}>{rm.fields.ffsn}</TableHead>
                  {isVisible('model-sku') && (
                    <TableHead style={{ color: colors.textSecondary }}>
                      {rm.fields.model} / {rm.fields.sku}
                    </TableHead>
                  )}
                  {isVisible('currentStatus') && (
                    <TableHead style={{ color: colors.textSecondary }}>
                      {rm.fields.currentStatus}
                    </TableHead>
                  )}
                  {isVisible('location') && (
                    <TableHead style={{ color: colors.textSecondary }}>{rm.fields.location}</TableHead>
                  )}
                  {isVisible('supplier') && (
                    <TableHead style={{ color: colors.textSecondary }}>
                      {rm.purchase.supplier}
                    </TableHead>
                  )}
                  {isVisible('customer') && (
                    <TableHead style={{ color: colors.textSecondary }}>
                      {rm.sales.customerName}
                    </TableHead>
                  )}
                  {/* 动态列表头 */}
                  {visibleListFields.map((def) => (
                    <TableHead
                      key={def.key}
                      className={def.type === 'money' || def.type === 'number' ? 'text-right' : ''}
                      style={{ color: colors.textSecondary }}
                    >
                      {getFieldLabel(def, locale)}
                    </TableHead>
                  ))}
                  {isVisible('grossMargin') && (
                    <TableHead className="text-right" style={{ color: colors.textSecondary }}>
                      {rm.finance.grossMargin}
                    </TableHead>
                  )}
                  {isVisible('updatedAt') && (
                    <TableHead className="text-right" style={{ color: colors.textSecondary }}>
                      {rm.fields.updatedAt}
                    </TableHead>
                  )}
                  {/* v3 业务字段列头（用户从 ColumnConfig 勾选的） */}
                  {V3_FIELDS.filter((f) => isVisible(`v3:${f.field}`)).map((f) => (
                    <TableHead
                      key={`v3-head:${f.field}`}
                      className={f.renderType === 'money' ? 'text-right' : ''}
                      style={{ color: colors.textSecondary }}
                    >
                      {pickLabel(f, locale)}
                    </TableHead>
                  ))}
                  <TableHead className="w-[50px]" />
                </TableRow>
              </TableHeader>
              <TableBody>
                {loading
                  ? Array.from({ length: 5 }).map((_, i) => (
                      <TableRow key={i}>
                        {Array.from({
                          length:
                            2 /* checkbox + ffsn */ +
                            ['model-sku', 'currentStatus', 'location', 'supplier', 'customer', 'grossMargin', 'updatedAt'].filter(isVisible).length +
                            visibleListFields.length +
                            1 /* 操作列 */,
                        }).map((_, j) => (
                          <TableCell key={j}>
                            <Skeleton className="h-4 w-full" />
                          </TableCell>
                        ))}
                      </TableRow>
                    ))
                  : robots.map((robot) => (
                      <TableRow
                        key={robot.id}
                        className="cursor-pointer hover:!bg-[#f3f6ff]"
                        onClick={() => router.push(`/robot-manager/${robot.id}`)}
                      >
                        <TableCell onClick={(e) => e.stopPropagation()}>
                          <Checkbox
                            checked={selectedIds.has(robot.id)}
                            onCheckedChange={() => handleSelectRow(robot.id)}
                          />
                        </TableCell>
                        <TableCell className="whitespace-nowrap">
                          <span className={typography.link}>{robot.ffsn}</span>
                        </TableCell>
                        {isVisible('model-sku') && (
                          <TableCell>
                            <div className="flex flex-col min-w-0 max-w-[180px]">
                              <span className={`${typography.body} truncate`}>
                                {robot.model?.name ?? EMPTY_PLACEHOLDER}
                              </span>
                              <span className={`${typography.caption} truncate`}>
                                {robot.sku?.code ?? EMPTY_PLACEHOLDER}
                              </span>
                            </div>
                          </TableCell>
                        )}
                        {isVisible('currentStatus') && (
                          <TableCell>{getStatusBadge((robot.snapshot?.currentStage ?? robot.currentStatus) as RobotStatus)}</TableCell>
                        )}
                        {isVisible('location') && (
                          <TableCell className={typography.body}>
                            <span className="block max-w-[140px] truncate">
                              {robot.location?.name ?? EMPTY_PLACEHOLDER}
                            </span>
                          </TableCell>
                        )}
                        {isVisible('supplier') && (
                          <TableCell className={typography.body}>
                            <span className="block max-w-[140px] truncate">
                              {robot.supplier?.name ?? EMPTY_PLACEHOLDER}
                            </span>
                          </TableCell>
                        )}
                        {isVisible('customer') && (
                          <TableCell className={typography.body}>
                            <span className="block max-w-[140px] truncate">
                              {robot.customer?.name ?? EMPTY_PLACEHOLDER}
                            </span>
                          </TableCell>
                        )}
                        {/* 动态列单元格 */}
                        {visibleListFields.map((def) => {
                          const val = (robot as any)[def.key] ?? (robot.metadata as any)?.[def.key];
                          if (def.type === 'money' || def.type === 'number') {
                            const n = toNum(val);
                            return (
                              <TableCell key={def.key} className={`text-right tabular-nums ${typography.body}`}>
                                {n != null ? (def.type === 'money' ? formatMoney(n, (robot.metadata as any)?.currency) : String(n)) : EMPTY_PLACEHOLDER}
                              </TableCell>
                            );
                          }
                          if (def.type === 'date' || def.type === 'datetime') {
                            return (
                              <TableCell key={def.key} className={typography.body}>
                                {val ? formatDate(val) : EMPTY_PLACEHOLDER}
                              </TableCell>
                            );
                          }
                          if (def.type === 'select') {
                            const found = (def.options ?? []).find((o) => o.code === val);
                            return (
                              <TableCell key={def.key} className={typography.body}>
                                {found?.label || val || EMPTY_PLACEHOLDER}
                              </TableCell>
                            );
                          }
                          if (def.type === 'bool') {
                            return (
                              <TableCell key={def.key} className={typography.body}>
                                {val === true ? '✓' : val === false ? '✗' : EMPTY_PLACEHOLDER}
                              </TableCell>
                            );
                          }
                          return (
                            <TableCell key={def.key} className={typography.body}>
                              <span className="block max-w-[140px] truncate">
                                {val || EMPTY_PLACEHOLDER}
                              </span>
                            </TableCell>
                          );
                        })}
                        {isVisible('grossMargin') && (
                          <TableCell className="text-right whitespace-nowrap tabular-nums">
                            {(() => {
                              const gm = robot.grossMargin;
                              if (gm == null) return EMPTY_PLACEHOLDER;
                              const color =
                                gm > 0 ? colors.success : gm < 0 ? colors.error : colors.textPrimary;
                              return (
                                <span className="text-sm font-medium" style={{ color }}>
                                  {formatMoney(gm, (robot.metadata as any)?.currency)}
                                </span>
                              );
                            })()}
                          </TableCell>
                        )}
                        {isVisible('updatedAt') && (
                          <TableCell className={`text-right whitespace-nowrap tabular-nums ${typography.bodySecondary}`}>
                            {formatDate(robot.updatedAt)}
                          </TableCell>
                        )}
                        {/* v3 业务字段列：accessor 取值 → formatV3Value 渲染；缺数据时 "—" */}
                        {V3_FIELDS.filter((f) => isVisible(`v3:${f.field}`)).map((f) => {
                          const raw = f.accessor ? f.accessor(robot) : undefined;
                          return (
                            <TableCell
                              key={`v3-cell:${f.field}:${robot.id}`}
                              className={f.renderType === 'money' ? 'text-right whitespace-nowrap tabular-nums' : 'whitespace-nowrap'}
                              style={{ color: raw == null ? colors.textTertiary : colors.textPrimary }}
                            >
                              {formatV3Value(f, raw)}
                            </TableCell>
                          );
                        })}
                        <TableCell onClick={(e) => e.stopPropagation()}>
                          <DropdownMenu>
                            <DropdownMenuTrigger asChild>
                              <Button variant="ghost" size="sm" className="h-8 w-8 p-0">
                                <MoreHorizontal className="w-4 h-4" />
                              </Button>
                            </DropdownMenuTrigger>
                            <DropdownMenuContent align="end">
                              <DropdownMenuItem
                                onClick={() => router.push(`/robot-manager/${robot.id}`)}
                              >
                                <Eye className="w-4 h-4 mr-2" />
                                {rm.actions.viewDetails}
                              </DropdownMenuItem>
                              {canChangeStatus && (
                                <DropdownMenuItem
                                  onClick={() => router.push(`/robot-manager/${robot.id}?tab=status`)}
                                >
                                  <ArrowUpDown className="w-4 h-4 mr-2" />
                                  {rm.actions.changeStatus}
                                </DropdownMenuItem>
                              )}
                              <DropdownMenuItem
                                onClick={() => router.push(`/robot-manager/create?duplicateFrom=${robot.id}`)}
                              >
                                <Copy className="w-4 h-4 mr-2" />
                                {rm.detail.duplicate}
                              </DropdownMenuItem>
                            </DropdownMenuContent>
                          </DropdownMenu>
                        </TableCell>
                      </TableRow>
                    ))}
              </TableBody>
            </Table>

            {/* 分页 */}
            {!loading && totalPages > 0 && (
              <div
                className="flex items-center justify-between px-4 py-3"
                style={{ borderTop: `1px solid ${colors.border}` }}
              >
                <div className="text-sm flex items-center gap-3" style={{ color: colors.textSecondary }}>
                  <span>
                    {rm.listPage.page} {page} {rm.listPage.pageOf} {totalPages} {rm.listPage.pages}{' '}
                    • {rm.listPage.total} {total} {rm.listPage.items}
                  </span>
                  <span className="flex items-center gap-1">
                    <span>{rm.listPage.pageSize ?? '每页'}</span>
                    <select
                      value={pageSize}
                      onChange={(e) => {
                        setPageSize(parseInt(e.target.value, 10));
                        setPage(1);
                      }}
                      className="px-1.5 py-0.5 text-xs border rounded"
                      style={{ borderColor: colors.border, color: colors.textPrimary }}
                    >
                      {[10, 20, 50, 100].map((n) => (
                        <option key={n} value={n}>{n}</option>
                      ))}
                    </select>
                  </span>
                </div>
                <div className="flex gap-2">
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={() => setPage((p) => Math.max(1, p - 1))}
                    disabled={page === 1}
                  >
                    {rm.listPage.prevPage}
                  </Button>
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
                    disabled={page === totalPages}
                  >
                    {rm.listPage.nextPage}
                  </Button>
                </div>
              </div>
            )}
          </>
        )}
        </div>
      </div>

      {/* 批量状态变更弹窗 */}
      <Dialog open={showBulkDialog} onOpenChange={setShowBulkDialog}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>{rm.actions.bulkChangeStatus}</DialogTitle>
            <DialogDescription>
              {rm.listPage.selectedCount.replace('{count}', String(selectedIds.size))}
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-4 py-2">
            <div>
              <label className="block text-sm font-medium mb-1" style={{ color: colors.textPrimary }}>
                {rm.listPage.targetStatus} *
              </label>
              <Select
                value={bulkTargetStatus || 'none'}
                onValueChange={(v) => setBulkTargetStatus(v === 'none' ? '' : (v as RobotStatus))}
              >
                <SelectTrigger className="w-full">
                  <SelectValue placeholder={rm.form.selectStatus} />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="none" disabled>
                    {rm.form.selectStatus}
                  </SelectItem>
                  {ALL_STATUSES.map((s) => {
                    const allowed = validBulkTargets.has(s);
                    return (
                      <SelectItem key={s} value={s} disabled={!allowed}>
                        <span>
                          {rm.status[s]}
                          {!allowed && (
                            <span className="ml-2 text-xs opacity-60">
                              {rm.listPage.notAllowedForSelection}
                            </span>
                          )}
                        </span>
                      </SelectItem>
                    );
                  })}
                </SelectContent>
              </Select>
            </div>
            <div>
              <label className="block text-sm font-medium mb-1" style={{ color: colors.textPrimary }}>
                {rm.listPage.remark}
                {bulkTargetStatus === 'CANCELLED' ? ' *' : ''}
              </label>
              <textarea
                className="w-full border rounded-md px-3 py-2 text-sm"
                style={{ borderColor: colors.border }}
                rows={3}
                value={bulkRemark}
                onChange={(e) => setBulkRemark(e.target.value)}
                placeholder={
                  bulkTargetStatus === 'CANCELLED'
                    ? rm.listPage.remarkRequired
                    : rm.listPage.remarkOptional
                }
              />
            </div>
          </div>
          <DialogFooter>
            <Button
              variant="outline"
              onClick={() => {
                setShowBulkDialog(false);
                setBulkTargetStatus('');
                setBulkRemark('');
              }}
              disabled={bulkProcessing}
            >
              {rm.actions.cancel}
            </Button>
            <Button onClick={handleBulkStatusChange} disabled={bulkProcessing}>
              {bulkProcessing ? '...' : rm.actions.confirm}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* 更多筛选 Drawer：SKU / 客户 / 位置 */}
      <FilterDrawer
        open={filterDrawerOpen}
        onClose={() => setFilterDrawerOpen(false)}
        title={rm.filters.moreFilters}
        footer={
          <div className="flex justify-between">
            <Button
              variant="ghost"
              size="sm"
              onClick={() => {
                setSkuIdFilter('');
                setCustomerIdFilter('');
                setLocationIdFilter('');
                setPage(1);
              }}
            >
              {rm.filters.resetFilters}
            </Button>
            <Button size="sm" onClick={() => setFilterDrawerOpen(false)}>
              {rm.filters.applyFilters}
            </Button>
          </div>
        }
      >
        <div className="space-y-4">
          {/* SKU */}
          <div>
            <label className="block text-xs font-medium mb-1.5" style={{ color: colors.textSecondary }}>
              {rm.fields.sku}
            </label>
            <Select
              value={skuIdFilter || 'all'}
              onValueChange={(v) => {
                setSkuIdFilter(v === 'all' ? '' : v);
                setPage(1);
              }}
            >
              <SelectTrigger className="w-full h-9"><SelectValue placeholder={rm.filters.all} /></SelectTrigger>
              <SelectContent>
                <SelectItem value="all">{rm.filters.all}</SelectItem>
                {skus
                  .filter((s) => !modelIdFilter || s.modelId === modelIdFilter)
                  .map((s) => (
                    <SelectItem key={s.id} value={s.id}>
                      {s.code} - {s.name}
                    </SelectItem>
                  ))}
              </SelectContent>
            </Select>
          </div>

          {/* 客户 */}
          <div>
            <label className="block text-xs font-medium mb-1.5" style={{ color: colors.textSecondary }}>
              {rm.sales.customerName}
            </label>
            <Select
              value={customerIdFilter || 'all'}
              onValueChange={(v) => {
                setCustomerIdFilter(v === 'all' ? '' : v);
                setPage(1);
              }}
            >
              <SelectTrigger className="w-full h-9"><SelectValue placeholder={rm.filters.all} /></SelectTrigger>
              <SelectContent>
                <SelectItem value="all">{rm.filters.all}</SelectItem>
                {customers.map((c) => (
                  <SelectItem key={c.id} value={c.id}>
                    {c.code} - {c.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          {/* 位置 */}
          <div>
            <label className="block text-xs font-medium mb-1.5" style={{ color: colors.textSecondary }}>
              {rm.fields.location}
            </label>
            <Select
              value={locationIdFilter || 'all'}
              onValueChange={(v) => {
                setLocationIdFilter(v === 'all' ? '' : v);
                setPage(1);
              }}
            >
              <SelectTrigger className="w-full h-9"><SelectValue placeholder={rm.filters.all} /></SelectTrigger>
              <SelectContent>
                <SelectItem value="all">{rm.filters.all}</SelectItem>
                {locations.map((l) => (
                  <SelectItem key={l.id} value={l.id}>
                    {l.code} - {l.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
        </div>
      </FilterDrawer>
    </div>
  );
}

export default function RobotListPage() {
  return (
    <Suspense
      fallback={
        <div className="h-full flex flex-col" style={{ backgroundColor: '#f7f8fa' }}>
          <div className="bg-white border-b" style={{ borderColor: '#e5e6eb' }}>
            <div className="px-6 h-12 flex items-center">
              <div className="h-5 w-48 bg-gray-200 rounded animate-pulse" />
            </div>
          </div>
        </div>
      }
    >
      <RobotListPageContent />
    </Suspense>
  );
}
