import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react';
import { afterEach, expect, test, vi } from 'vitest';
import UsersPage from './UsersPage';

const mocks = vi.hoisted(() => ({
  adminUsers: vi.fn(),
  vehicleCoverage: vi.fn(),
  createCustomerUser: vi.fn(),
  updateCustomerUser: vi.fn()
}));
const layout = vi.hoisted(() => ({ mobile: false }));

vi.mock('../../api/client', () => ({ api: mocks }));
vi.mock('../hooks/useMobileLayout', () => ({ useMobileLayout: () => layout.mobile }));

afterEach(() => {
  cleanup();
  document.querySelectorAll('.semi-portal').forEach((portal) => portal.remove());
  layout.mobile = false;
  Object.values(mocks).forEach((mock) => mock.mockReset());
});

test('deduplicates vehicle candidates by VIN and renders granted vehicles plate first', async () => {
  mocks.adminUsers.mockResolvedValue([{
    id: 7,
    username: 'customer-east',
    displayName: '华东客户',
    userType: 'customer',
    status: 'enabled',
    customerRef: '',
    tenantRef: '',
    authProvider: 'local',
    menuKeys: ['monitor'],
    vehicleVins: ['VIN001'],
    vehicles: [{ vin: 'VIN001', plate: '粤A11111', validFrom: '2026-06-05T00:00:00+08:00', sourceSystem: 'manual', grantedBy: '平台管理员' }],
    grantHistory: [{ id: 1, vin: 'VIN001', plate: '粤A11111', validFrom: '2026-06-05T00:00:00+08:00', sourceSystem: 'manual', grantedBy: '平台管理员', revokedBy: '', createdAt: '2026-07-16T00:00:00Z', updatedAt: '2026-07-16T00:00:00Z' }],
    createdAt: '2026-07-16T00:00:00Z',
    updatedAt: '2026-07-16T00:00:00Z'
  }]);
  const duplicatedVehicle = { vin: 'VIN002', plate: '粤A22222', protocols: ['GB32960', 'JT808'] };
  mocks.vehicleCoverage.mockResolvedValue({ items: [duplicatedVehicle, duplicatedVehicle], total: 1, limit: 20, offset: 0 });
  const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });

  const view = render(<QueryClientProvider client={client}><UsersPage /></QueryClientProvider>);

  const customer = await screen.findByRole('button', { name: /选择客户 华东客户/ });
  expect(screen.getByLabelText('账号管理操作')).toHaveTextContent('客户访问治理');
  expect(screen.getByLabelText('账号管理操作')).toHaveTextContent('变更最多 30 秒生效');
  expect(view.container.querySelector('.v2-page-heading')).not.toBeInTheDocument();
  expect(view.container.querySelector('.v2-user-discovery-shell')).toContainElement(screen.getByLabelText('账号管理操作'));
  expect(screen.getByRole('heading', { name: '账号范围', level: 5 })).toBeInTheDocument();
  expect(screen.getByText('按客户名称、登录账号与权限可用状态查找')).toBeInTheDocument();
  expect(screen.getAllByText('1 / 1 个账号')).toHaveLength(2);
  expect(view.container.querySelector('.v2-user-list.semi-card')).toBeInTheDocument();
  expect(view.container.querySelector('.v2-user-filter-panel.v2-workspace-filter-panel.semi-card')).toBeInTheDocument();
  expect(view.container.querySelector('.v2-customer-list.semi-list')).toBeInTheDocument();
  expect(screen.getByRole('row', { name: '客户账号目录列' })).toHaveTextContent('客户账号菜单权限车辆权限最近登录访问状态');
  expect(screen.getByText('权限就绪 1')).toBeInTheDocument();
  expect(screen.getByText('车辆授权 1')).toBeInTheDocument();
  expect(screen.getByText('权限就绪')).toBeInTheDocument();
  expect(view.container.querySelector('.v2-user-directory-metrics')).not.toBeInTheDocument();
  expect(customer).toHaveClass('semi-button', 'v2-user-list-item');
  expect(customer.closest('.semi-list-item')).toHaveClass('v2-user-list-row');
  expect(customer).toHaveAttribute('aria-pressed', 'false');
  expect(customer).toHaveAttribute('aria-expanded', 'false');
  expect(document.querySelector('.v2-user-editor-sidesheet')).not.toBeInTheDocument();
  fireEvent.click(customer);
  await waitFor(() => expect(customer).toHaveAttribute('aria-expanded', 'true'));
  const accountSummary = screen.getByRole('list', { name: '客户账号详情摘要' });
  expect(accountSummary).toHaveTextContent('登录账号@customer-east登录身份');
  expect(accountSummary).toHaveTextContent('权限范围1 菜单 · 1 辆最小必要权限');
  expect(accountSummary).toHaveTextContent('账号状态启用保存后最多 30 秒生效');
  const editorSheet = document.querySelector<HTMLElement>('.v2-user-editor-sidesheet .semi-sidesheet-inner');
  expect(editorSheet).toHaveAttribute('aria-label', '客户账号详情');
  expect(editorSheet).toHaveStyle({ width: 'min(840px, 100vw)' });
  expect(editorSheet?.closest('.semi-sidesheet')).toHaveClass('v2-workspace-editor-sidesheet');
  expect(document.querySelector('.v2-user-editor-sidesheet .v2-user-editor-tabs.semi-tabs')).toBeInTheDocument();
  expect(document.querySelector('.v2-user-editor-form')).toHaveAttribute('id', 'v2-user-editor-form');
  expect(screen.getAllByRole('tab')).toHaveLength(3);
  expect(document.querySelector('.v2-user-vehicle-section.semi-card')).toBeInTheDocument();
  fireEvent.click(screen.getByRole('tab', { name: '登录身份' }));
  expect(screen.getByLabelText('登录身份摘要')).toHaveTextContent('登录账号customer-east不可修改');
  expect(screen.getByLabelText('登录身份摘要')).toHaveTextContent('客户显示名称华东客户已设置');
  expect(screen.getByRole('group', { name: '基础身份' })).toHaveTextContent('用于客户登录和平台内展示');
  expect(screen.getByRole('group', { name: '安全与系统映射' })).toHaveTextContent('密码留空则保持不变');
  fireEvent.click(screen.getByRole('tab', { name: /菜单权限/ }));
  expect(screen.getByText('客户开放菜单').closest('.semi-tag')).toBeInTheDocument();
  expect(screen.getByLabelText('已开放 1 个菜单，共 4 个')).toHaveTextContent('客户工作台按最小权限开放');
  expect(screen.getAllByText('已开放')).toHaveLength(1);
  expect(screen.getAllByText('未开放')).toHaveLength(3);
  fireEvent.click(screen.getByRole('tab', { name: /车辆权限/ }));
  expect(document.querySelector('.v2-user-vehicle-section .v2-user-section-title .semi-tag')).toHaveTextContent('1 辆');
  const granted = await screen.findByRole('button', { name: '移除 粤A11111' });
  expect(granted).toHaveClass('semi-button');
  expect(granted.closest('.v2-assigned-vehicle-card')).toHaveClass('semi-card');
  expect(granted.closest('.v2-assigned-vehicle-card')).toHaveTextContent('粤A11111VIN001');
  expect(screen.getByRole('button', { name: '调整 粤A11111 有效期' })).toHaveAttribute('aria-haspopup', 'dialog');
  expect(document.querySelectorAll('input[type="datetime-local"]')).toHaveLength(0);
  fireEvent.click(screen.getByRole('button', { name: '调整 粤A11111 有效期' }));
  expect(await screen.findByLabelText('粤A11111 启用时间')).toHaveValue('2026-06-05T00:00');
  expect(document.querySelectorAll('input[type="datetime-local"]')).toHaveLength(2);
  const grantSheet = document.querySelector('.v2-user-grant-sidesheet .semi-sidesheet-inner');
  expect(grantSheet).toHaveAttribute('aria-label', '车辆授权有效期');
  expect(grantSheet?.closest('.semi-sidesheet')).toHaveClass('v2-workspace-config-sidesheet');
  const grantSummary = screen.getByRole('list', { name: '车辆授权有效期摘要' });
  expect(grantSummary).toHaveTextContent('车牌粤A11111');
  expect(grantSummary).toHaveTextContent('启用2026-06-05 00:00授权开始');
  expect(grantSummary).toHaveTextContent('停用持续有效未设置结束时间');
  expect(screen.getByRole('group', { name: '访问时间窗口' })).toHaveTextContent('只在授权区间内开放该车数据上海时间');
  fireEvent.click(screen.getByRole('button', { name: '关闭车辆授权有效期' }));
  expect(document.querySelectorAll('input[type="datetime-local"]')).toHaveLength(0);
  expect(document.querySelector('.v2-user-avatar')).toHaveClass('semi-avatar');
  expect(document.querySelector('.v2-user-status-tag')).toHaveClass('semi-tag');
  expect(document.querySelector('.v2-grant-history')).toHaveClass('semi-collapse');
  expect(document.querySelector('.v2-grant-history-title .semi-tag')).toHaveTextContent('1 条');

  fireEvent.change(screen.getByRole('textbox', { name: '按车牌或 VIN 搜索' }), { target: { value: '粤A22222' } });
  await waitFor(() => expect(mocks.vehicleCoverage).toHaveBeenCalled());
  const candidates = await screen.findAllByRole('option', { name: /粤A22222.*VIN002.*选择/ });
  expect(candidates).toHaveLength(1);
  expect((mocks.vehicleCoverage.mock.calls[0][0] as URLSearchParams).get('keyword')).toBe('粤A22222');

  fireEvent.click(candidates[0]);
  expect((await screen.findByRole('button', { name: '移除 粤A22222' })).closest('.v2-assigned-vehicle-card')).toHaveTextContent('粤A22222VIN002');
});

