<?php
/**
 * Utility Functions
 *
 * @package Vareon_Calculator_Suite_Lite
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

if ( ! function_exists( 'vareoncalc_get_option' ) ) {
	/**
	 * Get plugin option value.
	 *
	 * @param string $key           Option key.
	 * @param mixed  $default_value Default value.
	 * @return mixed Option value.
	 */
	function vareoncalc_get_option( $key, $default_value = null ) {
		$opts = get_option( 'vareoncalc_lite_options', array() );
		return $opts[ $key ] ?? $default_value;
	}
}

if ( ! function_exists( 'vareoncalc_get_branding_enabled_default' ) ) {
	/**
	 * Get default branding enabled state.
	 *
	 * @return bool Default branding state.
	 */
	function vareoncalc_get_branding_enabled_default() {
		return false;
	}
}

if ( ! function_exists( 'vareoncalc_get_asset_version' ) ) {
	/**
	 * Get a cache-busting asset version for frontend JS modules.
	 *
	 * Uses the newest modified time across core JS assets so calculator changes
	 * refresh reliably without manual version bumps.
	 *
	 * @return string Asset version.
	 */
	function vareoncalc_get_asset_version() {
		if ( ! defined( 'VAREONCALC_DIR' ) ) {
			return defined( 'VAREONCALC_VER' ) ? VAREONCALC_VER : '1';
		}

		$paths          = array();
		$asset_patterns = array(
			'js/*.js',
			'js/utils/*.js',
			'js/calculators/*.js',
			'assets/*.css',
			'assets/js/*.js',
			'assets/calculators/*.css',
			'assets/calculators.css',
			'blocks/vareoncalc/edit.js',
			'blocks/vareoncalc/block.json',
		);

		foreach ( $asset_patterns as $pattern ) {
			$glob_paths = glob( VAREONCALC_DIR . $pattern );
			if ( false !== $glob_paths ) {
				$paths = array_merge( $paths, $glob_paths );
			}
		}
		$paths = array_unique( $paths );

		$latest_mtime = 0;
		foreach ( $paths as $path ) {
			if ( ! file_exists( $path ) ) {
				continue;
			}
			$mtime = filemtime( $path );
			if ( $mtime && $mtime > $latest_mtime ) {
				$latest_mtime = $mtime;
			}
		}

		if ( $latest_mtime > 0 ) {
			return (string) $latest_mtime;
		}

		return defined( 'VAREONCALC_VER' ) ? VAREONCALC_VER : '1';
	}
}

if ( ! function_exists( 'vareoncalc_get_dev_nonce' ) ) {
	/**
	 * Get a per-request dev nonce for cache busting.
	 *
	 * @return string Dev nonce or empty string.
	 */
	function vareoncalc_get_dev_nonce() {
		static $nonce = null;
		if ( null !== $nonce ) {
			return $nonce;
		}

		$nonce = '';

		$is_debug_mode = ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG );
		$is_local_env  = function_exists( 'wp_get_environment_type' ) && in_array( wp_get_environment_type(), array( 'local', 'development' ), true );

		if ( $is_debug_mode || $is_local_env ) {
			$nonce = function_exists( 'wp_generate_uuid4' ) ? wp_generate_uuid4() : (string) time();
		}
		return $nonce;
	}
}

if ( ! function_exists( 'vareoncalc_should_use_minified_assets' ) ) {
	/**
	 * Determine whether runtime assets should use committed minified files.
	 *
	 * Source assets stay available behind SCRIPT_DEBUG for local debugging.
	 *
	 * @return bool
	 */
	function vareoncalc_should_use_minified_assets() {
		return ! ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG );
	}
}

