/**
 * REP-PERF-R15-01: SharedReport Body — row budget + overflow footer tests.
 *
 * Verifies that:
 * 1. The public shared-report body shows exactly VISIBLE_* rows per section
 * 2. An overflow footer "Showing X of N" appears when N > VISIBLE_*
 * 3. The overflow footer on the PUBLIC view shows plain text (no auth link)
 * 4. No footer when all rows fit within the budget
 */
import { render, screen } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';

import { VISIBLE_FINDINGS, VISIBLE_RECOMMENDATIONS } from '@/Components/Reports/reportLimits';

import { SharedReportBody as Body } from './Body';

vi.mock('recharts', () => ({
  ResponsiveContainer: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
  LineChart: () => <div data-testid="line-chart" />,
  Line: () => null,
  XAxis: () => null,
  YAxis: () => null,
  CartesianGrid: () => null,
  Tooltip: () => null,
  Legend: () => null,
}));

vi.mock('@/Components/SharedReport/HeroKpiBand', () => ({
  HeroKpiBand: () => <div data-testid="hero-kpi-band" />,
}));

vi.mock('@/Components/ui/charts/LazyCharts', () => ({
  LazyLineChart: () => <div data-testid="lazy-line-chart" />,
}));

const baseReport = {
  id: 1,
  name: 'Shared Report',
  sections: ['findings'],
  data: {
    site: { id: 1, name: 'Test Site', domain: 'example.com' },
    generated_at: '2026-01-15 10:00:00',
    filters: {},
    branding: null,
  },
};