test('pages and filters large vehicle grants without nesting a vehicle-list scrollbar', async () => {
  const vehicles = Array.from({ length: 12 }, (_, index) => ({
    vin: `VIN${String(index + 1).padStart(3, '0')}`,
    plate: `粤A${String(index + 1).padStart(5, '0')}`,
    validFrom: '2026-06-05T00:00:00+08:00',
    sourceSystem: 'manual',
    grantedBy: '平台管理员'
  }));
  mocks.adminUsers.mockResolvedValue([{
    id: 7,
    username: 'customer-east',
    displayName: '华东客户',
    userType: 'customer',
    status: 'enabled',
    customerRef: '',
    tenantRef: '',
    authProvider: 'local',
    menuKeys: ['monitor', 'vehicles', 'tracks', 'statistics'],
    vehicleVins: vehicles.map((vehicle) => vehicle.vin),
    vehicles,
    grantHistory: [],
    createdAt: '2026-07-16T00:00:00Z',
    updatedAt: '2026-07-16T00:00:00Z'
  }]);
  const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });

  const view = render(<QueryClientProvider client={client}><UsersPage /></QueryClientProvider>);
  fireEvent.click(await screen.findByRole('button', { name: /选择客户 华东客户/ }));

  expect(screen.getAllByRole('button', { name: /^移除 / })).toHaveLength(10);
  expect(screen.getByText('第 1–10 条，共 12 辆')).toBeInTheDocument();
  expect(document.querySelector('.v2-assigned-pagination')).toBeInTheDocument();
  fireEvent.click(screen.getByRole('button', { name: 'Next' }));
  expect(await screen.findByRole('button', { name: '移除 粤A00012' })).toBeInTheDocument();
  expect(screen.getAllByRole('button', { name: /^移除 / })).toHaveLength(2);

  fireEvent.change(screen.getByRole('textbox', { name: '筛选已授权车辆' }), { target: { value: '粤A00012' } });
  expect(screen.getAllByRole('button', { name: /^移除 / })).toHaveLength(1);
  expect(screen.getByText('1 条匹配结果')).toBeInTheDocument();
  expect(screen.getByText('第 1–1 条，共 1 辆')).toBeInTheDocument();
});

