import { makeDecorator } from '@storybook/addons';
import { escapeHTML } from '../../utils/DomUtils';

// Sets tab-indentation so that the last line is not indented, while lines before that keep their indentation level relative to the last line.
const normalizeIndentation = src => {
	const tabGroups = /\t+/g;
	const allTabGroups = src.trim().match(tabGroups);
	const maxIndentation = allTabGroups?.slice(-1)?.[0]?.length || 0;
	const tabsAtStartOfLine = new RegExp(`^\t{${maxIndentation}}`, 'gm');

	return src.trim().replace(tabsAtStartOfLine, '');
};

const getVariationTemplate = (title, src, inverted) => {
	if (!src || src === '') return '';

	return `<h2 class="${inverted ? 'white' : ''}">${title}</h2>${src}<code class="${`sb-syntax ${
		inverted ? 'is-inverted' : ''
	}`}">${escapeHTML(normalizeIndentation(src))}</code>`;
};

// Custom decorator for adding variations to a story
// variations are defined in the story parameters in the format { title: String, src: String }
export default makeDecorator({
	name: 'withVariations',
	parameterName: 'variations',
	skipIfNoParametersOrOptions: true,
	wrapper: (getStory, ctx, { parameters }) => {
		const inverted = ctx.parameters.backgrounds.default === 'dark';

		return parameters.reduce(
			(acc, { title, src }, i) => (acc += getVariationTemplate(title, src, inverted)),
			getVariationTemplate(ctx.parameters.defaultVariationTitle || 'Default', getStory(ctx), inverted)
		);
	}
});