if ( ! function_exists( 'vareoncalc_get_resolved_asset' ) ) {
	/**
	 * Resolve a plugin asset to its production or debug variant.
	 *
	 * @param string $relative_path Plugin-relative asset path.
	 * @return array<string,string>
	 */
	function vareoncalc_get_resolved_asset( $relative_path ) {
		$relative_path = ltrim( (string) $relative_path, '/\\' );
		$version       = defined( 'VAREONCALC_VER' ) ? VAREONCALC_VER : '1';
		$resolved_path = defined( 'VAREONCALC_DIR' ) ? VAREONCALC_DIR . $relative_path : $relative_path;
		$resolved_url  = defined( 'VAREONCALC_URL' ) ? VAREONCALC_URL . $relative_path : $relative_path;
		$resolved_rel  = $relative_path;

		$candidates = array( $relative_path );
		if (
			vareoncalc_should_use_minified_assets()
			&& preg_match( '/\.(js|css)$/i', $relative_path )
			&& ! preg_match( '/\.min\.(js|css)$/i', $relative_path )
		) {
			$minified_rel = preg_replace( '/\.(js|css)$/i', '.min.$1', $relative_path );
			if ( is_string( $minified_rel ) && '' !== $minified_rel ) {
				array_unshift( $candidates, $minified_rel );
			}
		}

		if ( defined( 'VAREONCALC_DIR' ) ) {
			foreach ( array_unique( $candidates ) as $candidate_rel ) {
				$candidate_path = VAREONCALC_DIR . $candidate_rel;
				if ( file_exists( $candidate_path ) ) {
					$resolved_rel  = $candidate_rel;
					$resolved_path = $candidate_path;
					$resolved_url  = VAREONCALC_URL . $candidate_rel;
					$mtime         = filemtime( $candidate_path );
					if ( $mtime ) {
						$version = (string) $mtime;
					}
					break;
				}
			}
		}

		return array(
			'relative_path' => $resolved_rel,
			'path'          => $resolved_path,
			'url'           => $resolved_url,
			'version'       => $version,
		);
	}
}

if ( ! function_exists( 'vareoncalc_get_importmap_loader_handles' ) ) {
	/**
	 * Get loader handles that require the calculator-base import map.
	 *
	 * @return string[]
	 */
	function vareoncalc_get_importmap_loader_handles() {
		return array(
			'vareoncalc-loader',
			'vareoncalc-loader-preview',
			'vareoncalc-lite-preview-frame-loader',
		);
	}
}

if ( ! function_exists( 'vareoncalc_has_enqueued_importmap_loader' ) ) {
	/**
	 * Check whether a loader that depends on the import map is enqueued.
	 *
	 * @return bool
	 */
	function vareoncalc_has_enqueued_importmap_loader() {
		foreach ( vareoncalc_get_importmap_loader_handles() as $handle ) {
			if ( wp_script_is( $handle, 'enqueued' ) ) {
				return true;
			}
		}

		return false;
	}
}

if ( ! function_exists( 'vareoncalc_get_importmap_data' ) ) {
	/**
	 * Build import map data for cache-busted shared modules.
	 *
	 * @return array Import map payload.
	 */
	function vareoncalc_get_importmap_data() {
		$asset_version = function_exists( 'vareoncalc_get_asset_version' ) ? vareoncalc_get_asset_version() : ( defined( 'VAREONCALC_VER' ) ? VAREONCALC_VER : '1' );
		$dev_nonce     = vareoncalc_get_dev_nonce();
		$base_asset    = vareoncalc_get_resolved_asset( 'js/calculator-base.js' );

		$query_args = array();
		if ( ! empty( $asset_version ) ) {
			$query_args['v'] = $asset_version;
		}
		if ( ! empty( $dev_nonce ) ) {
			$query_args['dev'] = $dev_nonce;
		}
		$query     = $query_args ? '?' . http_build_query( $query_args, '', '&', PHP_QUERY_RFC3986 ) : '';
		$module_id = '@vareoncalc/calculator-base';
		$base_url  = $base_asset['url'] . $query;

		return array(
			'imports' => array(
				$module_id => $base_url,
			),
		);
	}
}

if ( ! function_exists( 'vareoncalc_enqueue_importmap_bridge' ) ) {
	/**
	 * Enqueue a script-modules bridge to inject import map entries.
	 *
	 * @return void
	 */
	function vareoncalc_enqueue_importmap_bridge() {
		if ( ! function_exists( 'wp_register_script_module' ) || ! function_exists( 'wp_enqueue_script_module' ) ) {
			return;
		}
		if ( ! vareoncalc_has_enqueued_importmap_loader() ) {
			return;
		}

		$importmap      = vareoncalc_get_importmap_data();
		$imports        = isset( $importmap['imports'] ) && is_array( $importmap['imports'] ) ? $importmap['imports'] : array();
		$base_module_id = '@vareoncalc/calculator-base';
		$base_url       = $imports[ $base_module_id ] ?? '';
		if ( empty( $base_url ) ) {
			return;
		}

		$module_ids = array( $base_module_id );
		foreach ( $module_ids as $module_id ) {
			wp_register_script_module( $module_id, $base_url, array(), null, array( 'in_footer' => true ) );
		}

		$bridge_asset = vareoncalc_get_resolved_asset( 'js/importmap-bridge.js' );
		$bridge_id    = 'vareoncalc-importmap-bridge';
		$bridge_src   = $bridge_asset['url'];
		$bridge_ver   = $bridge_asset['version'];

		wp_register_script_module( $bridge_id, $bridge_src, $module_ids, $bridge_ver, array( 'in_footer' => true ) );
		wp_enqueue_script_module( $bridge_id );
	}
}