test('makes draft state explicit, protects bulk removal and preserves edits across a same-revision refresh', async () => {
  const customer = {
    id: 7,
    username: 'customer-east',
    displayName: '华东客户',
    userType: 'customer',
    status: 'enabled',
    customerRef: '',
    tenantRef: '',
    authProvider: 'local',
    menuKeys: ['monitor', 'vehicles', 'tracks', 'statistics'],
    vehicleVins: ['VIN001'],
    vehicles: [{ vin: 'VIN001', plate: '粤A11111', validFrom: '2026-06-05T00:00:00+08:00', sourceSystem: 'manual', grantedBy: '平台管理员' }],
    grantHistory: [],
    createdAt: '2026-07-16T00:00:00Z',
    updatedAt: '2026-07-16T00:00:00Z'
  };
  mocks.adminUsers.mockResolvedValue([customer]);
  const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
  render(<QueryClientProvider client={client}><UsersPage /></QueryClientProvider>);

  fireEvent.click(await screen.findByRole('button', { name: /选择客户 华东客户/ }));
  expect(screen.getByText('已同步')).toBeInTheDocument();
  expect(screen.getByRole('button', { name: '保存权限' })).toBeDisabled();

  fireEvent.click(screen.getByRole('tab', { name: '登录身份' }));
  const displayName = screen.getByDisplayValue('华东客户');
  fireEvent.change(displayName, { target: { value: '华东客户（更新）' } });
  expect(screen.getByText('待保存')).toBeInTheDocument();
  expect(screen.getByRole('button', { name: '保存权限' })).toBeEnabled();

  client.setQueryData(['admin-users'], [{ ...customer }]);
  await waitFor(() => expect(screen.getByDisplayValue('华东客户（更新）')).toBeInTheDocument());

  fireEvent.click(screen.getByRole('tab', { name: /车辆权限/ }));
  fireEvent.click(screen.getByRole('button', { name: '清空全部 1 辆车辆权限' }));
  expect(await screen.findByRole('dialog', { name: '确认清空车辆权限' })).toHaveTextContent('影响对象1 辆当前账号全部车辆权限');
  expect(screen.getByRole('dialog', { name: '确认清空车辆权限' })).toHaveTextContent('未保存不会影响服务器');
  fireEvent.click(screen.getByRole('button', { name: '确认清空' }));
  await waitFor(() => expect(screen.queryByRole('button', { name: '移除 粤A11111' })).not.toBeInTheDocument());
  expect(screen.getByText('已从草稿移除 1 辆车，保存后生效')).toBeInTheDocument();

  fireEvent.click(screen.getByRole('button', { name: '关闭账号详情' }));
  expect(await screen.findByRole('dialog', { name: '确认放弃未保存的更改' })).toHaveTextContent('放弃未保存的更改？');
  expect(screen.getByRole('dialog', { name: '确认放弃未保存的更改' })).toHaveTextContent('服务器数据不受影响');
  fireEvent.click(screen.getByRole('button', { name: '继续编辑' }));
  expect(document.querySelector('.v2-user-editor-form')).toBeInTheDocument();
  expect(screen.getByRole('button', { name: '保存权限' })).toBeEnabled();
});

