/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
import { getIconStyles } from "../../../tailwind-internal/dist/components/getIconStyles.js";
import { tailwindPlugin } from "../../../tailwind-internal/dist/tailwindPlugin.js";
import { hasAllowedEntryFileExtension } from "../../../tailwind-internal/dist/utils/entryPoints.js";
import { preserveVars, preserveVarsCleanup } from "../../../tailwind-internal/dist/utils/postcssPreserveVars.js";
import { getInternalSafelistClasses } from "../purger/optimized/utils/safelist.js";
import { formatCssDuration } from "./runner.helpers.js";
import { formatBytes } from "./utils.js";
import { iconPruneVarsSafelist } from "../packages/icons/src/safelist.js";
import { optimizeCSS } from "../utils/optimizeCSS.js";
import { fixScopedColorModeSelectorsPlugin, fixScopedSelfOrParentSelectorsPlugin } from "./postcss.js";
import path from "node:path";
import { fileURLToPath } from "node:url";
import fs from "node:fs";
import postcss from "postcss";
import autoprefixer from "autoprefixer";
import pruneVar from "postcss-prune-var";
import postcssScope from "postcss-scope";
//#region ../css/dist/css/generate.helpers.mjs
/*! © 2026 Yahoo, Inc. UDS CSS v0.0.0-development */
const getPruneVarSafelist = (cssOptions) => {
	const pruneVars = cssOptions?.optimization?.pruneVars;
	const configuredSafelist = pruneVars && typeof pruneVars === "object" ? pruneVars.safelist ?? [] : [];
	return [...iconPruneVarsSafelist, ...configuredSafelist];
};
const getCssFeatureFlags = (cssOptions) => {
	const optimizationConfig = cssOptions?.optimization;
	const shouldOptimize = optimizationConfig?.enabled !== false;
	const pruneVars = optimizationConfig?.pruneVars;
	return {
		enablePreflight: cssOptions?.preflight !== false,
		enableFontFaceDeclarations: cssOptions?.fontFaceDeclarations !== false,
		shouldOptimize,
		shouldPruneVars: shouldOptimize && pruneVars !== false
	};
};
const getContentGlobs = (contentDir) => {
	return (Array.isArray(contentDir) ? contentDir : [contentDir]).map((dir) => hasAllowedEntryFileExtension(dir) ? dir : path.join(dir, "**/*.{js,jsx,mjs,cjs,ts,tsx}"));
};
const getRawContentEntries = (rawContents) => rawContents.map((rawContent) => ({
	raw: rawContent,
	extension: "html"
}));
const getTailwindEntrypointCandidates = () => [new URL("../../../tailwind-internal/dist/vendor/tailwindcss/lib/index.js", import.meta.url), new URL("../vendor/tailwindcss/lib/index.js", import.meta.url)];
const loadTailwindcss = async () => {
	for (const candidate of getTailwindEntrypointCandidates()) {
		if (!fs.existsSync(fileURLToPath(candidate))) continue;
		const module = await import(candidate.href);
		return module.default ?? module;
	}
	throw new Error("Unable to locate a Tailwind CSS runtime for UDS CSS generation.");
};
const getInternalSafelistRawContent = (safelist) => {
	const internalClasses = new Set(getInternalSafelistClasses());
	const matchedInternalClasses = safelist.filter((entry) => typeof entry === "string" && internalClasses.has(entry));
	if (matchedInternalClasses.length === 0) return [];
	return [`<div class="${matchedInternalClasses.join(" ")}"></div>`];
};
const getInternalIconModeCss = (scopeClass) => {
	const iconStyles = getIconStyles();
	return Object.entries(iconStyles).map(([selector, declarations]) => {
		return `${scopeClass ? `${scopeClass} ${selector}` : selector} { ${Object.entries(declarations).map(([property, value]) => `${property}: ${value};`).join(" ")} }`;
	}).join(" ");
};
const createTailwindPlugin = async (options) => {
	return (await loadTailwindcss())({
		content: [
			...getContentGlobs(options.contentDir),
			...getRawContentEntries(getInternalSafelistRawContent(options.safelist)),
			...getRawContentEntries(options.rawContents ?? [])
		],
		safelist: options.safelist,
		corePlugins: { preflight: options.enablePreflight },
		plugins: [tailwindPlugin({
			config: options.config,
			disableFontFaceDeclarations: !options.enableFontFaceDeclarations,
			ignorePluginSafelists: true
		})]
	});
};
const getPruneVarPlugins = (safeVarPrefixes) => {
	if (safeVarPrefixes.length === 0) return [pruneVar()];
	return [
		preserveVars({ preserve: safeVarPrefixes }),
		pruneVar(),
		preserveVarsCleanup()
	];
};
const buildPostcssPlugins = (options) => {
	const plugins = [options.tailwindPlugin, autoprefixer()];
	if (options.shouldPruneVars) plugins.push(...getPruneVarPlugins(options.safeVarPrefixes));
	if (options.scopeClass) plugins.push(postcssScope(options.scopeClass));
	return plugins;
};
const applyScopedColorModeFix = async (css, scopeClass) => {
	if (!scopeClass) return css;
	return (await postcss([fixScopedSelfOrParentSelectorsPlugin(scopeClass), fixScopedColorModeSelectorsPlugin(scopeClass)]).process(css, { from: void 0 })).css;
};
const optimizeGeneratedCss = async (options) => {
	if (!options.shouldOptimize) return { css: options.css };
	const optimizationOptions = {
		removeUnusedFonts: options.optimizationConfig?.removeUnusedFonts,
		removeEmptyRules: options.optimizationConfig?.removeEmptyRules,
		aggregateDuplicateSelectors: options.optimizationConfig?.aggregateDuplicateSelectors,
		referenceCss: options.referenceCss,
		scopeClass: options.scopeClass
	};
	const optimized = await optimizeCSS(options.css, optimizationOptions);
	return {
		css: optimized.css,
		optimizationStats: {
			originalSize: optimized.stats.originalSize,
			originalSizeGzip: optimized.stats.originalSizeGzip,
			fontFacesRemoved: optimized.stats.fontFacesRemoved,
			emptyRulesRemoved: optimized.stats.emptyRulesRemoved,
			validationErrors: optimized.validation.errors
		}
	};
};
const printSimpleModeStats = (options) => {
	const { print, magenta, cyan, yellow } = options;
	const getDisplayPath = (targetPath) => {
		const relativePath = path.relative(options.cwd, targetPath);
		return relativePath.length === 0 ? "." : relativePath;
	};
	print("");
	print(`${magenta("Output:")} ${cyan(getDisplayPath(options.outputPath))}`);
	print(`${magenta("Stats:")}`);
	print(`   Files scanned: ${options.totalFilesScanned}`);
	if (options.verbose && options.scannedFilePaths && options.scannedFilePaths.length > 0) [...new Set(options.scannedFilePaths)].sort((left, right) => left.localeCompare(right)).forEach((filePath) => print(`      • ${cyan(getDisplayPath(filePath))}`));
	print(`   Classes: ${options.classCount}`);
	print(`   Size: ${formatBytes(options.sizeBytes)} (${formatBytes(options.sizeGzipBytes)} gzipped)`);
	const optimizationStats = options.optimizationStats;
	if (optimizationStats) {
		if (optimizationStats.originalSizeGzip - options.sizeGzipBytes > 0) {
			if (optimizationStats.fontFacesRemoved > 0) print(`      • removed ${optimizationStats.fontFacesRemoved} unused @font-face`);
			if (optimizationStats.emptyRulesRemoved > 0) print(`      • removed ${optimizationStats.emptyRulesRemoved} empty rules`);
		}
		if (optimizationStats.validationErrors.length > 0) {
			print(`   ${yellow("Validation warnings:")}`);
			optimizationStats.validationErrors.forEach((error) => print(`      ${yellow("•")} ${error}`));
		}
	}
	print(`   Time: ${formatCssDuration(options.duration)}`);
	if (options.scope) print(`   Scope: ${cyan(options.scope)}`);
};
//#endregion
export { applyScopedColorModeFix, buildPostcssPlugins, createTailwindPlugin, getCssFeatureFlags, getInternalIconModeCss, getPruneVarSafelist, optimizeGeneratedCss, printSimpleModeStats };
