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

import TopicClustersIndex from './Index';

vi.mock('@inertiajs/react', async () => {
  const actual = await vi.importActual('@inertiajs/react');
  return {
    ...actual,
    Head: ({ title }: { title: string }) => <title>{title}</title>,
    router: { post: vi.fn() },
  };
});

vi.mock('@/Layouts/DashboardLayout', () => ({
  default: ({ children }: { children: React.ReactNode }) => (
    <div data-testid="dashboard-layout">{children}</div>
  ),
}));

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

vi.mock('@/Components/TopicClusters/ClusterCard', () => ({
  default: ({ cluster }: { cluster: { name: string } }) => (
    <div data-testid="cluster-card">{cluster.name}</div>
  ),
}));

vi.mock('@/Components/ui/button', () => ({
  Button: ({
    children,
    onClick,
    disabled,
  }: {
    children: React.ReactNode;
    onClick?: () => void;
    disabled?: boolean;
  }) => (
    <button onClick={onClick} disabled={disabled}>
      {children}
    </button>
  ),
}));

vi.mock('@/Components/ui/empty-state', () => ({
  EmptyState: ({
    title,
    description,
  }: {
    title: string;
    description: string;
  }) => (
    <div data-testid="empty-state">
      <div>{title}</div>
      <div>{description}</div>
    </div>
  ),
}));

vi.mock('@/lib/analytics', () => ({
  trackProductEvent: vi.fn(),
}));

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

const mockCluster = {
  id: 1,
  name: 'SEO Tools',
  total_demand: 5000,
  coverage_percentage: 65,
  hub_page_url: '/seo-tools',
  metadata: { representative_queries: ['seo tools', 'best seo'] },
  page_count: 8,
  query_count: 24,
  gap_count: 3,
};

const mockProps = {
  site: { id: 1, name: 'Test Site', domain: 'https://test.com' },
  clusters: [mockCluster],
  latestRun: { id: 1, status: 'completed', started_at: '2026-01-15', completed_at: '2026-01-15', summary: null },
  filters: { coverage: null, demand: null },
  counts: { total: 1, high_coverage: 1, low_coverage: 0 },
};

describe('TopicClusters/Index', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    vi.stubGlobal('route', vi.fn((...args: string[]) => `/mock-route/${args[0]}`));
  });

  it('renders SiteNav', () => {
    render(<TopicClustersIndex {...mockProps} />);
    expect(screen.getByTestId('site-nav')).toBeInTheDocument();
  });

  it('renders cluster cards when clusters exist', () => {
    render(<TopicClustersIndex {...mockProps} />);
    expect(screen.getByTestId('cluster-card')).toBeInTheDocument();
    expect(screen.getByText('SEO Tools')).toBeInTheDocument();
  });

  it('shows empty state when no clusters and no run', () => {
    render(<TopicClustersIndex {...mockProps} clusters={[]} latestRun={null} />);
    expect(screen.getByTestId('empty-state')).toBeInTheDocument();
  });

  it('shows recompute button', () => {
    render(<TopicClustersIndex {...mockProps} />);
    expect(screen.getByRole('button', { name: /recompute/i })).toBeInTheDocument();
  });

  it('assigns DashboardLayout as layout', () => {
    expect(TopicClustersIndex.layout).toBeDefined();
  });
});
