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

import CannibalizationShow from './Show';

vi.mock('@inertiajs/react', async () => {
  const actual = await vi.importActual('@inertiajs/react');
  return {
    ...actual,
    Head: ({ title }: { title: string }) => <title>{title}</title>,
    Link: ({ children, href }: { children: React.ReactNode; href: string }) => (
      <a href={href}>{children}</a>
    ),
  };
});

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/ui/badge', () => ({
  Badge: ({ children, variant }: { children: React.ReactNode; variant?: string }) => (
    <span data-testid="badge" data-variant={variant}>{children}</span>
  ),
}));

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

vi.mock('@/Components/ui/table', () => ({
  Table: ({ children }: { children: React.ReactNode }) => <table>{children}</table>,
  TableBody: ({ children }: { children: React.ReactNode }) => <tbody>{children}</tbody>,
  TableCell: ({ children }: { children: React.ReactNode }) => <td>{children}</td>,
  TableHead: ({ children }: { children: React.ReactNode }) => <th>{children}</th>,
  TableHeader: ({ children }: { children: React.ReactNode }) => <thead>{children}</thead>,
  TableRow: ({ children }: { children: React.ReactNode }) => <tr>{children}</tr>,
}));

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

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

vi.mock('@/lib/format', () => ({
  formatDateOnly: (d: string) => d,
  formatNumber: (n: number) => String(n),
  formatPercent: (n: number) => `${n}%`,
}));

const mockCase = {
  id: 1,
  query_cluster: 'best laptops 2026',
  competing_pages_count: 3,
  lead_volatility_score: 0.8,
  impact_score: 85,
  confidence_score: 72,
  primary_page_url: '/laptop-guide',
  status: 'open',
  lifecycle_status: 'pending',
  dismissed_at: null,
  created_at: '2026-01-15T00:00:00Z',
};

const mockProps = {
  site: { id: 1, name: 'Test Site', domain: 'https://test.com' },
  cannibalizationRun: { id: 1, status: 'completed', completed_at: '2026-01-15' },
  case: mockCase,
  pages: [
    {
      id: 1,
      page_url: '/page-a',
      is_primary: true,
      impressions_share: 0.6,
      clicks_share: 0.65,
      avg_position: 4.2,
      metrics_summary: null,
    },
  ],
  queries: [
    {
      id: 1,
      query: 'best laptops',
      total_impressions: 500,
      total_clicks: 30,
      pages_count: 2,
      lead_page_switches: 3,
    },
  ],
  feedback: [],
};

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

  it('renders page title with site name and query cluster', () => {
    render(<CannibalizationShow {...mockProps} />);
    expect(document.querySelector('title')).toHaveTextContent(
      'Test Site - best laptops 2026',
    );
  });

  it('renders the query cluster as heading', () => {
    render(<CannibalizationShow {...mockProps} />);
    expect(screen.getByRole('heading', { name: 'best laptops 2026' })).toBeInTheDocument();
  });

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

  it('displays competing pages count', () => {
    render(<CannibalizationShow {...mockProps} />);
    expect(screen.getByText('3 competing pages')).toBeInTheDocument();
  });

  it('displays impact badge', () => {
    render(<CannibalizationShow {...mockProps} />);
    const badges = screen.getAllByTestId('badge');
    const highImpact = badges.find((b) => b.textContent === 'High Impact');
    expect(highImpact).toBeInTheDocument();
  });

  it('displays volatility badge', () => {
    render(<CannibalizationShow {...mockProps} />);
    const badges = screen.getAllByTestId('badge');
    const highVolatility = badges.find((b) => b.textContent === 'High Volatility');
    expect(highVolatility).toBeInTheDocument();
  });

  it('displays status badge', () => {
    render(<CannibalizationShow {...mockProps} />);
    const badges = screen.getAllByTestId('badge');
    const statusBadge = badges.find((b) => b.textContent === 'open');
    expect(statusBadge).toBeInTheDocument();
  });

  it('renders back to cannibalization link', () => {
    render(<CannibalizationShow {...mockProps} />);
    expect(
      screen.getByRole('link', { name: /Back to Cannibalization Cases/i }),
    ).toBeInTheDocument();
  });

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