/**
 * Save-path serialization helpers (pure, testable).
 */

import { getVisibleSteps } from './steps';
import { normalizeStringList } from './string-list';

/**
 * Escape text for HTML text nodes.
 *
 * @param {string} value Raw.
 * @return {string} Escaped.
 */
export function escapeHtml(value) {
	return String(value || '')
		.replace(/&/g, '&amp;')
		.replace(/</g, '&lt;')
		.replace(/>/g, '&gt;')
		.replace(/"/g, '&quot;')
		.replace(/'/g, '&#039;');
}

/**
 * Strip scripts / event handlers from step HTML before save.
 * Server re-sanitizes with wp_kses on render.
 *
 * @param {string} html Raw HTML.
 * @return {string} Safer HTML.
 */
export function sanitizeStepHtml(html) {
	const value = String(html || '');
	return value
		.replace(/<script[\s\S]*?>[\s\S]*?<\/script>/gi, '')
		.replace(/\son\w+\s*=\s*(".*?"|'.*?'|[^\s>]+)/gi, '')
		.replace(/javascript:/gi, '');
}

/**
 * Build static/fallback-visible inner HTML for the HowTo block.
 *
 * @param {Object} attributes Block attributes.
 * @return {string} Inner HTML (without outer section wrapper).
 */
export function buildHowToInnerHtml(attributes = {}) {
	const {
		name = '',
		description = '',
		steps = [],
		supplies = [],
		tools = [],
		totalTime = '',
		estimatedCost = {},
	} = attributes;

	const visible = getVisibleSteps(steps);
	const supplyList = normalizeStringList(supplies);
	const toolList = normalizeStringList(tools);
	const cost =
		estimatedCost && typeof estimatedCost === 'object' ? estimatedCost : {};
	const currency = String(cost.currency || '').trim();
	const costValue = String(cost.value || '').trim();

	const nameHtml = name
		? `<h2 class="seovault-howto-block__name">${escapeHtml(name)}</h2>`
		: '';
	const descriptionHtml = description
		? `<p class="seovault-howto-block__description">${escapeHtml(description)}</p>`
		: '';

	let metaHtml = '';
	if (totalTime || (currency && costValue)) {
		const parts = [];
		if (totalTime) {
			parts.push(
				`<li class="seovault-howto-block__time">${escapeHtml(totalTime)}</li>`
			);
		}
		if (currency && costValue) {
			parts.push(
				`<li class="seovault-howto-block__cost">${escapeHtml(
					`${currency} ${costValue}`
				)}</li>`
			);
		}
		metaHtml = `<ul class="seovault-howto-block__meta">${parts.join('')}</ul>`;
	}

	const suppliesHtml = supplyList.length
		? `<div class="seovault-howto-block__supplies"><h3 class="seovault-howto-block__section-title">Supplies</h3><ul>${supplyList
				.map((item) => `<li>${escapeHtml(item)}</li>`)
				.join('')}</ul></div>`
		: '';

	const toolsHtml = toolList.length
		? `<div class="seovault-howto-block__tools"><h3 class="seovault-howto-block__section-title">Tools</h3><ul>${toolList
				.map((item) => `<li>${escapeHtml(item)}</li>`)
				.join('')}</ul></div>`
		: '';

	const stepsHtml = visible.length
		? `<ol class="seovault-howto-block__steps">${visible
				.map((step, index) => {
					const stepName = (step.name || '').trim();
					const stepText = sanitizeStepHtml(step.text || '');
					const idAttr = step.id
						? ` data-howto-step-id="${escapeHtml(step.id)}"`
						: '';
					const namePart = stepName
						? `<h3 class="seovault-howto-block__step-name">${escapeHtml(
								stepName
							)}</h3>`
						: '';
					const textPart = stepText
						? `<div class="seovault-howto-block__step-text">${stepText}</div>`
						: '';
					return `<li class="seovault-howto-block__step" data-step-index="${
						index + 1
					}"${idAttr}>${namePart}${textPart}</li>`;
				})
				.join('')}</ol>`
		: '';

	return `${nameHtml}${descriptionHtml}${metaHtml}${suppliesHtml}${toolsHtml}${stepsHtml}`;
}

/**
 * Class list for the saved/rendered wrapper.
 *
 * @param {Object} attributes Attributes.
 * @return {string[]} Classes.
 */
export function buildHowToClassList(attributes = {}) {
	const {
		displayMode = 'numbered',
		stylePreset = 'clean',
		colorPreset = 'blue',
		density = 'comfortable',
	} = attributes;

	return [
		'seovault-howto-block',
		`seovault-howto-block--display-${displayMode}`,
		`seovault-howto-block--style-${stylePreset}`,
		`seovault-howto-block--color-${colorPreset}`,
		`seovault-howto-block--density-${density}`,
	];
}
