<?php

namespace MetForm_Pro\Utils;

defined('ABSPATH') || exit;
/**
 * Global helper class.
 *
 * @since 1.0.0
 */

class Helper
{

	/**
	 * Get metform older version if has any.
	 *
	 * @since 1.0.0
	 * @access public
	 */
	public static function old_version()
	{
		$version = get_option('metform_version');
		return null == $version ? -1 : $version;
	}

	/**
	 * Set metform installed version as current version.
	 *
	 * @since 1.0.0
	 * @access public
	 */
	public static function set_version()
	{
	}

	/**
	 * Auto generate classname from path.
	 *
	 * @since 1.0.0
	 * @access public
	 */
	public static function make_classname($dirname)
	{
		$dirname = pathinfo($dirname, PATHINFO_FILENAME);
		$class_name	 = explode('-', $dirname);
		$class_name	 = array_map('ucfirst', $class_name);
		$class_name	 = implode('_', $class_name);

		return $class_name;
	}

	public static function google_fonts($font_families = [])
	{
		$fonts_url         = '';
		if ($font_families) {
			$query_args = array(
				'family' => urlencode(implode('|', $font_families))
			);

			$fonts_url = add_query_arg($query_args, 'https://fonts.googleapis.com/css');
		}

		return esc_url_raw($fonts_url);
	}

	public static function kses($raw)
	{

		$allowed_tags = array(
			'a'								 => array(
				'class'	 => array(),
				'href'	 => array(),
				'rel'	 => array(),
				'title'	 => array(),
				'target'	 => array(),
			),
			'abbr'							 => array(
				'title' => array(),
			),
			'b'								 => array(),
			'blockquote'					 => array(
				'cite' => array(),
			),
			'cite'							 => array(
				'title' => array(),
			),
			'code'							 => array(),
			'del'							 => array(
				'datetime'	 => array(),
				'title'		 => array(),
			),
			'dd'							 => array(),
			'div'							 => array(
				'class'	 => array(),
				'title'	 => array(),
				'style'	 => array(),
			),
			'dl'							 => array(),
			'dt'							 => array(),
			'em'							 => array(),
			'h1'							 => array(
				'class' => array(),
			),
			'h2'							 => array(
				'class' => array(),
			),
			'h3'							 => array(
				'class' => array(),
			),
			'h4'							 => array(
				'class' => array(),
			),
			'h5'							 => array(
				'class' => array(),
			),
			'h6'							 => array(
				'class' => array(),
			),
			'i'								 => array(
				'class' => array(),
			),
			'img'							 => array(
				'alt'	 => array(),
				'class'	 => array(),
				'height' => array(),
				'src'	 => array(),
				'width'	 => array(),
			),
			'li'							 => array(
				'class' => array(),
			),
			'ol'							 => array(
				'class' => array(),
			),
			'p'								 => array(
				'class' => array(),
			),
			'q'								 => array(
				'cite'	 => array(),
				'title'	 => array(),
			),
			'span'							 => array(
				'class'	 => array(),
				'title'	 => array(),
				'style'	 => array(),
			),
			'iframe'						 => array(
				'width'			 => array(),
				'height'		 => array(),
				'scrolling'		 => array(),
				'frameborder'	 => array(),
				'allow'			 => array(),
				'src'			 => array(),
			),
			'strike'						 => array(),
			'br'							 => array(),
			'strong'						 => array(),
			'data-wow-duration'				 => array(),
			'data-wow-delay'				 => array(),
			'data-wallpaper-options'		 => array(),
			'data-stellar-background-ratio'	 => array(),
			'ul'							 => array(
				'class' => array(),
			),
		);

		if (function_exists('wp_kses')) { // WP is here
			return wp_kses($raw, $allowed_tags);
		} else {
			return $raw;
		}
	}

	public static function kspan($text)
	{
		return str_replace(['{', '}'], ['<span>', '</span>'], self::kses($text));
	}


	public static function trim_words($text, $num_words)
	{
		return wp_trim_words($text, $num_words, '');
	}