if ( ! function_exists( 'vareoncalc_print_inline_importmap' ) ) {
	/**
	 * Print a fallback inline import map for calculator modules.
	 *
	 * @param bool $require_loader Whether an eligible loader must be enqueued first.
	 * @return void
	 */
	function vareoncalc_print_inline_importmap( $require_loader = true ) {
		if ( ! function_exists( 'wp_get_inline_script_tag' ) ) {
			return;
		}
		if ( $require_loader && ! vareoncalc_has_enqueued_importmap_loader() ) {
			return;
		}

		$importmap = vareoncalc_get_importmap_data();
		if ( empty( $importmap['imports'] ) ) {
			return;
		}

		$json = wp_json_encode( $importmap, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES );
		if ( ! $json ) {
			return;
		}

		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Script tag is generated by core and contains JSON for importmap.
		echo wp_get_inline_script_tag( $json, array( 'type' => 'importmap' ) );
	}
}

if ( ! function_exists( 'vareoncalc_print_importmap' ) ) {
	/**
	 * Print import map for calculator modules when loader is enqueued.
	 *
	 * @return void
	 */
	function vareoncalc_print_importmap() {
		if ( function_exists( 'wp_register_script_module' ) && function_exists( 'wp_enqueue_script_module' ) ) {
			return;
		}

		vareoncalc_print_inline_importmap( true );
	}
}

