#!/usr/bin/env node
/**
 * Generates lucideIconData.ts with search metadata (keywords + categories) for Lucide icons.
 * SVG bodies are NOT included — they are loaded via generated chunks at runtime by lucideIconsPlugin
 * (packages/frontend/@n8n/design-system/src/icons/lucide/vite.ts).
 *
 * Usage: node scripts/generate-lucide-icon-data.mjs
 *
 * Output: packages/frontend/@n8n/design-system/src/components/N8nIconPicker/lucideIconData.ts
 */

import { readFileSync, writeFileSync, existsSync } from 'node:fs';
import { resolve, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = resolve(__dirname, '..');
const COMPONENTS_ROOT = resolve(
	ROOT,
	'packages/frontend/@n8n/design-system/src/components',
);

const LUCIDE_JSON_PATH = resolve(ROOT, 'node_modules/@iconify/json/json/lucide.json');
const OUTPUT_PATH = resolve(COMPONENTS_ROOT, 'N8nIconPicker/lucideIconData.ts');
const CACHE_PATH = resolve(ROOT, 'scripts/.lucide-tags-cache.json');

// Lucide GitHub raw URL for per-icon metadata
const LUCIDE_GITHUB_BASE =
	'https://raw.githubusercontent.com/lucide-icons/lucide/main/icons';

async function fetchIconMeta(iconName) {
	const url = `${LUCIDE_GITHUB_BASE}/${iconName}.json`;
	try {
		const res = await fetch(url);
		if (!res.ok) return { tags: [], categories: [] };
		const data = await res.json();
		return {
			tags: data.tags ?? [],
			categories: data.categories ?? [],
		};
	} catch {
		return { tags: [], categories: [] };
	}
}

async function main() {
	console.log('Reading @iconify/json lucide data...');
	const lucideJson = JSON.parse(readFileSync(LUCIDE_JSON_PATH, 'utf-8'));
	const icons = lucideJson.icons;
	const iconNames = Object.keys(icons).sort();
	console.log(`Found ${iconNames.length} Lucide icons`);

	// Load or initialize cache
	let cache = {};
	if (existsSync(CACHE_PATH)) {
		try {
			cache = JSON.parse(readFileSync(CACHE_PATH, 'utf-8'));
			console.log(`Loaded ${Object.keys(cache).length} cached icon metadata entries`);
		} catch {
			cache = {};
		}
	}

	// Fetch metadata for uncached icons
	const uncachedNames = iconNames.filter((name) => !cache[name]);
	if (uncachedNames.length > 0) {
		console.log(`Fetching metadata for ${uncachedNames.length} icons from Lucide GitHub...`);
		const BATCH_SIZE = 50;
		for (let i = 0; i < uncachedNames.length; i += BATCH_SIZE) {
			const batch = uncachedNames.slice(i, i + BATCH_SIZE);
			const results = await Promise.all(batch.map(fetchIconMeta));
			for (let j = 0; j < batch.length; j++) {
				cache[batch[j]] = results[j];
			}
			const progress = Math.min(i + BATCH_SIZE, uncachedNames.length);
			process.stdout.write(`\r  Fetched ${progress}/${uncachedNames.length}`);
		}
		console.log('\nSaving cache...');
		writeFileSync(CACHE_PATH, JSON.stringify(cache, null, 2));
	}

	// Build the output data
	const allCategories = new Set();
	const entries = [];

	for (const name of iconNames) {
		const meta = cache[name] ?? { tags: [], categories: [] };
		const body = icons[name]?.body;
		if (!body) continue;

		// Keywords: icon name parts + tags
		const nameParts = name.split('-').filter((p) => p.length > 0);
		const keywords = [...new Set([...nameParts, ...meta.tags])];
		const categories = meta.categories ?? [];
		categories.forEach((c) => allCategories.add(c));

		entries.push({ name, keywords, categories });
	}

	const sortedCategories = [...allCategories].sort();

	console.log(`Generating TypeScript file with ${entries.length} icons and ${sortedCategories.length} categories...`);

	// Generate TypeScript output — metadata only, no SVG bodies
	let output = `// AUTO-GENERATED by scripts/generate-lucide-icon-data.mjs — DO NOT EDIT
// Source: Lucide GitHub (tags/categories). SVG bodies are loaded via generated chunks at runtime.
// Icons: ${entries.length} | Categories: ${sortedCategories.length}

export interface LucideIconMeta {
\t/** Searchable keywords: icon name parts + Lucide tags */
\tkeywords: string[];
\t/** Lucide categories this icon belongs to */
\tcategories: string[];
}

export const lucideIcons: Record<string, LucideIconMeta> = {\n`;

	for (const entry of entries) {
		const kw = JSON.stringify(entry.keywords);
		const cats = JSON.stringify(entry.categories);
		output += `\t'${entry.name}': { keywords: ${kw}, categories: ${cats} },\n`;
	}

	output += `};\n\n`;

	output += `/** All unique Lucide icon categories, sorted alphabetically */\nexport const lucideCategories: string[] = ${JSON.stringify(sortedCategories, null, '\t')};\n`;

	writeFileSync(OUTPUT_PATH, output);

	const sizeKB = Math.round(Buffer.byteLength(output) / 1024);
	console.log(`\nDone! Written to: ${OUTPUT_PATH}`);
	console.log(`File size: ${sizeKB} KB`);
}

main().catch((err) => {
	console.error(err);
	process.exit(1);
});
