/**
 * ADMFE-R15-01 — Render-contract guard: CannibalizationCases Show
 *
 * Asserts that impact_score, confidence_score, and lead_volatility_score
 * render via .toFixed(2) without crashing.  Before the controller fix,
 * these arrive as strings (decimal:4 cast) and .toFixed on a string throws.
 */
import { render, screen } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';

import type { AdminCannibalizationCasesShowProps } from '@/types/admin';

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

vi.mock('@inertiajs/react', async () => {
  const actual = await vi.importActual('@inertiajs/react');
  return {
    ...actual,
    Head: ({ title }: { title: string }) => <title>{title}</title>,
    usePage: vi.fn(() => ({
      url: '/admin/cannibalization-cases/1',
      props: {
        auth: { user: { name: 'Admin', email: 'admin@test.com' } },
        features: {
          billing: false,
          socialAuth: false,
          emailVerification: true,
          apiTokens: true,
          userSettings: true,
          notifications: false,
        },
      },
    })),
    Link: ({
      children,
      href,
      ...rest
    }: {
      children: React.ReactNode;
      href: string;
      className?: string;
    }) => (
      <a href={href} {...rest}>
        {children}
      </a>
    ),
  };
});

import CannibalizationCasesShow from './Show';

const defaultProps: AdminCannibalizationCasesShowProps = {
  case: {
    id: 1,
    cannibalization_run_id: 10,
    site_id: 1,
    site_name: 'Test Site',
    site_domain: 'test.com',
    query_cluster: 'best seo tools',
    competing_pages_count: 2,
    impact_score: 42.5,
    confidence_score: 80.0,
    lead_volatility_score: null,
    status: 'open',
    lifecycle_status: 'active',
    primary_page_url: 'https://test.com/seo-tools',
    dismissed_at: null,
    created_at: '2026-01-01T00:00:00.000Z',
    pages: [
      {
        id: 1,
        url: 'https://test.com/page-a',
        title: 'Page A',
        impressions: 100,
        clicks: 10,
      },
    ],
    queries: [
      {
        id: 1,
        query: 'best seo',
        impressions: 500,
        clicks: 25,
      },
    ],
    feedback: [],
  },
};

describe('CannibalizationCasesShow — ADMFE-R15-01 decimal-score render guard', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('renders without crashing when scores are numbers', () => {
    // Before fix: '42.5000'.toFixed is undefined → TypeError
    expect(() => render(<CannibalizationCasesShow {...defaultProps} />)).not.toThrow();
  });

  it('renders impact score with 2 decimal places', () => {
    render(<CannibalizationCasesShow {...defaultProps} />);
    // toFixed(2) on 42.5 → '42.50'
    expect(screen.getByText('42.50')).toBeInTheDocument();
  });

  it('renders confidence score with 2 decimal places', () => {
    render(<CannibalizationCasesShow {...defaultProps} />);
    // toFixed(2) on 80.0 → '80.00'
    expect(screen.getByText('80.00')).toBeInTheDocument();
  });

  it('renders lead_volatility_score with 2 decimal places', () => {
    render(
      <CannibalizationCasesShow
        {...defaultProps}
        case={{ ...defaultProps.case, lead_volatility_score: 33.125 }}
      />,
    );
    expect(screen.getByText('33.13')).toBeInTheDocument();
  });

  it('renders em-dash for null scores', () => {
    render(
      <CannibalizationCasesShow
        {...defaultProps}
        case={{
          ...defaultProps.case,
          impact_score: null,
          confidence_score: null,
          lead_volatility_score: null,
        }}
      />,
    );
    const dashes = screen.getAllByText('—');
    expect(dashes.length).toBeGreaterThanOrEqual(3);
  });

  it('renders the query cluster name as the page title', () => {
    render(<CannibalizationCasesShow {...defaultProps} />);
    expect(screen.getByText('best seo tools')).toBeInTheDocument();
  });

  it('renders competing pages table', () => {
    render(<CannibalizationCasesShow {...defaultProps} />);
    expect(screen.getByText('Competing Pages (1)')).toBeInTheDocument();
    expect(screen.getByText('https://test.com/page-a')).toBeInTheDocument();
    expect(screen.getByText('Page A')).toBeInTheDocument();
  });

  it('renders queries table', () => {
    render(<CannibalizationCasesShow {...defaultProps} />);
    expect(screen.getByText('Queries')).toBeInTheDocument();
    expect(screen.getByText('best seo')).toBeInTheDocument();
  });

  it('renders feedback section when feedback is present', () => {
    const propsWithFeedback = {
      ...defaultProps,
      case: {
        ...defaultProps.case,
        feedback: [
          {
            id: 1,
            rating: 4,
            comment: 'Great catch',
            user_name: 'Alice',
            created_at: '2026-01-01T00:00:00.000Z',
          },
        ],
      },
    };
    render(<CannibalizationCasesShow {...propsWithFeedback} />);
    // Feedback card header appears when feedback is non-empty
    expect(screen.getByText('Great catch')).toBeInTheDocument();
    expect(screen.getByText('Rating: 4/5')).toBeInTheDocument();
  });
});
