import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { toast } from 'sonner';
import { describe, it, expect, vi } from 'vitest';

vi.mock('@/Components/Shared/MetricDelta', () => ({
  default: ({ value, format }: { value: number; format: string }) => (
    <span data-testid="metric-delta" data-value={value} data-format={format}>
      {value}%
    </span>
  ),
}));

vi.mock('sonner', () => ({
  toast: {
    success: vi.fn(),
    error: vi.fn(),
  },
}));

import WinnersLosersTable from './WinnersLosersTable';

interface Finding {
  id: number;
  page_url: string;
  delta_percent: number;
  recommendations_count?: number;
  supporting_data: {
    clicks_before: number;
    clicks_after: number;
    impressions_delta_pct?: number;
  };
}

function makeFinding(overrides: Partial<Finding> & Pick<Finding, 'id' | 'delta_percent'>): Finding {
  return {
    page_url: `https://example.com/page-${overrides.id}`,
    supporting_data: {
      clicks_before: 100,
      clicks_after: 50,
    },
    ...overrides,
  };
}

describe('WinnersLosersTable', () => {
  describe('severity classes on losers tab (default)', () => {
    it('applies red severity classes for delta_percent with abs >= 50', () => {
      const losers = [makeFinding({ id: 1, delta_percent: -80 })];
      const { container } = render(<WinnersLosersTable winners={[]} losers={losers} />);

      const row = container.querySelector('tbody tr');
      expect(row).not.toBeNull();
      expect(row).toHaveClass('border-l-2');
      expect(row).toHaveClass('border-l-destructive');
      expect(row).toHaveClass('bg-destructive/5');
    });

    it('applies orange severity classes for delta_percent with abs >= 20 and abs < 50', () => {
      const losers = [makeFinding({ id: 2, delta_percent: -30 })];
      const { container } = render(<WinnersLosersTable winners={[]} losers={losers} />);

      const row = container.querySelector('tbody tr');
      expect(row).not.toBeNull();
      expect(row).toHaveClass('border-l-2');
      expect(row).toHaveClass('border-l-warning');
      expect(row).toHaveClass('bg-warning/5');
    });

    it('does not apply severity classes for delta_percent with abs < 20', () => {
      const losers = [makeFinding({ id: 3, delta_percent: -5 })];
      const { container } = render(<WinnersLosersTable winners={[]} losers={losers} />);

      const row = container.querySelector('tbody tr');
      expect(row).not.toBeNull();
      expect(row?.className).not.toContain('border-l-2');
      expect(row?.className).not.toContain('border-l-destructive');
      expect(row?.className).not.toContain('border-l-warning');
      expect(row?.className).not.toContain('bg-destructive');
      expect(row?.className).not.toContain('bg-warning');
    });
  });

  describe('severity classes on winners tab', () => {
    it('applies green severity classes for delta_percent with abs >= 50', async () => {
      const user = userEvent.setup();
      const winners = [makeFinding({ id: 4, delta_percent: 60 })];
      const { container } = render(<WinnersLosersTable winners={winners} losers={[]} />);

      const winnersTab = screen.getByRole('tab', { name: /winners/i });
      await user.click(winnersTab);

      const row = container.querySelector('tbody tr');
      expect(row).not.toBeNull();
      expect(row).toHaveClass('border-l-2');
      expect(row).toHaveClass('border-l-success');
      expect(row).toHaveClass('bg-success/5');
    });

    it('applies emerald severity classes for delta_percent with abs >= 20 and abs < 50', async () => {
      const user = userEvent.setup();
      const winners = [makeFinding({ id: 5, delta_percent: 35 })];
      const { container } = render(<WinnersLosersTable winners={winners} losers={[]} />);

      const winnersTab = screen.getByRole('tab', { name: /winners/i });
      await user.click(winnersTab);

      const row = container.querySelector('tbody tr');
      expect(row).not.toBeNull();
      expect(row).toHaveClass('border-l-2');
      expect(row).toHaveClass('border-l-accent');
      expect(row).toHaveClass('bg-accent/5');
    });
  });

  describe('dark mode classes', () => {
    it('includes dark mode classes alongside light mode classes for losers', () => {
      const losers = [makeFinding({ id: 6, delta_percent: -80 })];
      const { container } = render(<WinnersLosersTable winners={[]} losers={losers} />);

      const row = container.querySelector('tbody tr');
      expect(row).not.toBeNull();
      expect(row).toHaveClass('bg-destructive/5');
      expect(row).toHaveClass('border-l-destructive');
    });

    it('includes dark mode classes alongside light mode classes for winners', async () => {
      const user = userEvent.setup();
      const winners = [makeFinding({ id: 7, delta_percent: 60 })];
      const { container } = render(<WinnersLosersTable winners={winners} losers={[]} />);

      const winnersTab = screen.getByRole('tab', { name: /winners/i });
      await user.click(winnersTab);

      const row = container.querySelector('tbody tr');
      expect(row).not.toBeNull();
      expect(row).toHaveClass('bg-success/5');
      expect(row).toHaveClass('border-l-success');
    });
  });

  describe('empty state', () => {
    it('shows empty message when losers list is empty (default tab)', () => {
      render(<WinnersLosersTable winners={[]} losers={[]} />);

      expect(screen.getByText('No losers found in this analysis.')).toBeInTheDocument();
    });

    it('shows empty message when winners list is empty after switching tab', async () => {
      const user = userEvent.setup();
      render(<WinnersLosersTable winners={[]} losers={[]} />);

      const winnersTab = screen.getByRole('tab', { name: /winners/i });
      await user.click(winnersTab);

      expect(screen.getByText('No winners found in this analysis.')).toBeInTheDocument();
    });
  });

  describe('clickable external links', () => {
    it('renders page URLs as external links with correct attributes', () => {
      const losers = [makeFinding({ id: 14, delta_percent: -25 })];
      render(<WinnersLosersTable winners={[]} losers={losers} />);

      const link = screen.getByRole('link', { name: /\/page-14/i });
      expect(link).toHaveAttribute('href', 'https://example.com/page-14');
      expect(link).toHaveAttribute('target', '_blank');
      expect(link).toHaveAttribute('rel', 'noopener noreferrer');
      expect(link).toHaveAttribute('title', 'https://example.com/page-14');
    });

    it('renders external link icon for each page URL', () => {
      const losers = [makeFinding({ id: 15, delta_percent: -30 })];
      render(<WinnersLosersTable winners={[]} losers={losers} />);

      const link = screen.getByRole('link', { name: /\/page-15/i });
      // ExternalLink icon is rendered as an svg within the link
      const icon = link.querySelector('svg');
      expect(icon).toBeInTheDocument();
    });

    it('renders copy button in DOM at all times (accessibility)', () => {
      const losers = [makeFinding({ id: 16, delta_percent: -25 })];
      const { container } = render(<WinnersLosersTable winners={[]} losers={losers} />);

      // Copy button is always in the DOM (opacity-0 when not hovered)
      const copyButtons = container.querySelectorAll('button[aria-label="Copy URL"]');
      expect(copyButtons).toHaveLength(1);
    });

    it('copy button has opacity-0 class by default (visually hidden but in DOM)', () => {
      const losers = [makeFinding({ id: 16, delta_percent: -25 })];
      const { container } = render(<WinnersLosersTable winners={[]} losers={losers} />);

      const copyButton = container.querySelector('button[aria-label="Copy URL"]');
      expect(copyButton).not.toBeNull();
      expect(copyButton).toHaveClass('opacity-0');
    });

    it('copy button has group-hover:opacity-100 and focus:opacity-100 classes', () => {
      const losers = [makeFinding({ id: 16, delta_percent: -25 })];
      const { container } = render(<WinnersLosersTable winners={[]} losers={losers} />);

      const copyButton = container.querySelector('button[aria-label="Copy URL"]');
      expect(copyButton).not.toBeNull();
      expect(copyButton).toHaveClass('group-hover:opacity-100');
      expect(copyButton).toHaveClass('focus:opacity-100');
    });

    it('row has group class for CSS group-hover to work', () => {
      const losers = [makeFinding({ id: 16, delta_percent: -25 })];
      const { container } = render(<WinnersLosersTable winners={[]} losers={losers} />);

      const row = container.querySelector('tbody tr');
      expect(row).toHaveClass('group');
    });

    it('copies URL to clipboard when copy button is clicked', async () => {
      const mockWriteText = vi.fn().mockResolvedValue(undefined);

      // Mock the clipboard API
      Object.defineProperty(navigator, 'clipboard', {
        value: {
          writeText: mockWriteText,
        },
        writable: true,
        configurable: true,
      });

      const losers = [makeFinding({ id: 17, delta_percent: -30 })];
      const { container } = render(<WinnersLosersTable winners={[]} losers={losers} />);

      const copyButton = container.querySelector('button[aria-label="Copy URL"]');
      expect(copyButton).not.toBeNull();

      if (copyButton) {
        fireEvent.click(copyButton);
      }

      expect(mockWriteText).toHaveBeenCalledWith('https://example.com/page-17');
    });

    it('truncates long URLs in display text', () => {
      const longUrl = 'https://example.com/' + 'a'.repeat(100);
      const losers = [makeFinding({ id: 18, delta_percent: -25, page_url: longUrl })];
      render(<WinnersLosersTable winners={[]} losers={losers} />);

      // Find the external link (not the recommendations link)
      const links = screen.getAllByRole('link');
      const externalLink = links.find((l) => l.getAttribute('target') === '_blank');
      expect(externalLink).toBeTruthy();
      // Link text should be truncated (path starts with '/')
      expect(externalLink?.textContent).toContain('...');
      // But href should have full URL
      expect(externalLink).toHaveAttribute('href', longUrl);
      // And title should have full URL for tooltip
      expect(externalLink).toHaveAttribute('title', longUrl);
    });

    it('renders external links in winners tab', async () => {
      const user = userEvent.setup();
      const winners = [makeFinding({ id: 19, delta_percent: 40 })];
      render(<WinnersLosersTable winners={winners} losers={[]} />);

      const winnersTab = screen.getByRole('tab', { name: /winners/i });
      await user.click(winnersTab);

      const link = screen.getByRole('link', { name: /\/page-19/i });
      expect(link).toHaveAttribute('href', 'https://example.com/page-19');
      expect(link).toHaveAttribute('target', '_blank');
      expect(link).toHaveAttribute('rel', 'noopener noreferrer');
    });
  });

  describe('copy-to-clipboard functionality', () => {
    it('calls handleCopyUrl when copy button is clicked', async () => {
      const mockWriteText = vi.fn().mockResolvedValue(undefined);
      Object.defineProperty(navigator, 'clipboard', {
        value: { writeText: mockWriteText },
        writable: true,
        configurable: true,
      });

      const losers = [makeFinding({ id: 20, delta_percent: -30 })];
      const { container } = render(<WinnersLosersTable winners={[]} losers={losers} />);

      const copyButton = container.querySelector('button[aria-label="Copy URL"]');
      if (copyButton) {
        fireEvent.click(copyButton);
      }

      expect(mockWriteText).toHaveBeenCalledWith('https://example.com/page-20');
    });

    it('handles clipboard API errors gracefully', async () => {
      const mockWriteText = vi.fn().mockRejectedValue(new Error('Copy failed'));
      Object.defineProperty(navigator, 'clipboard', {
        value: { writeText: mockWriteText },
        writable: true,
        configurable: true,
      });

      const losers = [makeFinding({ id: 21, delta_percent: -30 })];
      const { container } = render(<WinnersLosersTable winners={[]} losers={losers} />);

      const copyButton = container.querySelector('button[aria-label="Copy URL"]');
      if (copyButton) {
        fireEvent.click(copyButton);
      }

      expect(mockWriteText).toHaveBeenCalledWith('https://example.com/page-21');
      // The component catches the error and shows toast.error
      await waitFor(() => {
        expect(toast.error).toHaveBeenCalledWith("Couldn't copy the URL. Try again.");
      });
    });

    it('copy button is present in winners tab', async () => {
      const user = userEvent.setup();
      const winners = [makeFinding({ id: 22, delta_percent: 45 })];
      const { container } = render(<WinnersLosersTable winners={winners} losers={[]} />);

      const winnersTab = screen.getByRole('tab', { name: /winners/i });
      await user.click(winnersTab);

      const copyButton = container.querySelector('button[aria-label="Copy URL"]');
      expect(copyButton).toBeInTheDocument();
    });

    it('renders copy button with correct size and styling', () => {
      const losers = [makeFinding({ id: 24, delta_percent: -30 })];
      const { container } = render(<WinnersLosersTable winners={[]} losers={losers} />);

      const copyButton = container.querySelector('button[aria-label="Copy URL"]');
      const copyIcon = copyButton?.querySelector('svg');

      expect(copyButton).not.toBeNull();
      expect(copyButton).toHaveClass('h-6', 'w-6', 'p-0');
      expect(copyIcon).toHaveClass('h-3', 'w-3');
    });

    it('copy button has correct aria-label for screen readers', () => {
      const losers = [makeFinding({ id: 25, delta_percent: -30 })];
      const { container } = render(<WinnersLosersTable winners={[]} losers={losers} />);

      const copyButton = container.querySelector('button[aria-label="Copy URL"]');
      expect(copyButton).not.toBeNull();
      expect(copyButton).toHaveAttribute('aria-label', 'Copy URL');
    });
  });

  describe('cross-links for losers with recommendations', () => {
    it('shows "View recommendations" link for losers with recommendations_count > 0', () => {
      const losers = [makeFinding({ id: 30, delta_percent: -40, recommendations_count: 3 })];
      render(<WinnersLosersTable winners={[]} losers={losers} siteId={1} />);

      expect(screen.getByText('View 3 recommendations')).toBeInTheDocument();
    });

    it('shows singular "recommendation" for count of 1', () => {
      const losers = [makeFinding({ id: 31, delta_percent: -40, recommendations_count: 1 })];
      render(<WinnersLosersTable winners={[]} losers={losers} siteId={1} />);

      expect(screen.getByText('View 1 recommendation')).toBeInTheDocument();
    });

    it('does not show recommendations link when recommendations_count is 0', () => {
      const losers = [makeFinding({ id: 32, delta_percent: -40, recommendations_count: 0 })];
      render(<WinnersLosersTable winners={[]} losers={losers} siteId={1} />);

      expect(screen.queryByText(/View \d+ recommendation/)).not.toBeInTheDocument();
    });

    it('does not show recommendations link when recommendations_count is undefined', () => {
      const losers = [makeFinding({ id: 33, delta_percent: -40 })];
      render(<WinnersLosersTable winners={[]} losers={losers} siteId={1} />);

      expect(screen.queryByText(/View \d+ recommendation/)).not.toBeInTheDocument();
    });

    it('does not show recommendations link when siteId is not provided', () => {
      const losers = [makeFinding({ id: 34, delta_percent: -40, recommendations_count: 3 })];
      render(<WinnersLosersTable winners={[]} losers={losers} />);

      expect(screen.queryByText(/View \d+ recommendation/)).not.toBeInTheDocument();
    });

    it('does not show recommendations link on winners tab even with recommendations_count', async () => {
      const user = userEvent.setup();
      const winners = [makeFinding({ id: 35, delta_percent: 40, recommendations_count: 3 })];
      render(<WinnersLosersTable winners={winners} losers={[]} siteId={1} />);

      const winnersTab = screen.getByRole('tab', { name: /winners/i });
      await user.click(winnersTab);

      expect(screen.queryByText(/View \d+ recommendation/)).not.toBeInTheDocument();
    });
  });

  describe('tab behavior', () => {
    it('defaults to losers tab', () => {
      const losers = [makeFinding({ id: 8, delta_percent: -25 })];
      render(<WinnersLosersTable winners={[]} losers={losers} />);

      expect(screen.getByText(/\/page-8/)).toBeInTheDocument();
    });

    it('switches to winners tab on click', async () => {
      const user = userEvent.setup();
      const winners = [makeFinding({ id: 9, delta_percent: 40 })];
      const losers = [makeFinding({ id: 10, delta_percent: -40 })];
      render(<WinnersLosersTable winners={winners} losers={losers} />);

      // Losers tab initially active
      expect(screen.getByText(/\/page-10/)).toBeInTheDocument();
      expect(screen.queryByText(/\/page-9/)).not.toBeInTheDocument();

      const winnersTab = screen.getByRole('tab', { name: /winners/i });
      await user.click(winnersTab);

      // Winners tab now active
      expect(screen.getByText(/\/page-9/)).toBeInTheDocument();
      expect(screen.queryByText(/\/page-10/)).not.toBeInTheDocument();
    });

    it('displays correct counts in tab buttons', () => {
      const winners = [
        makeFinding({ id: 11, delta_percent: 20 }),
        makeFinding({ id: 12, delta_percent: 30 }),
      ];
      const losers = [makeFinding({ id: 13, delta_percent: -10 })];
      render(<WinnersLosersTable winners={winners} losers={losers} />);

      expect(screen.getByRole('tab', { name: /losers \(1\)/i })).toBeInTheDocument();
      expect(screen.getByRole('tab', { name: /winners \(2\)/i })).toBeInTheDocument();
    });
  });

  describe('severity labels and icons', () => {
    it('displays "Critical" label for high severity losers (abs >= 50)', () => {
      const losers = [makeFinding({ id: 20, delta_percent: -75 })];
      render(<WinnersLosersTable winners={[]} losers={losers} />);

      expect(screen.getByText('Critical')).toBeInTheDocument();
    });

    it('displays "Warning" label for medium severity losers (abs >= 20 and < 50)', () => {
      const losers = [makeFinding({ id: 21, delta_percent: -35 })];
      render(<WinnersLosersTable winners={[]} losers={losers} />);

      expect(screen.getByText('Warning')).toBeInTheDocument();
    });

    it('displays "Minor" label for low severity (abs < 20)', () => {
      const losers = [makeFinding({ id: 22, delta_percent: -10 })];
      render(<WinnersLosersTable winners={[]} losers={losers} />);

      expect(screen.getByText('Minor')).toBeInTheDocument();
    });

    it('displays "Gain" label for winners', async () => {
      const user = userEvent.setup();
      const winners = [makeFinding({ id: 23, delta_percent: 45 })];
      render(<WinnersLosersTable winners={winners} losers={[]} />);

      const winnersTab = screen.getByRole('tab', { name: /winners/i });
      await user.click(winnersTab);

      expect(screen.getByText('Gain')).toBeInTheDocument();
    });

    it('includes severity information in row aria-label', () => {
      const losers = [makeFinding({ id: 24, delta_percent: -60 })];
      const { container } = render(<WinnersLosersTable winners={[]} losers={losers} />);

      const row = container.querySelector('tbody tr');
      expect(row).toHaveAttribute('aria-label', expect.stringContaining('Critical'));
    });

    it('displays severity labels for different delta percentages', () => {
      const losers = [
        makeFinding({ id: 25, delta_percent: -80 }),
        makeFinding({ id: 26, delta_percent: -30 }),
        makeFinding({ id: 27, delta_percent: -5 }),
      ];
      render(<WinnersLosersTable winners={[]} losers={losers} />);

      expect(screen.getByText('Critical')).toBeInTheDocument();
      expect(screen.getByText('Warning')).toBeInTheDocument();
      expect(screen.getAllByText('Minor').length).toBeGreaterThan(0);
    });
  });

  describe('responsive expandable row details', () => {
    it('renders expand button with correct responsive classes', () => {
      const losers = [makeFinding({ id: 40, delta_percent: -30 })];
      render(<WinnersLosersTable winners={[]} losers={losers} />);

      const expandButton = screen.getByRole('button', { name: /expand details/i });
      expect(expandButton).toBeInTheDocument();

      // Button should be in a cell with md:hidden class
      const buttonCell = expandButton.closest('td');
      expect(buttonCell).toHaveClass('md:hidden');
    });

    it('expands row details when expand button is clicked', async () => {
      const user = userEvent.setup();
      const losers = [makeFinding({ id: 41, delta_percent: -30 })];
      render(<WinnersLosersTable winners={[]} losers={losers} />);

      const expandButton = screen.getByRole('button', { name: /expand details/i });
      await user.click(expandButton);

      // Should show expanded row with details
      expect(screen.getByText('Clicks Before:')).toBeInTheDocument();
      expect(screen.getByText('Clicks After:')).toBeInTheDocument();
    });

    it('shows hidden column data in expanded row', async () => {
      const user = userEvent.setup();
      const losers = [
        makeFinding({
          id: 42,
          delta_percent: -30,
          supporting_data: {
            clicks_before: 150,
            clicks_after: 75,
          },
        }),
      ];
      render(<WinnersLosersTable winners={[]} losers={losers} />);

      const expandButton = screen.getByRole('button', { name: /expand details/i });
      await user.click(expandButton);

      // Verify the data is displayed (should appear in both hidden cells and expanded section)
      expect(screen.getAllByText('150').length).toBeGreaterThan(0);
      expect(screen.getAllByText('75').length).toBeGreaterThan(0);
    });

    it('rotates chevron icon when row is expanded', async () => {
      const user = userEvent.setup();
      const losers = [makeFinding({ id: 43, delta_percent: -30 })];
      render(<WinnersLosersTable winners={[]} losers={losers} />);

      const expandButton = screen.getByRole('button', { name: /expand details/i });
      const chevron = expandButton.querySelector('svg');

      expect(chevron).not.toHaveClass('rotate-180');

      await user.click(expandButton);

      expect(chevron).toHaveClass('rotate-180');
    });

    it('collapses row when expand button is clicked again', async () => {
      const user = userEvent.setup();
      const losers = [makeFinding({ id: 44, delta_percent: -30 })];
      render(<WinnersLosersTable winners={[]} losers={losers} />);

      const expandButton = screen.getByRole('button', { name: /expand details/i });

      // Expand
      await user.click(expandButton);
      expect(screen.getByText('Clicks Before:')).toBeInTheDocument();

      // Collapse
      const collapseButton = screen.getByRole('button', { name: /collapse details/i });
      await user.click(collapseButton);

      expect(screen.queryByText('Clicks Before:')).not.toBeInTheDocument();
    });

    it('expanded row has correct responsive classes', async () => {
      const user = userEvent.setup();
      const losers = [makeFinding({ id: 45, delta_percent: -30 })];
      const { container } = render(<WinnersLosersTable winners={[]} losers={losers} />);

      const expandButton = screen.getByRole('button', { name: /expand details/i });
      await user.click(expandButton);

      // Find the expanded detail row
      const expandedRows = container.querySelectorAll('tbody tr');
      const detailRow = expandedRows[1]; // Second row should be the detail row

      expect(detailRow).toHaveClass('md:hidden');
    });

    it('only one row can be expanded at a time', async () => {
      const user = userEvent.setup();
      const losers = [
        makeFinding({ id: 46, delta_percent: -30 }),
        makeFinding({ id: 47, delta_percent: -40 }),
      ];
      render(<WinnersLosersTable winners={[]} losers={losers} />);

      const expandButtons = screen.getAllByRole('button', { name: /expand details/i });

      // Expand first row
      await user.click(expandButtons[0]);
      expect(screen.getAllByText('Clicks Before:').length).toBe(1);

      // Expand second row - first should collapse
      await user.click(expandButtons[1]);
      expect(screen.getAllByText('Clicks Before:').length).toBe(1);
    });

    it('expandable rows work on winners tab', async () => {
      const user = userEvent.setup();
      const winners = [makeFinding({ id: 48, delta_percent: 50 })];
      render(<WinnersLosersTable winners={winners} losers={[]} />);

      const winnersTab = screen.getByRole('tab', { name: /winners/i });
      await user.click(winnersTab);

      const expandButton = screen.getByRole('button', { name: /expand details/i });
      await user.click(expandButton);

      expect(screen.getByText('Clicks Before:')).toBeInTheDocument();
      expect(screen.getByText('Clicks After:')).toBeInTheDocument();
    });

    it('expanded row does not have bottom border', async () => {
      const user = userEvent.setup();
      const losers = [makeFinding({ id: 49, delta_percent: -30 })];
      const { container } = render(<WinnersLosersTable winners={[]} losers={losers} />);

      const expandButton = screen.getByRole('button', { name: /expand details/i });

      // Check main row has border when collapsed
      const mainRow = container.querySelector('tbody tr');
      expect(mainRow?.className).toContain('border-b');

      // Expand and check border is removed
      await user.click(expandButton);
      expect(mainRow?.className).not.toContain('border-b');
    });

    it('expanded row content is in a Card component', async () => {
      const user = userEvent.setup();
      const losers = [makeFinding({ id: 50, delta_percent: -30 })];
      const { container } = render(<WinnersLosersTable winners={[]} losers={losers} />);

      const expandButton = screen.getByRole('button', { name: /expand details/i });
      await user.click(expandButton);

      // The expanded content should be in a Card (shadow-none class is used)
      const card = container.querySelector('.shadow-none');
      expect(card).toBeInTheDocument();
    });

    it('hidden columns have correct responsive classes in table header', () => {
      const losers = [makeFinding({ id: 51, delta_percent: -30 })];
      const { container } = render(<WinnersLosersTable winners={[]} losers={losers} />);

      const headers = container.querySelectorAll('thead th');

      // Clicks Before and Clicks After should be hidden on mobile
      const clicksBeforeHeader = Array.from(headers).find((h) => h.textContent === 'Clicks Before');
      const clicksAfterHeader = Array.from(headers).find((h) => h.textContent === 'Clicks After');

      expect(clicksBeforeHeader).toHaveClass('hidden', 'md:table-cell');
      expect(clicksAfterHeader).toHaveClass('hidden', 'md:table-cell');
    });

    it('hidden columns have correct responsive classes in table cells', () => {
      const losers = [makeFinding({ id: 52, delta_percent: -30 })];
      const { container } = render(<WinnersLosersTable winners={[]} losers={losers} />);

      const cells = container.querySelectorAll('tbody td');

      // Find cells with clicks data (should have hidden md:table-cell)
      const hiddenCells = Array.from(cells).filter(
        (cell) => cell.classList.contains('hidden') && cell.classList.contains('md:table-cell'),
      );

      // Should have 2 hidden cells per row (clicks before and after)
      expect(hiddenCells.length).toBe(2);
    });
  });
});
