/**
 * Internal dependencies.
 */
import { getDynamicContent } from '@spectra-pro-extensions/dynamic-content/utils/helpers';

/**
 * Parses and processes dynamic content within the given string.
 *
 * @since x.x.x
 *
 * @param {string} content - The content to process
 * @param {Object} context - The context object
 * @return {Promise<string>} Processed content with dynamic values
 */
const parseDynamicContent = async ( content, context ) => {
	// Return unchanged content if it's empty or lacks dynamic content markers.
	if ( ! content || ! content.includes( 'spectra-pro-dc-content' ) ) return content;

	// Parse the content string into a DOM structure for manipulation.
	const doc = new DOMParser().parseFromString( content, 'text/html' );

	// Select all dynamic content elements with the specified class and data attribute.
	const dynamicElements = Array.from( doc.body.querySelectorAll( 'span.spectra-pro-dc-content[data-spectra-dc]' ) );

	// Return unchanged content if no dynamic elements are found.
	if ( dynamicElements.length === 0 ) return content;

	// Process all dynamic elements in parallel to fetch their dynamic content.
	const updates = await Promise.all(
		dynamicElements.map( async ( element ) => {
			// Retrieve the JSON string from the data attribute.
			const jsonString = element.getAttribute( 'data-spectra-dc' );

			// Store the original content as a fallback.
			const originalContent = element.innerHTML;

			// Return original content if no JSON data is present.
			if ( ! jsonString ) return { element, dynamicContent: originalContent };

			// Parse the JSON string into settings.
			const settings = JSON.parse( jsonString );

			try {
				// Validate that the settings contain required source type and field.
				if ( ! settings?.source?.type || ! settings?.source?.field ) {
					return { element, dynamicContent: originalContent };
				}

				// Initialize settings with post ID for current post context.
				const enhancedSettings = {
					...settings,
					source: {
						...settings.source,
						...( settings?.source?.type === 'current_post' &&
							context?.postType &&
							context?.postId && {
								postId: context.postId,
								postType: context.postType,
							} ),
					},
				};

				// Fetch the dynamic content using the enhanced settings.
				const dynamicContent = await getDynamicContent( enhancedSettings );

				return { element, dynamicContent };
			} catch ( error ) {
				// Return original content in case of errors.
				return { element, dynamicContent: originalContent };
			}
		} )
	);

	// Apply the fetched dynamic content to the corresponding DOM elements.
	updates.forEach( ( update ) => {
		if ( update && update.element.innerHTML !== update.dynamicContent ) {
			update.element.innerHTML = update.dynamicContent;
		}
	} );

	// Return the updated HTML content of the document body.
	return doc.body.innerHTML;
};

export default parseDynamicContent;
