/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
import { cyan, magenta, yellow } from "../packages/cli/dist/lib/colors.js";
import { print } from "../packages/cli/dist/lib/print.js";
import { measureAsync } from "./perf.js";
import { resolveEntryPaths } from "../../../tailwind-internal/dist/utils/entryPoints.js";
import { loadConfigFile, scanDirectoriesForSafelist } from "./nodeUtils.js";
import { spinStop } from "../packages/cli/dist/lib/spinner.js";
import { defaultTokensConfig } from "../packages/config/dist/index.js";
import { deduplicateSafelist, getInternalSafelistClasses, getThemeAndScaleClasses } from "../purger/optimized/utils/safelist.js";
import { extractRuntimeConfigValues, extractVariantDefaults, getConfigurableCssVariables, getMotionVarPrefixes } from "./utils.js";
import { applyScopedColorModeFix, buildPostcssPlugins, createTailwindPlugin, getCssFeatureFlags, getInternalIconModeCss, optimizeGeneratedCss, printSimpleModeStats } from "./generate.helpers.js";
import path from "node:path";
import fs from "node:fs";
import { gzipSync } from "node:zlib";
import postcss from "postcss";
//#region ../css/dist/css/generate.mjs
/*! © 2026 Yahoo, Inc. UDS CSS v0.0.0-development */
const normalizeScope = (scope) => {
	const trimmedScope = scope?.trim();
	return trimmedScope ? trimmedScope : void 0;
};
const getArbitrarySafelistRawContent = (safelist) => {
	const arbitraryClasses = safelist.filter((entry) => typeof entry === "string" && entry.includes("["));
	if (arbitraryClasses.length === 0) return [];
	return [`<div class="${arbitraryClasses.join(" ")}"></div>`];
};
/**
* Generate CSS from a safelist using Tailwind + PostCSS
* @param safelist - UDS component classes to include
* @param config - Token configuration
* @param options - Additional options
*/
const generateCSS = async (safelist, config, options) => {
	const sourceCSS = "@tailwind base; @tailwind components; @tailwind utilities";
	const contentDir = options?.contentDir ?? path.join(process.cwd(), "src");
	const cssFlags = getCssFeatureFlags(options?.cssOptions);
	const optimizationConfig = options?.cssOptions?.optimization;
	const scopeClass = normalizeScope(options?.scope) ?? normalizeScope(options?.cssOptions?.scope);
	const plugins = buildPostcssPlugins({
		tailwindPlugin: await createTailwindPlugin({
			contentDir,
			rawContents: getArbitrarySafelistRawContent(safelist),
			safelist,
			config,
			enablePreflight: cssFlags.enablePreflight,
			enableFontFaceDeclarations: cssFlags.enableFontFaceDeclarations
		}),
		shouldPruneVars: cssFlags.shouldPruneVars,
		safeVarPrefixes: options?.safeVarPrefixes ?? [],
		scopeClass
	});
	const result = await measureAsync("gen:postcss", () => postcss(plugins).process(sourceCSS, { from: void 0 }));
	let css = await measureAsync("gen:scoped-color-fix", () => applyScopedColorModeFix(result.css, scopeClass));
	if (!css.includes("uds-light-mode-icon") || !css.includes("uds-dark-mode-icon")) css = `${css} ${getInternalIconModeCss(scopeClass)}`.trim();
	const optimizedCss = await measureAsync("gen:optimize", () => optimizeGeneratedCss({
		css,
		shouldOptimize: cssFlags.shouldOptimize,
		optimizationConfig,
		referenceCss: options?.referenceCss,
		scopeClass
	}));
	css = optimizedCss.css;
	const sizeBytes = Buffer.byteLength(css, "utf8");
	const sizeGzipBytes = gzipSync(css).length;
	return {
		css,
		sizeBytes,
		sizeGzipBytes,
		classCount: safelist.length,
		optimizationStats: optimizedCss.optimizationStats
	};
};
/**
* Generate CSS in simple mode (no uds.theme.ts)
*/
const generateSimpleModeCSS = async (options) => {
	const isWatch = options.isWatch === true;
	const shouldLogStats = !(options.silent === true) && !isWatch;
	const startTime = performance.now();
	const colorModes = ["dark"];
	let tokensConfig = defaultTokensConfig;
	if (options.configPath) {
		const loadedConfig = await loadConfigFile(options.configPath);
		if (loadedConfig) tokensConfig = loadedConfig;
		else if (shouldLogStats) spinStop("⚠️", `Config file not found: ${options.configPath}, using defaults`);
	}
	const variantDefaults = extractVariantDefaults(tokensConfig);
	const runtimeConfigValues = extractRuntimeConfigValues(tokensConfig);
	const resolvedEntries = resolveEntryPaths(options.entry, options.workspaceDir);
	const entryDirs = resolvedEntries.map((entry) => entry.absolutePath);
	const scanResult = await scanDirectoriesForSafelist(entryDirs, colorModes, options.variants, options.autoVariants, options.componentData, variantDefaults, runtimeConfigValues);
	const totalFilesScanned = scanResult.filesScanned;
	const allClasses = [...scanResult.safelist];
	const allComponents = new Set(scanResult.components);
	const packageDirs = [...new Set(resolvedEntries.map((entry) => entry.kind === "directory" ? entry.absolutePath : entry.watchDirectory))];
	const cssResult = await generateCSS(deduplicateSafelist([
		...allClasses,
		...getThemeAndScaleClasses(colorModes),
		...getInternalSafelistClasses()
	]), tokensConfig, {
		scope: options.scope,
		contentDir: entryDirs,
		safeVarPrefixes: [...getMotionVarPrefixes(options.componentData, [...allComponents]), ...getConfigurableCssVariables()]
	});
	const outputPath = path.isAbsolute(options.outFile) ? options.outFile : path.join(options.workspaceDir, options.outFile);
	const outputDir = path.dirname(outputPath);
	if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir, { recursive: true });
	fs.writeFileSync(outputPath, cssResult.css);
	const duration = Math.round(performance.now() - startTime);
	if (shouldLogStats) printSimpleModeStats({
		cwd: options.workspaceDir,
		outputPath,
		totalFilesScanned,
		scannedFilePaths: scanResult.filePaths,
		classCount: cssResult.classCount,
		sizeBytes: cssResult.sizeBytes,
		sizeGzipBytes: cssResult.sizeGzipBytes,
		duration,
		scope: options.scope,
		verbose: options.verbose,
		optimizationStats: cssResult.optimizationStats,
		print,
		magenta,
		cyan,
		yellow
	});
	return {
		success: true,
		outputPath,
		packageDirs
	};
};
//#endregion
export { generateCSS, generateSimpleModeCSS };
