import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react';
import { afterEach, expect, test, vi } from 'vitest';
import { MemoryRouter, Route, Routes } from 'react-router-dom';
import { ROUTER_FUTURE } from '../routing/routerConfig';

const routing = vi.hoisted(() => ({
  preloadRoute: vi.fn(async () => undefined),
  scheduleIdleRoutePreloads: vi.fn(() => vi.fn()),
  shouldPreloadRouteOnIntent: vi.fn(() => true)
}));
const auth = vi.hoisted(() => ({ session: { name: 'test-user', role: 'viewer' as const } as any }));

vi.mock('../routing/routeModules', () => routing);
vi.mock('../auth/AuthGate', () => ({
  usePlatformSession: () => ({ session: auth.session, logout: vi.fn() })
}));

import { AppShell } from './AppShell';

afterEach(() => {
  cleanup();
  vi.clearAllMocks();
  auth.session = { name: 'test-user', role: 'viewer' };
});

test('renders only explicitly assigned customer menus', () => {
  auth.session = { name: '客户甲', role: 'customer', userType: 'customer', menuKeys: ['monitor', 'vehicles', 'tracks', 'statistics'] };
  render(<MemoryRouter future={ROUTER_FUTURE} initialEntries={['/monitor']}>
    <Routes><Route element={<AppShell />}><Route path="*" element={<span>页面内容</span>} /></Route></Routes>
  </MemoryRouter>);

  expect(screen.getByRole('link', { name: '全局监控' })).toBeInTheDocument();
  expect(screen.getByRole('link', { name: '车辆查询' })).toBeInTheDocument();
  expect(screen.getByRole('link', { name: '轨迹回放' })).toBeInTheDocument();
  expect(screen.getByRole('link', { name: '里程查询' })).toBeInTheDocument();
  expect(screen.queryByRole('link', { name: '历史数据' })).not.toBeInTheDocument();
  expect(screen.queryByRole('link', { name: '告警中心' })).not.toBeInTheDocument();
  expect(screen.queryByRole('link', { name: '接入管理' })).not.toBeInTheDocument();
  expect(screen.queryByRole('link', { name: '账号管理' })).not.toBeInTheDocument();
  expect(screen.queryByRole('link', { name: '运维质量' })).not.toBeInTheDocument();
});

test('reschedules likely route preloads when the active module changes', async () => {
  const firstCleanup = vi.fn();
  const secondCleanup = vi.fn();
  routing.scheduleIdleRoutePreloads
    .mockReturnValueOnce(firstCleanup)
    .mockReturnValueOnce(secondCleanup);

  render(<MemoryRouter future={ROUTER_FUTURE} initialEntries={['/monitor']}>
    <Routes><Route element={<AppShell />}><Route path="*" element={<span>页面内容</span>} /></Route></Routes>
  </MemoryRouter>);

  expect(routing.scheduleIdleRoutePreloads).toHaveBeenCalledWith({ activePathname: '/monitor' });
  fireEvent.click(screen.getByRole('link', { name: '历史数据' }));

  await waitFor(() => expect(routing.scheduleIdleRoutePreloads).toHaveBeenLastCalledWith({ activePathname: '/history' }));
  expect(firstCleanup).toHaveBeenCalledTimes(1);

  cleanup();
  expect(secondCleanup).toHaveBeenCalledTimes(1);
});

test('opens contextual help for the active module and closes it without navigating', () => {
  render(<MemoryRouter future={ROUTER_FUTURE} initialEntries={['/monitor']}>
    <Routes><Route element={<AppShell />}><Route path="*" element={<span>页面内容</span>} /></Route></Routes>
  </MemoryRouter>);

  const help = screen.getByRole('button', { name: '帮助' });
  expect(help).toHaveAttribute('aria-expanded', 'false');
  fireEvent.click(help);

  expect(screen.getByRole('dialog', { name: '全局监控' })).toHaveTextContent('筛选会自动生效');
  expect(help).toHaveAttribute('aria-expanded', 'true');
  fireEvent.click(screen.getByRole('button', { name: '关闭帮助' }));
  expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
  expect(screen.getByText('页面内容')).toBeInTheDocument();
});
