/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
import { getParentComponentInfo } from "./jsx.js";
import { extractExplicitProps } from "./props.js";
import { SyntaxKind } from "ts-morph";
//#region ../css/dist/purger/optimized/ast/spread.mjs
/*! © 2026 Yahoo, Inc. UDS CSS v0.0.0-development */
/**
* Find all usages of a component across the entire project.
* This is the key function for spread resolution - when we encounter
* {...props} on a UDS component inside a wrapper, we trace back to
* find all places where the wrapper is used and extract actual values.
*
* @param componentName Name of the component to find usages of
* @param project The ts-morph project
* @param cache Optional cache to avoid re-scanning
* @returns Array of component usages with their props
*/
const findComponentUsages = (componentName, project, cache) => {
	if (cache?.has(componentName)) return cache.get(componentName);
	const usages = [];
	project.getSourceFiles().forEach((sourceFile) => {
		if (!fileReferencesComponent(sourceFile, componentName)) return;
		[...sourceFile.getDescendantsOfKind(SyntaxKind.JsxSelfClosingElement), ...sourceFile.getDescendantsOfKind(SyntaxKind.JsxOpeningElement)].filter((el) => el.getTagNameNode().getText() === componentName).forEach((element) => {
			const props = extractExplicitProps(element);
			usages.push({
				componentName,
				filePath: sourceFile.getFilePath(),
				line: element.getStartLineNumber(),
				props
			});
		});
	});
	if (cache) cache.set(componentName, usages);
	return usages;
};
/**
* Check if a source file references a component (by import or definition)
*/
const fileReferencesComponent = (sourceFile, componentName) => {
	if (sourceFile.getImportDeclarations().some((imp) => imp.getNamedImports().some((named) => named.getName() === componentName))) return true;
	if (sourceFile.getVariableDeclaration(componentName)) return true;
	if (sourceFile.getFunction(componentName)) return true;
	return false;
};
/**
* Resolve spread props by tracing component usage.
*
* When we encounter {...props} on a UDS component inside a wrapper:
* 1. Find the parent component that contains this spread
* 2. Search ALL files for usages of that parent component
* 3. Extract actual prop values passed at each usage site
* 4. Return ONLY those values - never fall back to type properties
*
* @param element The JSX element with the spread
* @param spreadIdentifier The identifier being spread (e.g., 'rest' from {...rest})
* @param context The purge context for caching
* @returns Map of prop names to their resolved values, or undefined if couldn't trace
*/
const resolveSpreadFromUsages = (element, spreadIdentifier, context) => {
	const parentInfo = getParentComponentInfo(element);
	if (!parentInfo) return;
	if (!(parentInfo.spreadRestIdentifier === spreadIdentifier || parentInfo.paramIdentifier === spreadIdentifier)) return;
	const usages = findComponentUsages(parentInfo.componentName, context.project, context.componentUsageCache);
	if (usages.length === 0) return;
	context.stats.spreadsTraced++;
	const resolvedProps = /* @__PURE__ */ new Map();
	usages.forEach((usage) => {
		usage.props.forEach((prop) => {
			if (prop.fromSpread) return;
			const existing = resolvedProps.get(prop.name) ?? [];
			prop.values.forEach((value) => {
				if (!existing.includes(value)) existing.push(value);
			});
			resolvedProps.set(prop.name, existing);
		});
	});
	const cacheKey = `${element.getSourceFile().getFilePath()}:${element.getStartLineNumber()}:${spreadIdentifier}`;
	context.spreadCache.set(cacheKey, Array.from(resolvedProps).map(([name, values]) => ({
		name,
		values,
		fromSpread: true
	})));
	return resolvedProps;
};
//#endregion
export { resolveSpreadFromUsages };
