import { render, screen } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';

import { router, usePage } from '@inertiajs/react';

import GeographicIndex from './Index';

vi.mock('@inertiajs/react', async () => {
  const actual = await vi.importActual('@inertiajs/react');
  return {
    ...actual,
    usePage: vi.fn(() => ({
      props: {
        auth: {
          user: {
            name: 'Test User',
            email: 'test@example.com',
          },
        },
        features: {
          notifications: false,
        },
      },
    })),
    router: {
      visit: vi.fn(),
    },
    Head: ({ title }: { title: string }) => <title>{title}</title>,
    Link: ({ children, href }: { children: React.ReactNode; href: string }) => (
      <a href={href}>{children}</a>
    ),
  };
});

// Mock the useTheme hook
vi.mock('@/Components/theme/use-theme', () => ({
  useTheme: vi.fn(() => ({
    theme: 'system',
    setTheme: vi.fn(),
    resolvedTheme: 'light',
  })),
}));

// Mock the SiteNav component
vi.mock('@/Components/Navigation/SiteNav', () => ({
  default: () => <div data-testid="site-nav" />,
}));

// Mock LazyCharts so LazyCountryMap resolves synchronously (no Suspense async dance in jsdom)
vi.mock('@/Components/ui/charts/LazyCharts', () => ({
  LazyCountryMap: ({ data, 'aria-label': ariaLabel }: Record<string, unknown>) => (
    <div data-testid="country-map" aria-label={ariaLabel as string}>
      Country Map with {(data as Array<Record<string, unknown>>).length} countries
    </div>
  ),
}));

// Mock the CountryTable component
vi.mock('@/Components/Geographic/CountryTable', () => ({
  default: ({
    data,
    onRowClick,
  }: {
    data: Array<Record<string, unknown>>;
    onRowClick?: (country: string) => void;
  }) => (
    <div data-testid="country-table" onClick={() => onRowClick && onRowClick('USA')}>
      Country Table with {data.length} countries
    </div>
  ),
}));

const mockedUsePage = vi.mocked(usePage);

const defaultSite = {
  id: 1,
  name: 'Test Site',
  domain: 'example.com',
};

const mockCountryData = [
  {
    country: 'United States',
    clicks: 1000,
    impressions: 50000,
    ctr: 0.02,
    position: 15.5,
  },
  {
    country: 'United Kingdom',
    clicks: 500,
    impressions: 25000,
    ctr: 0.02,
    position: 12.3,
  },
];

