import { describe, it, expect, afterEach, vi } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';

import EnrichmentBlock from './EnrichmentBlock.svelte';

// Hoist the mutable navigation reference so vi.mock's factory (also hoisted)
// can read it via a getter. Sync factory, no dynamic import: ADR-012 invariant.
const { mockNavigating } = vi.hoisted(() => ({
	mockNavigating: { type: null as string | null }
}));

vi.mock('$app/state', () => ({
	get navigating() {
		return mockNavigating;
	}
}));

afterEach(() => {
	cleanup();
	mockNavigating.type = null;
});

type Doc = { id: string; title: string; uploadedAt: string };

function doc(id: string, title = 'Doc'): Doc {
	return { id, title, uploadedAt: '2026-04-20T12:00:00' };
}

describe('EnrichmentBlock', () => {
	it('renders nothing when topDocs is empty and banner count is 0', async () => {
		render(EnrichmentBlock, {
			topDocs: [],
			totalCount: 0,
			bannerCount: 0,
			onBannerClose: vi.fn()
		});
		await expect.element(page.getByTestId('enrichment-block')).not.toBeInTheDocument();
	});

	it('renders the list component when topDocs is non-empty', async () => {
		render(EnrichmentBlock, {
			topDocs: [doc('d1')],
			totalCount: 1,
			bannerCount: 0,
			onBannerClose: vi.fn()
		});
		await expect.element(page.getByTestId('dashboard-needs-metadata')).toBeInTheDocument();
	});

	it('renders the banner when bannerCount > 0', async () => {
		render(EnrichmentBlock, {
			topDocs: [],
			totalCount: 0,
			bannerCount: 3,
			onBannerClose: vi.fn()
		});
		await expect.element(page.getByRole('status')).toBeInTheDocument();
	});

	it('composes banner + list when both are present', async () => {
		render(EnrichmentBlock, {
			topDocs: [doc('d1')],
			totalCount: 1,
			bannerCount: 2,
			onBannerClose: vi.fn()
		});
		await expect.element(page.getByRole('status')).toBeInTheDocument();
		await expect.element(page.getByTestId('dashboard-needs-metadata')).toBeInTheDocument();
	});

	it('renders the skeleton when navigation is active and topDocs is empty', async () => {
		mockNavigating.type = 'link';
		render(EnrichmentBlock, {
			topDocs: [],
			totalCount: 0,
			bannerCount: 0,
			onBannerClose: vi.fn()
		});
		await expect.element(page.getByTestId('enrichment-block-skeleton')).toBeInTheDocument();
	});

	it('does not render the skeleton when topDocs is non-empty even during navigation', async () => {
		mockNavigating.type = 'link';
		render(EnrichmentBlock, {
			topDocs: [doc('d1')],
			totalCount: 1,
			bannerCount: 0,
			onBannerClose: vi.fn()
		});
		await expect.element(page.getByTestId('enrichment-block-skeleton')).not.toBeInTheDocument();
	});
});
