<?php
/**
 * Import / VB load: convert leftover Supreme D4 shortcodes to native `dsm/*` blocks.
 *
 * Divi may leave `[dsm_*]` inside `divi/shortcode-module` after library import when conversion
 * maps were not ready, or when wpautop wrapped the shortcode in `<p>…</p>` so Divi's converter
 * never treats it as convertible. In the Visual Builder those fallbacks crash
 * (`moduleDefinition.asMutable is not a function`) because D4 shortcode defs are not loaded as
 * Immutable objects for Supreme modules. Frontend then prints raw shortcode text.
 *
 * Convert on import + raw VB load (before the shortcode-module UI runs). VB save still has
 * {@see PersistShortcodeModuleConversionOnSave} as a second line of defense.
 *
 * @package DiviSupreme
 */

declare(strict_types=1);

namespace DiviSupreme\Includes\Divi5Conversion;

/**
 * Portability / VB-load conversion for all Supreme `dsm_*` shortcodes.
 */
final class SupremeShortcodeImportMigrator {

	/**
	 * Prevent re-entrancy when conversion re-applies portability filters.
	 *
	 * @var bool
	 */
	private static bool $busy = false;

	/**
	 * @return void
	 */
	public static function register(): void {
		// Before module-specific migrators (typing normalize, filterable gallery, flipbox).
		add_filter(
			'divi_framework_portability_import_migrated_post_content',
			array( self::class, 'migrate_import_content' ),
			15,
			2
		);

		add_filter(
			'et_fb_load_raw_post_content',
			array( self::class, 'migrate_import_content' ),
			15,
			2
		);
	}

	/**
	 * Convert unmigrated Supreme shortcodes / shortcode-modules to native blocks.
	 *
	 * @param string   $content Post content.
	 * @param int|null $post_id Optional post ID.
	 * @return string
	 */
	public static function migrate_import_content( $content, $post_id = null ) {
		if ( self::$busy || ! is_string( $content ) || '' === $content ) {
			return $content;
		}

		if ( ! self::content_needs_supreme_shortcode_conversion( $content ) ) {
			return $content;
		}

		self::$busy = true;

		try {
			$result = LegacyShortcodeConversionService::convert_content(
				$content,
				is_numeric( $post_id ) ? (int) $post_id : null
			);

			if ( $result->changed && is_string( $result->content ) && '' !== $result->content ) {
				$content = $result->content;
			}
		} finally {
			self::$busy = false;
		}

		return $content;
	}

	/**
	 * Whether content still has raw Supreme shortcodes or shortcode-module wrappers.
	 *
	 * @param string $content Post content.
	 * @return bool
	 */
	private static function content_needs_supreme_shortcode_conversion( string $content ): bool {
		if ( preg_match( '/\[dsm_[a-z0-9_]+/i', $content ) ) {
			return true;
		}

		return str_contains( $content, 'divi/shortcode-module' )
			&& str_contains( $content, 'dsm_' );
	}
}
