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

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

import DeviceIndex 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 the DeviceChart component
vi.mock('@/Components/Device/DeviceChart', () => ({
  DeviceChart: ({ data, 'aria-label': ariaLabel }: Record<string, unknown>) => (
    <div data-testid="device-chart" aria-label={ariaLabel as string}>
      Device Chart with {(data as Array<Record<string, unknown>>).length} devices
    </div>
  ),
}));

// Mock the DeviceTable component
vi.mock('@/Components/Device/DeviceTable', () => ({
  default: ({
    data,
    onRowClick,
  }: {
    data: Array<Record<string, unknown>>;
    onRowClick?: (device: string) => void;
  }) => (
    <div data-testid="device-table" onClick={() => onRowClick && onRowClick('MOBILE')}>
      Device Table with {data.length} devices
    </div>
  ),
}));

const mockedUsePage = vi.mocked(usePage);

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

const mockDeviceData = [
  {
    device: 'MOBILE',
    clicks: 1000,
    impressions: 50000,
    ctr: 0.02,
    position: 15.5,
  },
  {
    device: 'DESKTOP',
    clicks: 500,
    impressions: 25000,
    ctr: 0.02,
    position: 12.3,
  },
];

describe('DeviceIndex', () => {
  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 device performance page', () => {
      render(<DeviceIndex site={defaultSite} devices={[]} />);

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

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

      expect(
        screen.getByText(
          'Traffic metrics by device type showing mobile, desktop, and tablet performance',
        ),
      ).toBeInTheDocument();
    });

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

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

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

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

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

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

      expect(screen.queryByTestId('device-chart')).not.toBeInTheDocument();
      expect(screen.queryByTestId('device-table')).not.toBeInTheDocument();
    });
  });

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

  describe('with data', () => {
    it('renders device chart when data is available', () => {
      render(<DeviceIndex site={defaultSite} devices={mockDeviceData} />);

      expect(screen.getByTestId('device-chart')).toBeInTheDocument();
      expect(screen.getByText(/Device Chart with 2 devices/)).toBeInTheDocument();
    });

    it('renders device table when data is available', () => {
      render(<DeviceIndex site={defaultSite} devices={mockDeviceData} />);

      expect(screen.getByTestId('device-table')).toBeInTheDocument();
      expect(screen.getByText(/Device Table with 2 devices/)).toBeInTheDocument();
    });

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

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

    it('renders section headings', () => {
      render(<DeviceIndex site={defaultSite} devices={mockDeviceData} />);

      expect(screen.getByText('Device Performance Trends')).toBeInTheDocument();
    });
  });

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

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

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

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

      // 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(DeviceIndex.layout).toBeDefined();
    });
  });

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

  describe('accessibility', () => {
    it('has proper heading hierarchy', () => {
      render(<DeviceIndex site={defaultSite} devices={mockDeviceData} />);

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

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

    it('has proper aria-labels on sections', () => {
      render(<DeviceIndex site={defaultSite} devices={mockDeviceData} />);

      // Check that sections have proper aria labels
      expect(
        screen.getByLabelText('Chart showing traffic trends by device type'),
      ).toBeInTheDocument();
    });

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

      // 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 handleDeviceClick is called', () => {
      const { container } = render(<DeviceIndex site={defaultSite} devices={mockDeviceData} />);

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

      expect(router.visit).toHaveBeenCalledWith('/sites/1/device/MOBILE');
    });
  });
});