if ( ! function_exists( 'vareoncalc_render_dashicon' ) ) {
	/**
	 * Get emoji to dashicon mapping
	 *
	 * @return array Emoji => Dashicon slug map.
	 */
	function vareoncalc_get_dashicon_emoji_map() {
		static $map = null;

		if ( null === $map ) {
			$map = array(
				'⚙️'  => 'admin-generic',
				'📖'   => 'book-alt',
				'🧮'   => 'calculator',
				'📊'   => 'chart-bar',
				'🚀'   => 'star-filled',
				'🎨'   => 'admin-appearance',
				'🔘'   => 'admin-generic',
				'✏️'  => 'edit',
				'📝'   => 'media-text',
				'✅'   => 'yes-alt',
				'⚠️'  => 'warning',
				'💡'   => 'lightbulb',
				'📤'   => 'download',
				'📥'   => 'upload',
				'💾'   => 'saved',
				'⭐'   => 'star-filled',
				'✨'   => 'star-filled',
				'🎯'   => 'admin-generic',
				'📚'   => 'book-alt',
				'🗑️'  => 'trash',
				'✓'   => 'yes-alt',
				'🧾'   => 'media-text',
				'📈'   => 'chart-area',
				'📉'   => 'chart-bar',
				'💰'   => 'money-alt',
				'💵'   => 'money-alt',
				'🏠'   => 'admin-home',
				'💳'   => 'cart',
				'🎓'   => 'welcome-learn-more',
				'💯'   => 'awards',
				'📋'   => 'clipboard',
				'📌'   => 'admin-post',
				'🔒'   => 'lock',
				'🧑‍🍳' => 'admin-users',
				'🎂'   => 'calendar-alt',
				'🔧'   => 'admin-tools',
				'⛽'   => 'performance',
				'🔄'   => 'update',
				'📏'   => 'editor-expand',
				'💼'   => 'portfolio',
				'📐'   => 'admin-customizer',
				'🍳'   => 'admin-generic',
				'🚗'   => 'car',
				'🌍'   => 'admin-site-alt3',
				'💸'   => 'money-alt',
				'🌱'   => 'palmtree',
				'👥'   => 'groups',
				'🏡'   => 'admin-home',
				'🏘️'  => 'admin-multisite',
				'🏛️'  => 'bank',
				'🔨'   => 'hammer',
				'🏆'   => 'awards',
				'🔋'   => 'performance',
				'💕'   => 'heart',
				'🎁'   => 'cart',
				'🐾'   => 'smiley',
				'☕'   => 'coffee',
				'🍕'   => 'admin-generic',
				'😴'   => 'controls-pause',
				'📱'   => 'smartphone',
				'🍪'   => 'sticky',
				'😬'   => 'format-status',
				'🧪'   => 'filter',
				'⚡'   => 'performance',
				'💎'   => 'star-filled',
				'🧠'   => 'welcome-learn-more',
				'📦'   => 'archive',
				'📯'   => 'megaphone',
				'💧'   => 'admin-generic',
				'♻️'  => 'image-rotate',
				'⏰'   => 'clock',
				'📅'   => 'calendar',
				'🧳'   => 'palmtree',
				'🏨'   => 'admin-site',
				'％'   => 'editor-bold',
			);

			$map['⭐'] = 'star-filled';
		}

		return $map;
	}

	/**
	 * Normalize dashicon slug
	 *
	 * @param string $icon Icon string.
	 * @return string Normalized slug.
	 */
	function vareoncalc_normalize_dashicon_slug( $icon ) {
		if ( empty( $icon ) ) {
			return '';
		}

		$icon = trim( $icon );

		if ( strpos( $icon, 'dashicons-' ) === 0 ) {
			return substr( $icon, strlen( 'dashicons-' ) );
		}

		$map = vareoncalc_get_dashicon_emoji_map();

		return $map[ $icon ] ?? $icon;
	}

	/**
	 * Replace emoji with dashicons in text
	 *
	 * @param string $text Text to process.
	 * @param array  $args Optional arguments.
	 * @return string Processed text.
	 */
	function vareoncalc_replace_emoji_with_dashicons( $text, array $args = array() ) {
		if ( '' === $text || null === $text ) {
			return $text;
		}

		$map      = vareoncalc_get_dashicon_emoji_map();
		$defaults = array(
			'size'      => '',
			'class'     => '',
			'label_map' => array(),
		);

		$args = wp_parse_args( $args, $defaults );

		$pattern  = '/(<script\b[^>]*>.*?<\/script>|<style\b[^>]*>.*?<\/style>)/is';
		$segments = preg_split( $pattern, $text, -1, PREG_SPLIT_DELIM_CAPTURE );

		if ( false === $segments ) {
			return $text;
		}

		$rebuilt = '';
		foreach ( $segments as $segment ) {
			if ( '' === $segment ) {
				continue;
			}

			if ( preg_match( $pattern, $segment ) ) {
				$rebuilt .= $segment;
				continue;
			}

			foreach ( $map as $emoji => $slug ) {
				if ( false === strpos( $segment, $emoji ) ) {
					continue;
				}

				$label       = $args['label_map'][ $emoji ] ?? '';
				$replacement = vareoncalc_render_dashicon(
					$emoji,
					array(
						'size'  => '' !== $args['size'] ? $args['size'] : '1em',
						'class' => $args['class'],
						'label' => $label,
						'style' => $args['style'] ?? '',
					)
				);

				$segment = str_replace( $emoji, $replacement, $segment );
			}

			$rebuilt .= $segment;
		}

		return $rebuilt;
	}

	/**
	 * Render a Dashicon span element.
	 *
	 * @param string $icon  Dashicon slug without the `dashicons-` prefix.
	 * @param array  $args {
	 *   Optional. Additional arguments to customise the output.
	 *
	 *   @type string $size  CSS size value applied to width/height/font-size. Default '16px'.
	 *   @type string $class Extra class names appended to the element.
	 *   @type string $label Accessible label; when empty the icon is aria-hidden.
	 * }
	 * @return string HTML span element containing the Dashicon.
	 */
	function vareoncalc_render_dashicon( $icon, array $args = array() ) {
		if ( empty( $icon ) ) {
			return '';
		}

		$defaults = array(
			'size'  => '',
			'class' => '',
			'label' => '',
			'style' => '',
		);

		$args = wp_parse_args( $args, $defaults );

		$normalized_icon = vareoncalc_normalize_dashicon_slug( $icon );
		if ( empty( $normalized_icon ) ) {
			return '';
		}

		$classes     = trim( 'dashicons dashicons-' . $normalized_icon . ' ' . $args['class'] );
		$style_parts = array();
		if ( $args['size'] ) {
			$style_parts[] = sprintf( 'width: %1$s; height: %1$s; font-size: %1$s;', $args['size'] );
		}
		if ( ! empty( $args['style'] ) ) {
			$style_parts[] = $args['style'];
		}

		$style = implode( ' ', array_filter( $style_parts ) );

		$attributes = $style ? ' style="' . esc_attr( $style ) . '"' : '';

		if ( ! empty( $args['label'] ) ) {
			$attributes .= ' role="img" aria-label="' . esc_attr( $args['label'] ) . '"';
		} else {
			$attributes .= ' aria-hidden="true"';
		}

		return '<span class="' . esc_attr( $classes ) . '"' . $attributes . '></span>';
	}
}
