'use strict';
const css = require('css');
const {remToPx, isUtilitySupported} = require('./util');

const modifyRule = (rule, selector) => {
	rule.declarations.forEach(declaration => {
		const rawValue = declaration.value;
		const property = declaration.property;

		if (property === 'line-height' && !rawValue.endsWith('rem')) {
			return;
		}

		if (rawValue.endsWith('rem') || rawValue.endsWith('em')) {
			declaration.value = remToPx(rawValue);
		}

		// hycss can not compile flex: 1 1 0%;
		if (selector === 'flex-1' && property === 'flex') {
			declaration.value = 1;
		}
	});
};

module.exports = source => {
	const ast = css.parse(source);

	let supportRules = [];

	// Collect Hyext support rules
	for (const rule of ast.stylesheet.rules) {
		if (rule.type === 'rule') {
			for (const selector of rule.selectors) {
				const utility = selector.replace(/^\./, '').replace('\\/', '/');
				if (isUtilitySupported(utility, rule)) {
					modifyRule(rule, selector);
					supportRules.push(rule);
				}
			}
		}
	}

	// Compile --tw vars
	const applyVarRE = /var\(([a-zA-Z-]+)\)/;
	const varDeclarations = new Map();

	supportRules.forEach((rule, index) => {
		if (rule.type === 'rule') {
			for (const declaration of rule.declarations) {
				if (declaration.property.startsWith('--tw')) {
					if (rule.declarations.length === 1) {
						supportRules[index] = null // it will be removed, on next step
					} else {
						varDeclarations.set(declaration.property, declaration.value);
					}
				}
			}

			for (const declaration of rule.declarations) {
				const match = declaration.value.match(applyVarRE);
				if (match !== null) {
					const varName = match[1];
					const varValue = varDeclarations.get(varName);
					if (varValue !== void 0) {
						declaration.value = declaration.value.replace(applyVarRE, varValue);
						const varDecItemIndex = rule.declarations.findIndex(
							item => item.property === varName
						);
						if (varDecItemIndex > -1)
							rule.declarations.splice(varDecItemIndex, 1);
					}
				}
			}
		}
	});

	supportRules = supportRules.filter((v) => v !== null)
	ast.stylesheet.rules = supportRules;

	return css.stringify(ast);
};