test('keeps the customer directory visible on mobile and opens details on demand', async () => {
  layout.mobile = true;
  mocks.adminUsers.mockResolvedValue([{
    id: 7, username: 'customer-east', displayName: '华东客户', userType: 'customer', status: 'enabled',
    customerRef: '', tenantRef: '', authProvider: 'local', menuKeys: ['monitor'], vehicleVins: [],
    vehicles: [], grantHistory: [], createdAt: '2026-07-16T00:00:00Z', updatedAt: '2026-07-16T00:00:00Z'
  }]);
  const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
  const view = render(<QueryClientProvider client={client}><UsersPage /></QueryClientProvider>);

  expect(await screen.findByText('客户权限目录')).toBeInTheDocument();
  const customer = await screen.findByRole('button', { name: /选择客户 华东客户/ });
  expect(view.container.querySelector('.v2-user-mobile-picker')).not.toBeInTheDocument();
  expect(view.container.querySelector('.v2-customer-list.semi-list')).toBeInTheDocument();
  expect(screen.queryByRole('textbox', { name: '搜索客户账号' })).not.toBeInTheDocument();
  expect(screen.getByRole('button', { name: '新建客户账号' })).toHaveClass('v2-workspace-mobile-tool-button', 'is-primary');
  const filterToggle = screen.getByRole('button', { name: '修改账号范围：全部状态' });
  expect(filterToggle).toHaveAttribute('aria-expanded', 'false');
  fireEvent.click(filterToggle);
  expect(screen.getByRole('button', { name: '关闭账号范围：全部状态' })).toHaveAttribute('aria-expanded', 'true');
  expect(screen.getByRole('textbox', { name: '搜索客户账号' })).toBeInTheDocument();
  expect(document.querySelector('.v2-user-mobile-filter-sidesheet .semi-sidesheet-inner')).toHaveAttribute('aria-label', '客户账号筛选');
  expect(document.querySelector('.v2-user-filter-panel')).not.toBeInTheDocument();
  expect(document.querySelector('.v2-user-editor-sidesheet')).not.toBeInTheDocument();
  fireEvent.click(screen.getByRole('button', { name: '关闭客户账号筛选' }));
  await waitFor(() => expect(screen.getByRole('button', { name: '修改账号范围：全部状态' })).toHaveAttribute('aria-expanded', 'false'));
  fireEvent.click(customer);
  expect(await screen.findByRole('button', { name: '关闭账号详情' })).toBeInTheDocument();
  expect(customer).toHaveAttribute('aria-expanded', 'true');
  fireEvent.click(screen.getByRole('button', { name: '关闭账号详情' }));
  await waitFor(() => expect(document.querySelector('.v2-user-editor-form')).not.toBeInTheDocument());
  expect(customer).toHaveAttribute('aria-expanded', 'false');
  expect(screen.getAllByRole('button', { name: '新建客户账号' })).toHaveLength(1);
});

