import { fireEvent, render, screen } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { MemoryRouter } from 'react-router-dom';
import { describe, expect, it, vi } from 'vitest';

import { AppSidebar } from '@/components/layout/AppSidebar';
import { queryKeys } from '@/lib/queryKeys';

describe('AppSidebar', () => {
  function renderSidebar(initialEntry: string) {
    const queryClient = new QueryClient({
      defaultOptions: {
        queries: {
          retry: false,
        },
      },
    });

    return {
      queryClient,
      ...render(
        <QueryClientProvider client={queryClient}>
          <MemoryRouter initialEntries={[initialEntry]}>
            <AppSidebar />
          </MemoryRouter>
        </QueryClientProvider>,
      ),
    };
  }

  it('shows only the active directory drawer and closes the previous one when switching', () => {
    renderSidebar('/standardized?tab=failed');

    const standardizationLink = screen.getByRole('link', { name: 'AI标准化' });

    expect(standardizationLink).toBeInTheDocument();
    expect(standardizationLink).toHaveAttribute('aria-expanded', 'true');
    expect(screen.getByRole('link', { name: '标准化成功数据' })).toHaveAttribute('href', '/standardized');
    expect(screen.getByRole('link', { name: '标准化失败数据' })).toHaveAttribute('href', '/standardized?tab=failed');
    expect(screen.getByRole('link', { name: '标准化任务状态' })).toHaveAttribute('href', '/standardized?tab=tasks');
    expect(screen.queryByRole('link', { name: '搜索结果' })).not.toBeInTheDocument();
    expect(screen.queryByRole('link', { name: '话术配置' })).not.toBeInTheDocument();

    fireEvent.click(standardizationLink);

    expect(standardizationLink).toHaveAttribute('aria-expanded', 'false');
    expect(screen.queryByRole('link', { name: '标准化成功数据' })).not.toBeInTheDocument();
    expect(screen.queryByRole('link', { name: '标准化失败数据' })).not.toBeInTheDocument();
    expect(screen.queryByRole('link', { name: '标准化任务状态' })).not.toBeInTheDocument();

    fireEvent.click(standardizationLink);

    expect(standardizationLink).toHaveAttribute('aria-expanded', 'true');
    expect(screen.getByRole('link', { name: '标准化成功数据' })).toHaveAttribute('href', '/standardized');

    fireEvent.click(screen.getByRole('link', { name: '智能搜索' }));

    expect(screen.getByRole('link', { name: '搜索结果' })).toHaveAttribute('href', '/search-results');
    expect(screen.getByRole('link', { name: '搜索任务状态' })).toHaveAttribute('href', '/search-results?tab=tasks');
    expect(screen.queryByRole('link', { name: '标准化成功数据' })).not.toBeInTheDocument();
    expect(screen.queryByRole('link', { name: '话术配置' })).not.toBeInTheDocument();

    fireEvent.click(screen.getByRole('link', { name: '采购清单' }));

    expect(screen.queryByRole('link', { name: '搜索结果' })).not.toBeInTheDocument();
    expect(screen.queryByRole('link', { name: '搜索任务状态' })).not.toBeInTheDocument();

    fireEvent.click(screen.getByRole('link', { name: '智能询价' }));

    expect(screen.getByRole('link', { name: '话术配置' })).toHaveAttribute('href', '/smart-inquiry');
    expect(screen.getByRole('link', { name: '询价任务' })).toHaveAttribute('href', '/smart-inquiry?tab=tasks');
    expect(screen.queryByRole('link', { name: '标准化成功数据' })).not.toBeInTheDocument();
    expect(screen.queryByRole('link', { name: '搜索结果' })).not.toBeInTheDocument();
  });

  it('exposes procurement-list review as a child entry under procurement materials', () => {
    renderSidebar('/materials');

    const materialsLink = screen.getByRole('link', { name: '采购清单' });
    expect(materialsLink).toHaveAttribute('aria-expanded', 'true');
    expect(screen.getByRole('link', { name: '物料明细' })).toHaveAttribute('href', '/materials');
    expect(screen.getByRole('link', { name: '清单梳理' })).toHaveAttribute('href', '/procurement-list-review');

    fireEvent.click(screen.getByRole('link', { name: '清单梳理' }));
    expect(screen.getByRole('link', { name: '清单梳理' })).toHaveClass('bg-blue-50', 'text-blue-700');
  });

  it('highlights the active standardization child from the tab query', () => {
    renderSidebar('/standardized?tab=tasks');

    expect(screen.getByRole('link', { name: '标准化任务状态' })).toHaveClass('bg-blue-50', 'text-blue-700');
    expect(screen.getByRole('link', { name: '标准化成功数据' })).not.toHaveClass('bg-blue-50');
    expect(screen.getByRole('link', { name: '标准化失败数据' })).not.toHaveClass('bg-blue-50');
  });

  it('highlights the active search-results child from tab query params', () => {
    renderSidebar('/search-results?tab=tasks&batch_id=CG-20260420-001');

    expect(screen.getByRole('link', { name: '搜索任务状态' })).toHaveClass('bg-blue-50', 'text-blue-700');
    expect(screen.getByRole('link', { name: '搜索结果' })).not.toHaveClass('bg-blue-50');
  });

  it('highlights the active smart-inquiry child from the tab query', () => {
    renderSidebar('/smart-inquiry?tab=tasks');

    expect(screen.getByRole('link', { name: '询价任务' })).toHaveClass('bg-blue-50', 'text-blue-700');
    expect(screen.getByRole('link', { name: '话术配置' })).not.toHaveClass('bg-blue-50');
  });

  it('refreshes standardization success data when its menu item is clicked', () => {
    const { queryClient } = renderSidebar('/standardized?tab=tasks');
    const invalidateSpy = vi.spyOn(queryClient, 'invalidateQueries').mockResolvedValue();
    const refetchSpy = vi.spyOn(queryClient, 'refetchQueries').mockResolvedValue();

    fireEvent.click(screen.getByRole('link', { name: '标准化成功数据' }));

    expect(invalidateSpy).toHaveBeenCalledWith({ queryKey: queryKeys.standardization.successes });
    expect(invalidateSpy).toHaveBeenCalledWith({ queryKey: queryKeys.procurement.batchOptions });
    expect(refetchSpy).toHaveBeenCalledWith({ queryKey: queryKeys.standardization.successes, type: 'active' });
    expect(refetchSpy).toHaveBeenCalledWith({ queryKey: queryKeys.procurement.batchOptions, type: 'active' });
  });

  it('refreshes standardization failure data when its menu item is clicked', () => {
    const { queryClient } = renderSidebar('/standardized');
    const invalidateSpy = vi.spyOn(queryClient, 'invalidateQueries').mockResolvedValue();
    const refetchSpy = vi.spyOn(queryClient, 'refetchQueries').mockResolvedValue();

    fireEvent.click(screen.getByRole('link', { name: '标准化失败数据' }));

    expect(invalidateSpy).toHaveBeenCalledWith({ queryKey: queryKeys.standardization.failures });
    expect(invalidateSpy).toHaveBeenCalledWith({ queryKey: queryKeys.standardization.tasks });
    expect(refetchSpy).toHaveBeenCalledWith({ queryKey: queryKeys.standardization.failures, type: 'active' });
    expect(refetchSpy).toHaveBeenCalledWith({ queryKey: queryKeys.standardization.tasks, type: 'active' });
  });
});