	public static function array_push_assoc($array, $key, $value)
	{
		$array[$key] = $value;
		return $array;
	}

	public static function render($content)
	{
		if (stripos($content, "metform-has-lisence") !== false) {
			return null;
		}

		return $content;
	}
	public static function render_elementor_content($content_id)
	{
		$elementor_instance = \Elementor\Plugin::instance();
		return $elementor_instance->frontend->get_builder_content_for_display($content_id);
	}

	public static function img_meta($id)
	{
		$attachment = get_post($id);
		if ($attachment == null || $attachment->post_type != 'attachment') {
			return null;
		}
		return [
			'alt' => get_post_meta($attachment->ID, '_wp_attachment_image_alt', true),
			'caption' => $attachment->post_excerpt,
			'description' => $attachment->post_content,
			'href' => get_permalink($attachment->ID),
			'src' => $attachment->guid,
			'title' => $attachment->post_title
		];
	}

	public static function render_inner_content($content, $id)
	{
		return str_replace('.elementor-' . $id . ' ', '#elementor .elementor-' . $id . ' ', $content);
	}

	public static function url_generate($url, $params)
	{
		$params_url = http_build_query($params, '', '&');
		if (strpos($url, '?') === false) {
			return ($url . '?' . $params_url);
		} else {
			return ($url . '&' . $params_url);
		}
	}