test('applies mobile customer filters explicitly and discards unconfirmed draft changes', async () => {
  layout.mobile = true;
  mocks.adminUsers.mockResolvedValue([
    {
      id: 7, username: 'customer-east', displayName: '华东客户', userType: 'customer', status: 'enabled',
      customerRef: 'east', tenantRef: '', authProvider: 'local', menuKeys: ['monitor'], vehicleVins: [],
      vehicles: [], grantHistory: [], createdAt: '2026-07-16T00:00:00Z', updatedAt: '2026-07-16T00:00:00Z'
    },
    {
      id: 8, username: 'customer-west', displayName: '西部客户', userType: 'customer', status: 'disabled',
      customerRef: 'west', tenantRef: '', authProvider: 'local', menuKeys: ['monitor'], vehicleVins: [],
      vehicles: [], grantHistory: [], createdAt: '2026-07-16T00:00:00Z', updatedAt: '2026-07-16T00:00:00Z'
    }
  ]);
  const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
  render(<QueryClientProvider client={client}><UsersPage /></QueryClientProvider>);

  expect(await screen.findByRole('button', { name: /选择客户 华东客户/ })).toBeInTheDocument();
  expect(screen.getByRole('button', { name: /选择客户 西部客户/ })).toBeInTheDocument();
  fireEvent.click(screen.getByRole('button', { name: '修改账号范围：全部状态' }));
  fireEvent.change(screen.getByRole('textbox', { name: '搜索客户账号' }), { target: { value: '西部' } });

  expect(screen.getByRole('button', { name: /选择客户 华东客户/ })).toBeInTheDocument();
  expect(screen.getByRole('button', { name: /选择客户 西部客户/ })).toBeInTheDocument();
  fireEvent.click(screen.getByRole('button', { name: '关闭客户账号筛选' }));
  await waitFor(() => expect(screen.getByRole('button', { name: '修改账号范围：全部状态' })).toBeInTheDocument());
  expect(screen.getByRole('button', { name: /选择客户 华东客户/ })).toBeInTheDocument();

  fireEvent.click(screen.getByRole('button', { name: '修改账号范围：全部状态' }));
  expect(screen.getByRole('textbox', { name: '搜索客户账号' })).toHaveValue('');
  fireEvent.change(screen.getByRole('textbox', { name: '搜索客户账号' }), { target: { value: '西部' } });
  fireEvent.click(screen.getByRole('button', { name: '应用筛选' }));

  await waitFor(() => expect(screen.queryByRole('button', { name: /选择客户 华东客户/ })).not.toBeInTheDocument());
  expect(screen.getByRole('button', { name: /选择客户 西部客户/ })).toBeInTheDocument();
  expect(screen.getByRole('button', { name: '修改账号范围：全部状态 · 西部' })).toBeInTheDocument();

  fireEvent.click(screen.getByRole('button', { name: '修改账号范围：全部状态 · 西部' }));
  fireEvent.click(screen.getByRole('button', { name: '重置条件' }));
  expect(screen.getByRole('dialog', { name: '客户账号筛选' })).toBeInTheDocument();
  expect(screen.getByRole('button', { name: '关闭账号范围：全部状态 · 西部' })).toHaveAttribute('aria-expanded', 'true');
  fireEvent.click(screen.getByRole('button', { name: '应用筛选' }));
  await waitFor(() => expect(screen.getByRole('button', { name: /选择客户 华东客户/ })).toBeInTheDocument());
  expect(screen.getByRole('button', { name: /选择客户 西部客户/ })).toBeInTheDocument();
  expect(screen.getByRole('button', { name: '修改账号范围：全部状态' })).toBeInTheDocument();
});

