import type { ComponentSettings } from '@nitrogenbuilder/types';
import { describe, expect, it } from 'vitest';

import {
	createComponentManifest,
	createComponentManifestEntry,
} from './componentManifest.js';

function makeSettings(
	overrides: Partial<ComponentSettings> = {}
): ComponentSettings {
	return {
		options: { category: 'Layout' },
		categories: {
			content: {
				label: 'Content',
				groups: {
					main: {
						label: 'Main',
						props: {
							heading: { type: 'string', label: 'Heading', default: 'Hi' },
						},
					},
				},
			},
		},
		...overrides,
	};
}

describe('createComponentManifestEntry', () => {
	it('carries the module description onto the manifest entry', () => {
		const entry = createComponentManifestEntry({
			name: 'Section',
			settings: makeSettings({
				description: 'A full-width layout section.',
			}),
		});

		expect(entry.name).toBe('Section');
		expect(entry.description).toBe('A full-width layout section.');
		// Schema still serialized so an agent can read prop paths.
		expect(entry.categories.content.groups.main.props.heading.type).toBe(
			'string'
		);
	});

	it('leaves description undefined when not provided', () => {
		const entry = createComponentManifestEntry({
			name: 'Section',
			settings: makeSettings(),
		});

		expect(entry.description).toBeUndefined();
	});
});

describe('createComponentManifest', () => {
	it('includes descriptions across the component list', () => {
		const manifest = createComponentManifest(
			[
				{
					name: 'Section',
					settings: makeSettings({ description: 'Layout container.' }),
				},
				{
					name: 'Button',
					settings: makeSettings({ description: 'A clickable button.' }),
				},
			],
			{ generatedAt: '2026-01-01T00:00:00.000Z' }
		);

		// Sorted by name → Button before Section.
		expect(manifest.components.map((c) => c.name)).toEqual([
			'Button',
			'Section',
		]);
		expect(manifest.components.map((c) => c.description)).toEqual([
			'A clickable button.',
			'Layout container.',
		]);
	});
});