	/**
	 * Check if woocommerce is exists
	 */
	public static function mf_is_woo_exists()
	{
		if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
			return true;
		}
		return false;
	}

	/**
	 * Get license tier by price id
	 * @param string $price_id
	 * @return string
	 */
	public static function get_tier( $price_id = '' ) {
		switch ( $price_id ) {
			case '1':
			case '4':
				return 'starter';
			case '2':
			case '5':
				return 'mid';
			case '3':
			case '6':
				return 'top';
			default:
				return '';
		}
	}

	/**
	 * Calculate and validate payment amount based on field configuration
	 * 
	 * @param string $amount_field Amount field name
	 * @param array $map_data Form field configuration
	 * @param array $form_data User submitted data
	 * @param mixed $payment_input_name Payment input name
	 * @return float|false Validated amount or false
	 */
	public static function calculate_expected_amount($amount_field, $map_data, $form_data, $payment_input_name)
	{
		if (!isset($map_data[$amount_field])) {
			return false;
		}

		$field_config = $map_data[$amount_field];
		
		// CASE 1: Calculation field - evaluate equation
		if (isset($field_config->widgetType) && $field_config->widgetType === 'mf-calculation') {
			$equation = isset($field_config->mf_input_calculation_equation) 
				? $field_config->mf_input_calculation_equation : '';

			if (empty($equation)) {
				return false;
			}

			return self::evaluate_equation($equation, $form_data, $map_data);
		}

		// CASE 2: Fixed price from widget or field settings
		$widget = is_array($payment_input_name) ? current($payment_input_name) : '';
		if (isset($map_data[$widget]->mf_input_payment_field_amount) 
			&& !empty($map_data[$widget]->mf_input_payment_field_amount)) {
			$fixed_amount = floatval($map_data[$widget]->mf_input_payment_field_amount);
			if ($fixed_amount > 0) {
				return $fixed_amount;
			}
		}

		if (isset($field_config->mf_input_payment_field_amount) 
			&& !empty($field_config->mf_input_payment_field_amount)) {
			$fixed_amount = floatval($field_config->mf_input_payment_field_amount);
			if ($fixed_amount > 0) {
				return $fixed_amount;
			}
		}

		// CASE 3: Radio/Select with predefined options
		if (isset($field_config->mf_input_list) && !empty($field_config->mf_input_list)) {
			$selected_value = isset($form_data[$amount_field]) 
				? $form_data[$amount_field] : '';
			
			foreach ($field_config->mf_input_list as $option) {
				$option_value = is_object($option) 
					? (isset($option->mf_input_option_value) ? $option->mf_input_option_value : '')
					: (isset($option['mf_input_option_value']) ? $option['mf_input_option_value'] : '');
					
				if ($option_value == $selected_value && !empty($option_value)) {
					return floatval($selected_value);
				}
			}
			
			// Reject invalid option value
			return false;
		}

		// CASE 4: User-defined amount (donation/pay-what-you-want)
		if (isset($form_data[$amount_field])) {
			$user_amount = floatval($form_data[$amount_field]);
			
			// Validate: minimum $0.50, max 2 decimals, reasonable limit
			if ($user_amount < 0.50 || round($user_amount, 2) != $user_amount) {
				return false;
			}
			
			if ($user_amount < 999999999) {
				return $user_amount;
			}
		}

		return false;
	}

	/**
	 * Validate that a submitted field value is permitted by the server-side field config.
	 * For radio/select/checkbox fields, value(s) must be in the predefined option list.
	 *
	 * @param string $field_name  Field input name
	 * @param mixed  $submitted   Submitted value (scalar or array for checkboxes)
	 * @param array  $map_data    Server-side field map from get_fields()
	 * @return mixed|false Validated value or false if invalid
	 */
	private static function validate_field_value( $field_name, $submitted, $map_data ) {
		
		if ( empty( $map_data ) || ! isset( $map_data[ $field_name ] ) ) {
			return $submitted;
		}

		$field_config = $map_data[ $field_name ];

		// Only constrain fields that have a predefined option list (radio, select, checkbox).
		if ( ! isset( $field_config->mf_input_list ) || empty( $field_config->mf_input_list ) ) {
			return $submitted;
		}

		$allowed = [];
		foreach ( $field_config->mf_input_list as $option ) {
			$v = is_object( $option )
				? ( isset( $option->mf_input_option_value ) ? (string) $option->mf_input_option_value : '' )
				: ( isset( $option['mf_input_option_value'] ) ? (string) $option['mf_input_option_value'] : '' );
			if ( $v !== '' ) {
				$allowed[] = $v;
			}
		}

		if ( is_array( $submitted ) ) {
			// Checkbox – every selected value must be in the allowed list.
			foreach ( $submitted as $val ) {
				if ( ! in_array( (string) $val, $allowed, true ) ) {
					return false;
				}
			}
			return $submitted;
		}

		if ( ! in_array( (string) $submitted, $allowed, true ) ) {
			return false;
		}

		return $submitted;
	}

	/**
	 * Safely evaluate mathematical equation with form data
	 *
	 * @param string $equation  Math equation to evaluate
	 * @param array  $form_data Form data for variables
	 * @param array  $map_data  Server-side field map — used to validate option-based fields
	 * @return float|false Result or false on error / invalid value
	 */
	public static function evaluate_equation( $equation, $form_data, $map_data = [] )
	{
		$equation = preg_replace('/[^0-9+\-*\/().a-zA-Z_\-\s]/', '', $equation);

		preg_match_all('/[a-zA-Z_][a-zA-Z0-9_\-]*/', $equation, $matches);
		$variables = array_unique($matches[0]);

		foreach ($variables as $var) {
			$raw = isset($form_data[$var]) ? $form_data[$var] : 0;

			// Reject the calculation if any variable value is not permitted
			// by the server-side field configuration (e.g. unlisted radio/select value).
			$validated = self::validate_field_value( $var, $raw, $map_data );
			if ( $validated === false ) {
				return false;
			}

			if (is_array($validated)) {
				$value = array_sum(array_map('floatval', $validated));
			} else {
				$value = floatval($validated);
			}

			$equation = preg_replace('/\b' . preg_quote($var, '/') . '\b/', $value, $equation);
		}

		try {
			if (preg_match('/[a-zA-Z]/', $equation)) {
				return false;
			}

			$result = @eval('return (' . $equation . ');');

			if ($result === false || !is_numeric($result)) {
				return false;
			}

			return floatval($result);
		} catch (\Exception $e) {
			return false;
		}
	}
}