test('keeps granted vehicles primary and reveals mobile assignment tools on demand', async () => {
  layout.mobile = true;
  const vehicles = Array.from({ length: 5 }, (_, index) => ({
    vin: `VIN${String(index + 1).padStart(3, '0')}`,
    plate: `粤A${String(index + 1).padStart(5, '0')}`,
    validFrom: '2026-06-05T00:00:00+08:00',
    sourceSystem: 'manual',
    grantedBy: '平台管理员'
  }));
  mocks.adminUsers.mockResolvedValue([{
    id: 7, username: 'customer-east', displayName: '华东客户', userType: 'customer', status: 'enabled',
    customerRef: '', tenantRef: '', authProvider: 'local', menuKeys: ['monitor', 'vehicles', 'tracks', 'statistics'],
    vehicleVins: vehicles.map((vehicle) => vehicle.vin), vehicles, grantHistory: [],
    createdAt: '2026-07-16T00:00:00Z', updatedAt: '2026-07-16T00:00:00Z'
  }]);
  const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
  render(<QueryClientProvider client={client}><UsersPage /></QueryClientProvider>);

  fireEvent.click(await screen.findByRole('button', { name: /选择客户 华东客户/ }));

  const toggle = await screen.findByRole('button', { name: '添加授权车辆' });
  expect(toggle).toHaveAttribute('aria-expanded', 'false');
  expect(document.querySelector('.v2-user-vehicle-section')).toHaveClass('is-composer-collapsed');
  expect(screen.queryByRole('textbox', { name: '按车牌或 VIN 搜索' })).not.toBeInTheDocument();
  expect(screen.getAllByRole('button', { name: /^移除 / })).toHaveLength(4);
  expect(screen.getByText('第 1–4 条，共 5 辆')).toBeInTheDocument();
  expect(document.querySelectorAll('.v2-assigned-vehicle-card.is-mobile-compact')).toHaveLength(4);
  expect(document.querySelector('.v2-assigned-vehicle-interval')).toHaveAttribute('aria-label', '授权有效期：启用 2026-06-05 00:00；停用 持续有效');
  expect(document.querySelector('.v2-user-editor-sidesheet .v2-workspace-config-title small')).toHaveTextContent('@customer-east · 最近登录');

  fireEvent.click(toggle);

  expect(screen.getByRole('button', { name: '收起添加车辆' })).toHaveAttribute('aria-expanded', 'true');
  expect(document.querySelector('.v2-user-vehicle-section')).not.toHaveClass('is-composer-collapsed');
  expect(screen.getByRole('textbox', { name: '按车牌或 VIN 搜索' })).toBeInTheDocument();
  expect(document.querySelector('#v2-user-vehicle-composer')).toBeInTheDocument();
});