describe('SharedReport Body', () => {
  it('renders without crashing', () => {
    const { container } = render(<Body report={baseReport} />);
    expect(container).toBeTruthy();
  });

  // REP-PERF-R15-01: row budget
  it('shows exactly VISIBLE_FINDINGS rows for a 50-row findings section', () => {
    const findings50 = Array.from({ length: 50 }, (_, i) => ({
      id: i + 1,
      type: 'winner',
      direction: 'winner',
      page_url: `https://example.com/page-${i + 1}`,
      segment_type: null,
      segment_value: null,
      metric_before: 100,
      metric_after: 120,
      delta_absolute: 20,
      delta_percent: 20,
      supporting_data: {},
    }));
    const report = {
      ...baseReport,
      sections: ['findings'],
      data: {
        ...baseReport.data,
        findings: {
          findings: findings50,
          total_count: 50,
          truncated: true,
          truncated_count: 30,
        },
      },
    };
    render(<Body report={report} />);

    const pageUrlCells = screen.getAllByText(/^https:\/\/example\.com\/page-\d+$/);
    expect(pageUrlCells).toHaveLength(VISIBLE_FINDINGS);
  });

  it('shows overflow footer "Showing 20 of 50" for a 50-row findings section', () => {
    const findings50 = Array.from({ length: 50 }, (_, i) => ({
      id: i + 1,
      type: 'winner',
      direction: 'winner',
      page_url: `https://example.com/f-${i + 1}`,
      segment_type: null,
      segment_value: null,
      metric_before: 100,
      metric_after: 120,
      delta_absolute: 20,
      delta_percent: 20,
      supporting_data: {},
    }));
    const report = {
      ...baseReport,
      sections: ['findings'],
      data: {
        ...baseReport.data,
        findings: {
          findings: findings50,
          total_count: 50,
          truncated: true,
          truncated_count: 30,
        },
      },
    };
    render(<Body report={report} />);

    expect(screen.getByText(/Showing 20 of 50/)).toBeInTheDocument();
  });

  it('does NOT show an authenticated link in the public overflow footer', () => {
    const findings50 = Array.from({ length: 50 }, (_, i) => ({
      id: i + 1,
      type: 'winner',
      direction: 'winner',
      page_url: `https://example.com/pub-${i + 1}`,
      segment_type: null,
      segment_value: null,
      metric_before: 100,
      metric_after: 120,
      delta_absolute: 20,
      delta_percent: 20,
      supporting_data: {},
    }));
    const report = {
      ...baseReport,
      sections: ['findings'],
      data: {
        ...baseReport.data,
        findings: {
          findings: findings50,
          total_count: 50,
          truncated: true,
          truncated_count: 30,
        },
      },
    };
    render(<Body report={report} />);

    // The public view must NOT render a <a href> link in the overflow footer
    const overflowEl = screen.getByText(/Showing 20 of 50/);
    // Walk up to containing footer element and check no anchor inside it
    const footerEl = overflowEl.closest('[data-overflow-footer]') ?? overflowEl.parentElement;
    if (footerEl) {
      expect(footerEl.querySelector('a')).toBeNull();
    }
  });

  it('does NOT show findings overflow footer when all rows fit within budget', () => {
    const exactRows = Array.from({ length: VISIBLE_FINDINGS }, (_, i) => ({
      id: i + 1,
      type: 'winner',
      direction: 'winner',
      page_url: `https://example.com/exact-${i + 1}`,
      segment_type: null,
      segment_value: null,
      metric_before: 100,
      metric_after: 120,
      delta_absolute: 20,
      delta_percent: 20,
      supporting_data: {},
    }));
    const report = {
      ...baseReport,
      sections: ['findings'],
      data: {
        ...baseReport.data,
        findings: {
          findings: exactRows,
          total_count: VISIBLE_FINDINGS,
          truncated: false,
          truncated_count: 0,
        },
      },
    };
    render(<Body report={report} />);

    expect(screen.queryByText(/Showing/)).not.toBeInTheDocument();
  });

  it('shows exactly VISIBLE_RECOMMENDATIONS rows for a 25-row recs section', () => {
    const recs25 = Array.from({ length: 25 }, (_, i) => ({
      id: i + 1,
      page_url: `https://example.com/r-${i + 1}`,
      action_type: 'content_rewrite',
      lifecycle_status: 'pending',
      impact_score: 80,
      confidence_score: 90,
      title: `Recommendation ${i + 1}`,
      reasoning: 'Reasoning text',
      evidence: {},
      applied_at: null,
    }));
    const report = {
      ...baseReport,
      sections: ['recommendations'],
      data: {
        ...baseReport.data,
        recommendations: {
          recommendations: recs25,
          total_count: 25,
          truncated: true,
          truncated_count: 15,
          status_counts: { pending: 25, reviewed: 0, approved: 0, applied: 0, rejected: 0 },
          analysis_run_id: 1,
          grouped_by_action_type: [],
        },
      },
    };
    render(<Body report={report} />);

    const titles = screen.getAllByText(/^Recommendation \d+$/);
    expect(titles).toHaveLength(VISIBLE_RECOMMENDATIONS);
  });

  it('shows overflow footer "Showing 10 of 25" for a 25-row recs section', () => {
    const recs25 = Array.from({ length: 25 }, (_, i) => ({
      id: i + 1,
      page_url: `https://example.com/r2-${i + 1}`,
      action_type: 'content_rewrite',
      lifecycle_status: 'pending',
      impact_score: 80,
      confidence_score: 90,
      title: `Rec ${i + 1}`,
      reasoning: 'Reasoning',
      evidence: {},
      applied_at: null,
    }));
    const report = {
      ...baseReport,
      sections: ['recommendations'],
      data: {
        ...baseReport.data,
        recommendations: {
          recommendations: recs25,
          total_count: 25,
          truncated: true,
          truncated_count: 15,
          status_counts: { pending: 25, reviewed: 0, approved: 0, applied: 0, rejected: 0 },
          analysis_run_id: 1,
          grouped_by_action_type: [],
        },
      },
    };
    render(<Body report={report} />);

    expect(screen.getByText(/Showing 10 of 25/)).toBeInTheDocument();
  });
});
