/**
 * The detail sheet must load EVERY vulnerability (paging past the per-request
 * cap), not a single capped page, so severity filtering, inspection, and
 * suppression reach findings beyond the first page.
 */
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, waitFor } from '@testing-library/react';

vi.mock('@/lib/api', () => ({ apiFetch: vi.fn() }));
vi.mock('@/components/ui/toast-store', () => ({ toast: { error: vi.fn(), success: vi.fn() } }));

import { apiFetch } from '@/lib/api';
import { VulnerabilityScanSheet } from '../VulnerabilityScanSheet';

const mockedFetch = vi.mocked(apiFetch);
const ok = (body: unknown) => ({ ok: true, json: async () => body }) as Response;

function vuln(i: number) {
  return {
    id: i, scan_id: 1, vulnerability_id: `CVE-2026-${i}`, pkg_name: 'pkg', installed_version: '1',
    fixed_version: null, severity: 'HIGH', title: null, description: null, primary_url: null,
  };
}

const SCAN = {
  id: 1, node_id: 1, image_ref: 'img:1', image_digest: null, scanned_at: Date.now(),
  total_vulnerabilities: 1500, critical_count: 0, high_count: 1500, medium_count: 0, low_count: 0,
  unknown_count: 0, fixable_count: 0, secret_count: 0, misconfig_count: 0, scanners_used: 'vuln',
  highest_severity: 'HIGH', os_info: null, trivy_version: '0.50.0', scan_duration_ms: 1, triggered_by: 'manual',
  status: 'completed', error: null, stack_context: null, policy_evaluation: null,
};

beforeEach(() => {
  mockedFetch.mockReset();
  mockedFetch.mockImplementation(((url: string) => {
    if (/\/vulnerabilities\?limit=1000&offset=0/.test(url)) {
      return Promise.resolve(ok({ items: Array.from({ length: 1000 }, (_, i) => vuln(i)), total: 1500 }));
    }
    if (/\/vulnerabilities\?limit=1000&offset=1000/.test(url)) {
      return Promise.resolve(ok({ items: Array.from({ length: 500 }, (_, i) => vuln(1000 + i)), total: 1500 }));
    }
    if (/\/secrets/.test(url) || /\/misconfigs/.test(url) || /\/security\/scans\?imageRef/.test(url)) {
      return Promise.resolve(ok({ items: [] }));
    }
    if (/\/security\/scans\/1$/.test(url)) return Promise.resolve(ok(SCAN));
    return Promise.resolve(ok({ items: [] }));
  }) as unknown as typeof apiFetch);
});

describe('VulnerabilityScanSheet load', () => {
  it('pages the full vulnerability list instead of a single capped page', async () => {
    render(<VulnerabilityScanSheet scanId={1} onClose={() => {}} />);
    await waitFor(() => {
      const urls = mockedFetch.mock.calls.map((c) => String(c[0]));
      // Both pages of the offset-based full fetch were requested.
      expect(urls.some((u) => /vulnerabilities\?limit=1000&offset=0/.test(u))).toBe(true);
      expect(urls.some((u) => /vulnerabilities\?limit=1000&offset=1000/.test(u))).toBe(true);
    });
    // The old single capped page request is gone.
    const urls = mockedFetch.mock.calls.map((c) => String(c[0]));
    expect(urls.some((u) => /vulnerabilities\?limit=500/.test(u))).toBe(false);
  });
});