test('filters the customer directory by status and exposes the active result scope', async () => {
  mocks.adminUsers.mockResolvedValue([
    {
      id: 7, username: 'customer-east', displayName: '华东客户', userType: 'customer', status: 'enabled',
      customerRef: 'east', tenantRef: '', authProvider: 'local', menuKeys: ['monitor'], vehicleVins: [],
      vehicles: [], grantHistory: [], createdAt: '2026-07-16T00:00:00Z', updatedAt: '2026-07-16T00:00:00Z'
    },
    {
      id: 8, username: 'customer-west', displayName: '西部客户', userType: 'customer', status: 'disabled',
      customerRef: 'west', tenantRef: '', authProvider: 'local', menuKeys: ['monitor'], vehicleVins: [],
      vehicles: [], grantHistory: [], createdAt: '2026-07-16T00:00:00Z', updatedAt: '2026-07-16T00:00:00Z'
    }
  ]);
  const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
  const view = render(<QueryClientProvider client={client}><UsersPage /></QueryClientProvider>);

  expect(await screen.findByRole('button', { name: /选择客户 华东客户/ })).toBeInTheDocument();
  expect(screen.getByRole('button', { name: /选择客户 西部客户/ })).toBeInTheDocument();
  fireEvent.click(screen.getByRole('combobox', { name: '访问状态' }));
  const disabledOption = await waitFor(() => {
    const option = [...document.querySelectorAll<HTMLElement>('.semi-select-option')]
      .find((item) => item.textContent?.includes('停用账号'));
    expect(option).toBeInTheDocument();
    return option!;
  });
  fireEvent.click(disabledOption);

  await waitFor(() => expect(screen.queryByRole('button', { name: /选择客户 华东客户/ })).not.toBeInTheDocument());
  expect(screen.getByRole('button', { name: /选择客户 西部客户/ })).toBeInTheDocument();
  expect(screen.getAllByText('1 / 2 个账号')).toHaveLength(2);
  expect(screen.getByText('权限就绪 0')).toBeInTheDocument();
  expect(screen.getByText('车辆授权 0')).toBeInTheDocument();

  fireEvent.click(screen.getByRole('button', { name: '清空账号筛选' }));
  await waitFor(() => expect(screen.getByRole('button', { name: /选择客户 华东客户/ })).toBeInTheDocument());
  expect(screen.getByRole('button', { name: /选择客户 西部客户/ })).toBeInTheDocument();

  // Semi keeps the first Select popup mounted briefly while its close animation
  // finishes. Remount before the second scope assertion so the test never clicks
  // a stale portal when the full suite is under load.
  view.unmount();
  document.querySelectorAll('.semi-portal').forEach((portal) => portal.remove());
  render(<QueryClientProvider client={client}><UsersPage /></QueryClientProvider>);
  expect(await screen.findByRole('button', { name: /选择客户 华东客户/ })).toBeInTheDocument();

  fireEvent.click(screen.getByRole('combobox', { name: '访问状态' }));
  const attentionOption = await waitFor(() => {
    const options = [...document.querySelectorAll<HTMLElement>('.semi-select-option')]
      .filter((item) => item.textContent?.includes('待完善权限'));
    const option = options[options.length - 1];
    expect(option).toBeInTheDocument();
    return option!;
  });
  fireEvent.click(attentionOption);

  await waitFor(() => expect(screen.queryByRole('button', { name: /选择客户 西部客户/ })).not.toBeInTheDocument());
  expect(screen.getByRole('button', { name: /选择客户 华东客户/ })).toBeInTheDocument();
  expect(screen.getByText('待分配车辆')).toBeInTheDocument();
  expect(screen.getByText('待完善 1')).toBeInTheDocument();
});

test('uses a standard Semi empty state when no customer account exists', async () => {
  mocks.adminUsers.mockResolvedValue([]);
  const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
  const view = render(<QueryClientProvider client={client}><UsersPage /></QueryClientProvider>);

  expect(await screen.findByText('还没有客户账号')).toBeInTheDocument();
  expect(view.container.querySelector('.v2-user-list-empty.semi-empty')).toBeInTheDocument();
  expect(document.querySelector('.v2-user-editor-sidesheet')).not.toBeInTheDocument();
  expect(screen.getAllByRole('button', { name: '创建第一个客户账号' })).toHaveLength(1);
});

test('submits per-vehicle authorization interval instead of only a VIN list', async () => {
  mocks.adminUsers.mockResolvedValue([{
    id: 7, username: 'customer-east', displayName: '华东客户', userType: 'customer', status: 'enabled',
    customerRef: '', tenantRef: '', authProvider: 'local', menuKeys: ['statistics'], vehicleVins: ['VIN001'],
    vehicles: [{ vin: 'VIN001', plate: '粤A11111', validFrom: '2026-07-16T14:08:18+08:00', sourceSystem: 'manual', grantedBy: '平台管理员' }],
    grantHistory: [], createdAt: '2026-07-16T00:00:00Z', updatedAt: '2026-07-16T00:00:00Z'
  }]);
  mocks.updateCustomerUser.mockResolvedValue({ id: 7 });
  const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
  render(<QueryClientProvider client={client}><UsersPage /></QueryClientProvider>);
  fireEvent.click(await screen.findByRole('button', { name: /选择客户 华东客户/ }));
  expect(document.querySelectorAll('input[type="datetime-local"]')).toHaveLength(0);
  fireEvent.click(screen.getByRole('button', { name: '调整 粤A11111 有效期' }));
  fireEvent.change(await screen.findByLabelText('粤A11111 启用时间'), { target: { value: '2026-06-05T00:00' } });
  fireEvent.click(screen.getByRole('button', { name: '完成' }));
  fireEvent.click(screen.getByRole('button', { name: '保存权限' }));
  await waitFor(() => expect(mocks.updateCustomerUser).toHaveBeenCalled());
  expect(mocks.updateCustomerUser.mock.calls[0][1]).toMatchObject({
    vehicleVins: ['VIN001'],
    vehicleGrants: [{ vin: 'VIN001', validFrom: '2026-06-05T00:00', validTo: '' }]
  });
});