describe('GeographicIndex', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    mockedUsePage.mockReturnValue({
      props: {
        auth: {
          user: {
            name: 'Test User',
            email: 'test@example.com',
          },
        },
        features: {
          notifications: false,
        },
      },
    } as unknown as ReturnType<typeof usePage>);
  });

  // ============================================
  // Rendering tests
  // ============================================

  describe('rendering', () => {
    it('renders the geographic performance page', () => {
      render(<GeographicIndex site={defaultSite} countries={[]} />);

      expect(screen.getByText('Geographic Performance')).toBeInTheDocument();
    });

    it('renders the page description', () => {
      render(<GeographicIndex site={defaultSite} countries={[]} />);

      expect(
        screen.getByText('Traffic metrics by country showing where your audience is located'),
      ).toBeInTheDocument();
    });

    it('sets the page title with site name', () => {
      render(<GeographicIndex site={defaultSite} countries={[]} />);

      expect(document.querySelector('title')).toHaveTextContent(
        'Test Site - Geographic Performance',
      );
    });
  });

  // ============================================
  // Empty state tests
  // ============================================

  describe('empty state', () => {
    it('shows empty state when no countries data', () => {
      render(<GeographicIndex site={defaultSite} countries={[]} />);

      expect(screen.getByText('No geographic data yet')).toBeInTheDocument();
      expect(
        screen.getByText(
          'Connect Google Search Console and sync your data to see country-level performance metrics.',
        ),
      ).toBeInTheDocument();
    });

    it('does not show map and table when no data', () => {
      render(<GeographicIndex site={defaultSite} countries={[]} />);

      expect(screen.queryByTestId('country-map')).not.toBeInTheDocument();
      expect(screen.queryByTestId('country-table')).not.toBeInTheDocument();
    });
  });

  // ============================================
  // With data tests
  // ============================================

  describe('with data', () => {
    it('renders country map when data is available', () => {
      render(<GeographicIndex site={defaultSite} countries={mockCountryData} />);

      expect(screen.getByTestId('country-map')).toBeInTheDocument();
      expect(screen.getByText(/Country Map with 2 countries/)).toBeInTheDocument();
    });

    it('renders country table when data is available', () => {
      render(<GeographicIndex site={defaultSite} countries={mockCountryData} />);

      expect(screen.getByTestId('country-table')).toBeInTheDocument();
      expect(screen.getByText(/Country Table with 2 countries/)).toBeInTheDocument();
    });

    it('does not show empty state when data is available', () => {
      render(<GeographicIndex site={defaultSite} countries={mockCountryData} />);

      expect(screen.queryByText('No geographic data yet')).not.toBeInTheDocument();
    });

    it('renders section headings', () => {
      render(<GeographicIndex site={defaultSite} countries={mockCountryData} />);

      expect(screen.getByText('Country Heatmap')).toBeInTheDocument();
    });
  });

  // ============================================
  // Layout integration tests
  // ============================================

  describe('layout integration', () => {
    it('renders within container with proper spacing', () => {
      const { container } = render(<GeographicIndex site={defaultSite} countries={[]} />);

      expect(container.querySelector('.container')).toBeInTheDocument();
    });

    it('renders SiteNav component', () => {
      render(<GeographicIndex site={defaultSite} countries={[]} />);

      // SiteNav should render
      expect(screen.getByTestId('site-nav')).toBeInTheDocument();
    });

    it('has layout property set to DashboardLayout', () => {
      // The .layout property is used by Inertia to wrap the component
      expect(GeographicIndex.layout).toBeDefined();
    });
  });

  // ============================================
  // Accessibility tests
  // ============================================

  describe('accessibility', () => {
    it('has proper heading hierarchy', () => {
      render(<GeographicIndex site={defaultSite} countries={mockCountryData} />);

      // Main heading
      expect(
        screen.getByRole('heading', { level: 1, name: 'Geographic Performance' }),
      ).toBeInTheDocument();

      // Section headings
      expect(
        screen.getByRole('heading', { level: 2, name: 'Country Heatmap' }),
      ).toBeInTheDocument();
    });

    it('has proper aria-labels on sections', () => {
      render(<GeographicIndex site={defaultSite} countries={mockCountryData} />);

      // Check that sections have proper aria labels
      expect(
        screen.getByLabelText('Heatmap showing traffic distribution by country'),
      ).toBeInTheDocument();
    });

    it('sections have proper aria-labelledby attributes', () => {
      const { container } = render(
        <GeographicIndex site={defaultSite} countries={mockCountryData} />,
      );

      // Check for aria-labelledby on sections
      const sections = container.querySelectorAll('section');
      expect(sections.length).toBeGreaterThan(0);
      sections.forEach((section) => {
        expect(section.getAttribute('aria-labelledby')).toBeTruthy();
      });
    });
  });

  // ============================================
  // Navigation tests
  // ============================================

  describe('navigation', () => {
    it('navigates to detail page when handleCountryClick is called', () => {
      const { container } = render(
        <GeographicIndex site={defaultSite} countries={mockCountryData} />,
      );

      const countryTable = container.querySelector('[data-testid="country-table"]');
      countryTable?.dispatchEvent(new MouseEvent('click', { bubbles: true }));

      expect(router.visit).toHaveBeenCalledWith('/sites/1/geographic/USA');
    });
  });
});
