<?php

namespace orderflow\Facebook\Helpers;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

// Helper functions
if ( ! function_exists( 'orderflow\Facebook\Helpers\get_persistence_user_data' ) ) {
    function get_persistence_user_data( $email = '', $first_name = '', $last_name = '', $phone = '' ) {
        return array(
            'em' => sanitize_email( $email ),
            'fn' => sanitize_text_field( $first_name ),
            'ln' => sanitize_text_field( $last_name ),
            'tel' => sanitize_text_field( $phone ),
        );
    }
}

if ( ! function_exists( 'orderflow\Facebook\Helpers\isWPMLActive' ) ) {
    function isWPMLActive() {
        return defined( 'ICL_SITEPRESS_VERSION' );
    }
}

/**
 * @return array
 */
function getAdvancedMatchingParams() {

	$params = array();
	$user = wp_get_current_user();

	if ( $user->ID ) {
		$user_persistence_data = get_persistence_user_data( $user->get( 'user_email' ), $user->get( 'user_firstname' ), $user->get( 'user_lastname' ), '' );
	} else {
		$user_persistence_data = get_persistence_user_data( '', '', '', '' );
	}

	if ( !empty( $user_persistence_data[ 'fn' ] ) ) $params[ 'fn' ] = $user_persistence_data[ 'fn' ];
	if ( !empty( $user_persistence_data[ 'ln' ] ) ) $params[ 'ln' ] = $user_persistence_data[ 'ln' ];
	if ( !empty( $user_persistence_data[ 'em' ] ) ) $params[ 'em' ] = $user_persistence_data[ 'em' ];
	if ( !empty( $user_persistence_data[ 'tel' ] ) ) $params[ 'ph' ] = $user_persistence_data[ 'tel' ];

	/**
	 * Add common WooCommerce Advanced Matching params
	 */

	if ( \orderflow\Facebook\isWooCommerceActive() ) {

		// if first name is not set in regular wp user meta
		if ( empty( $params['fn'] ) ) {
			$params['fn'] = $user->get( 'billing_first_name' );
		}

		// if last name is not set in regular wp user meta
		if ( empty( $params['ln'] ) ) {
			$params['ln'] = $user->get( 'billing_last_name' );
		}

		$user_persistence_data = get_persistence_user_data( '', $params['fn'], $params['ln'], $user->get('billing_phone') );
		if ( !empty( $user_persistence_data[ 'fn' ] ) ) $params[ 'fn' ] = $user_persistence_data[ 'fn' ];
		if ( !empty( $user_persistence_data[ 'ln' ] ) ) $params[ 'ln' ] = $user_persistence_data[ 'ln' ];
		if ( !empty( $user_persistence_data[ 'tel' ] ) ) $params[ 'ph' ] = $user_persistence_data[ 'tel' ];

		$params['ct'] = $user->get( 'billing_city' );
		$params['st'] = $user->get( 'billing_state' );
		$params['country'] = $user->get( 'billing_country' );

		/**
		 * Add purchase WooCommerce Advanced Matching params
		 */

		if ( \orderflow\Facebook\PYS()->woo_is_order_received_page() && isset( $_REQUEST['key'] ) && $_REQUEST['key'] != "" ) {
            $order_key = sanitize_key($_REQUEST['key']);
            $cache_key = 'order_id_' . $order_key;
            $order_id = get_transient( $cache_key );
            global $wp;
            if (empty($order_id) && $wp->query_vars['order-received']) {

                $order_id = absint( $wp->query_vars['order-received'] );
                if ($order_id) {
                    set_transient( $cache_key, $order_id, HOUR_IN_SECONDS );
                }
            }
            if ( empty($order_id) ) {
                $order_id = (int) wc_get_order_id_by_order_key( $order_key );
                set_transient( $cache_key, $order_id, HOUR_IN_SECONDS );
            }
			$order    = wc_get_order( $order_id );

			if ( $order ) {

				if ( \orderflow\Facebook\isWooCommerceVersionGte( '3.0.0' ) ) {

					$user_persistence_data = get_persistence_user_data( $order->get_billing_email(), $order->get_billing_first_name(), $order->get_billing_last_name(), $order->get_billing_phone() );
					$params = array(
						'em'      => $user_persistence_data['em'],
						'ph'      => $user_persistence_data['tel'],
						'fn'      => $user_persistence_data['fn'],
						'ln'      => $user_persistence_data['ln'],
						'ct'      => $order->get_billing_city(),
						'st'      => $order->get_billing_state(),
						'country' => $order->get_billing_country(),
					);

				} else {

					$user_persistence_data = get_persistence_user_data( $order->billing_email, $order->billing_first_name, $order->billing_last_name, $order->billing_phone );
					$params = array(
						'em'      => $user_persistence_data['em'],
						'ph'      => $user_persistence_data['tel'],
						'fn'      => $user_persistence_data['fn'],
						'ln'      => $user_persistence_data['ln'],
						'ct'      => $order->billing_city,
						'st'      => $order->billing_state,
						'country' => $order->billing_country,
					);
				}
			}
		}
	}

	/**
	 * Add common EDD Advanced Matching params
	 */

	if ( \orderflow\Facebook\isEddActive()) {

		/**
		 * Add purchase EDD Advanced Matching params
		 */

		// skip payment confirmation page
		if ( edd_is_success_page() && ! isset( $_GET['payment-confirmation'] ) ) {
			global $edd_receipt_args;

			$session = edd_get_purchase_session();
			if ( isset( $_GET['payment_key'] ) ) {
				$payment_key = urldecode( $_GET['payment_key'] );
			} else if ( $session ) {
				$payment_key = $session['purchase_key'];
			} elseif ( $edd_receipt_args && $edd_receipt_args['payment_key'] ) {
				$payment_key = $edd_receipt_args['payment_key'];
			}

			if ( isset( $payment_key ) ) {

				$payment_id = edd_get_purchase_id_by_key( $payment_key );

				if ( $payment = edd_get_payment( $payment_id ) ) {

					$user_first_name = !empty( $params[ 'fn' ] ) ? $params[ 'fn' ] : $payment->user_info[ 'first_name' ];
					$user_last_name = !empty( $params[ 'ln' ] ) ? $params[ 'ln' ] : $payment->user_info[ 'last_name' ];
					$user_persistence_data = get_persistence_user_data( '', $user_first_name, $user_last_name, '' );

					if ( !empty( $user_persistence_data[ 'fn' ] ) ) $params[ 'fn' ] = $user_persistence_data[ 'fn' ];
					if ( !empty( $user_persistence_data[ 'ln' ] ) ) $params[ 'ln' ] = $user_persistence_data[ 'ln' ];

					$params[ 'ct' ] = $payment->address[ 'city' ];
					$params[ 'st' ] = $payment->address[ 'state' ];

					$params[ 'country' ] = $payment->address[ 'country' ];
				}
			}
		}
	}

    if(\orderflow\Facebook\EventsManager::isTrackExternalId()){
        if($user && $user->get( 'external_id' )){
            $params['external_id'] = $user->get( 'external_id' );
        } elseif (\orderflow\Facebook\PYS()->get_pbid()) {
            $params['external_id'] = \orderflow\Facebook\PYS()->get_pbid();
        }
    }
	$sanitized = array();

	foreach ( $params as $key => $value ) {

		if ( ! empty( $value ) ) {
			$sanitized[ $key ] = sanitizeAdvancedMatchingParam( $value, $key );
		}

	}

	return $sanitized;

}

function sanitizeAdvancedMatchingParam( $value, $key ) {
    
    // prevents fatal error when mb_string extension not enabled
    if ( function_exists( 'mb_strtolower' ) ) {
        $value = mb_strtolower( $value );
    } else {
        $value = strtolower( $value );
    }

	if ( $key == 'ph' ) {
		$value = preg_replace( '/\D/', '', $value );
	} elseif ( $key == 'em' ) {
		$value = preg_replace( '/[^a-z0-9._+-@]+/i', '', $value );
	} else {
		$value = preg_replace( '/[^a-z]/', '', $value );
	}

	return $value;

}

/**
 * @param string $product_id
 *
 * @return array
 */
function getFacebookWooProductContentId( $product_id ) {

	if(isWPMLActive() && \orderflow\Facebook\Facebook::instance()->getOption( 'woo_wpml_unified_id' )) {
		$wpml_product_id = apply_filters('wpml_original_element_id', NULL, $product_id);
		if ($wpml_product_id) {
			$product_id = $wpml_product_id;
		}
	}

    if ( \orderflow\Facebook\Facebook::instance()->getOption( 'woo_content_id' ) == 'product_sku' ) {
        $product = wc_get_product( $product_id );
        if ($product && $product->is_type( 'variation' ) ) {
            $content_id = $product->get_sku();
            if ( empty( $content_id ) ) {
                $parent_id = $product->get_parent_id();
                $parent_product = wc_get_product( $parent_id );
                if($parent_product){
                    $content_id = $parent_product->get_sku();
                }
                if ( empty( $content_id ) ) {
                    $content_id = $product_id;
                }
            }
        } elseif($product) {
            $content_id = $product->get_sku();
            if ( empty( $content_id ) ) {
                $content_id = $product_id;
            }
        } else {
            $content_id = $product_id;
        }
    } else {
        $content_id = $product_id;
    }

	$prefix = \orderflow\Facebook\Facebook::instance()->getOption( 'woo_content_id_prefix' );
	$suffix = \orderflow\Facebook\Facebook::instance()->getOption( 'woo_content_id_suffix' );

	$value = $prefix . $content_id . $suffix;
	$value = array( $value );

	// Facebook for WooCommerce plugin integration
	if ( ! isDefaultWooContentIdLogic() ) {

		$product = wc_get_product($product_id);

		if ( ! $product ) {
			return $value;
		}


        $ids = array(
            get_fb_plugin_retailer_id($product)
		);

		$value = array_values( array_filter( $ids ) );
		
	}

	return $value;

}
function get_fb_plugin_retailer_id( $woo_product ) {
    if(!$woo_product) return "";
    $woo_id = $woo_product->get_id();

    // Call $woo_product->get_id() instead of ->id to account for Variable
    // products, which have their own variant_ids.
    return $woo_product->get_sku() ? $woo_product->get_sku() . '_' .
        $woo_id : 'wc_post_id_'. $woo_id;
}
function getFacebookWooCartItemId( $item ) {

	if ( ! \orderflow\Facebook\Facebook::instance()->getOption( 'woo_variable_as_simple' ) && isset( $item['variation_id'] ) && $item['variation_id'] !== 0 ) {
		$product_id = $item['variation_id'];
	} else {
		$product_id = $item['product_id'];
	}

	// Facebook for WooCommerce plugin integration
	if ( ! isDefaultWooContentIdLogic() ) {

		if ( isset( $item['variation_id'] ) && $item['variation_id'] !== 0 ) {
			$product_id = $item['variation_id'];
		} else {
			$product_id = $item['product_id'];
		}

	}

	return $product_id;

}

/**
 * Adds "content_name" and "category_name" params
 */
function getWooCustomAudiencesOptimizationParams( $post_id ) {

	$post = get_post( $post_id );

	$params = array(
		'content_name'  => '',
		'category_name' => '',
	);

	if ( ! $post ) {
		return $params;
	}

	if ( $post->post_type == 'product_variation' ) {
		$post_id = $post->post_parent; // get terms from parent
	}

	$params['content_name'] = $post->post_title;
	$params['category_name'] = implode( ', ', \orderflow\Facebook\getObjectTerms( 'product_cat', $post_id ) );

	return $params;

}

function getWooSingleAddToCartParams( $_product_id, $qty = 1 ) {

	$params = array();
    $product = wc_get_product($_product_id);
    if(!$product) {
        return array();
    }
    
    $product_ids = array();
    $isGrouped = $product->get_type() == "grouped";
    if($isGrouped) {
        $product_ids = $product->get_children();
    } else {
        $product_ids[] = $_product_id;
    }
    $params['content_type'] = 'product';
    $params['content_ids']  = array();
    $params['contents'] = array();




	// content_name, category_name, tags
	$params['tags'] = implode( ', ', \orderflow\Facebook\getObjectTerms( 'product_tag', $_product_id ) );
	$params = array_merge( $params, getWooCustomAudiencesOptimizationParams( $_product_id ) );
	// Ensure content_name is always set for AddToCart (product name - works for simple and variable)
	if ( empty( $params['content_name'] ) && $product ) {
		$params['content_name'] = method_exists( $product, 'get_name' ) ? $product->get_name() : get_the_title( $_product_id );
	}

	// currency - always add like PageView (always uppercase)
	$params['currency'] = strtoupper(get_woocommerce_currency());
	
	// value - always add
	if ( \orderflow\Facebook\PYS()->getOption( 'woo_add_to_cart_value_enabled' ) ) {
		// If value option is enabled, use the configured option
		$value_option = \orderflow\Facebook\PYS()->getOption( 'woo_add_to_cart_value_option' );
		$global_value = \orderflow\Facebook\PYS()->getOption( 'woo_add_to_cart_value_global', 0 );
		$params['value'] = \orderflow\Facebook\getWooEventValue( $value_option, $global_value, 100, $_product_id, $qty );
	} else {
		// If value option is not enabled, use product price as default
		$params['value'] = \orderflow\Facebook\getWooProductPriceToDisplay( $_product_id, $qty );
	}

    foreach ($product_ids as $product_id) {
        $product = wc_get_product($product_id);
        if(!$product) continue;
        if($product->get_type() == "variable" && $isGrouped) {
            continue;
        }
        $content_id = getFacebookWooProductContentId( $product_id );
        $params['content_ids'] = array_merge($params['content_ids'],$content_id);
        // contents
        if ( isDefaultWooContentIdLogic() ) {

            // Facebook for WooCommerce plugin does not support new Dynamic Ads parameters
            $params['contents'][] = array(
                'id'         => (string) reset( $content_id ),
                'quantity'   => $qty,
                //'item_price' => \orderflow\Facebook\getWooProductPriceToDisplay( $product_id ),// remove because price need send only with currency
            );
        }
    }

	return $params;

}

function getWooCartParams( $context = 'cart' ) {

	$params['content_type'] = 'product';

	$content_ids        = array();
	$content_names      = array();
	$content_categories = array();
	$tags               = array();
	$contents           = array();

	foreach ( WC()->cart->cart_contents as $cart_item_key => $cart_item ) {

		$product_id = getFacebookWooCartItemId( $cart_item );
		// raw product id
		$_product_id = empty( $cart_item['variation_id'] ) ? $cart_item['product_id'] : $cart_item['variation_id'];
		$content_id = getFacebookWooProductContentId( $product_id );

		$content_ids = array_merge( $content_ids, $content_id );

		// content_name, category_name, tags
		$custom_audiences = getWooCustomAudiencesOptimizationParams( $product_id );
		$content_name     = ! empty( $custom_audiences['content_name'] ) ? $custom_audiences['content_name'] : '';
		if ( empty( $content_name ) ) {
			$_product = wc_get_product( $_product_id );
			if ( $_product ) {
				$content_name = method_exists( $_product, 'get_name' ) ? $_product->get_name() : get_the_title( $_product_id );
			}
		}
		$content_names[]      = $content_name;
		$content_categories[] = $custom_audiences['category_name'];

		$cart_item_tags = \orderflow\Facebook\getObjectTerms( 'product_tag', $product_id );
		// Variations often don't have terms directly; include parent product tags.
		if ( empty( $cart_item_tags ) && ! empty( $cart_item['variation_id'] ) && ! empty( $cart_item['product_id'] ) ) {
			$cart_item_tags = \orderflow\Facebook\getObjectTerms( 'product_tag', $cart_item['product_id'] );
		}
		$tags = array_merge( $tags, $cart_item_tags );

		// contents
		$contents[] = array(
			'id'         => (string) reset( $content_id ),
			'quantity'   => $cart_item['quantity'],
			//'item_price' => \orderflow\Facebook\getWooProductPriceToDisplay( $_product_id ),
		);

	}

	$params['content_ids']   = ( $content_ids );
	$params['content_name']  = implode( ', ', $content_names );
	$params['category_name'] = implode( ', ', $content_categories );

	// contents
	if ( isDefaultWooContentIdLogic() ) {

		// Facebook for WooCommerce plugin does not support new Dynamic Ads parameters
		$params['contents'] = ( $contents );

	}

	$tags           = array_unique( $tags );
	$tags           = array_slice( $tags, 0, 100 );
	$params['tags'] = implode( ', ', $tags );

	if ( $context == 'InitiateCheckout' ) {

		$params['num_items'] = WC()->cart->get_cart_contents_count();

		$value_option_option  = 'woo_initiate_checkout_value_option';
		$value_global_option  = 'woo_initiate_checkout_value_global';
		
		$params['subtotal'] = \orderflow\Facebook\getWooCartSubtotal();

		// currency, value - always add like Purchase event (currency always uppercase)
		$value_option = \orderflow\Facebook\PYS()->getOption( $value_option_option );
		$global_value = \orderflow\Facebook\PYS()->getOption( $value_global_option, 0 );

		$params['value']    = \orderflow\Facebook\getWooEventValueCart( $value_option, $global_value );
		$params['currency'] = strtoupper(get_woocommerce_currency());

	} else { // AddToCart

		$value_enabled_option = 'woo_add_to_cart_value_enabled';
		$value_option_option  = 'woo_add_to_cart_value_option';
		$value_global_option  = 'woo_add_to_cart_value_global';

		if ( \orderflow\Facebook\PYS()->getOption( $value_enabled_option ) ) {

			$value_option = \orderflow\Facebook\PYS()->getOption( $value_option_option );
			$global_value = \orderflow\Facebook\PYS()->getOption( $value_global_option, 0 );

			$params['value']    = \orderflow\Facebook\getWooEventValueCart( $value_option, $global_value );
			$params['currency'] = strtoupper(get_woocommerce_currency());

		}
	}

	return $params;

}

function isFacebookForWooCommerceActive() {
	return class_exists( 'WC_Facebookcommerce' );
}

function isDefaultWooContentIdLogic() {
	return ! isFacebookForWooCommerceActive() || \orderflow\Facebook\Facebook::instance()->getOption( 'woo_content_id_logic' ) != 'facebook_for_woocommerce';
}

/**
 * EASY DIGITAL DOWNLOADS
 */

function getFacebookEddDownloadContentId( $download_id ) {

	if ( \orderflow\Facebook\PYS()->getOption( 'edd_content_id' ) == 'download_sku' ) {
		$content_id = get_post_meta( $download_id, 'edd_sku', true );
	} else {
		$content_id = $download_id;
	}

	$prefix = \orderflow\Facebook\PYS()->getOption( 'edd_content_id_prefix' );
	$suffix = \orderflow\Facebook\PYS()->getOption( 'edd_content_id_suffix' );

	return $prefix . $content_id . $suffix;

}

/**
 * Adds "content_name" and "category_name" params
 */
function getEddCustomAudiencesOptimizationParams( $post_id ) {

	$post = get_post( $post_id );

	$params = array(
		'content_name'  => '',
		'category_name' => '',
	);

	if ( ! $post ) {
		return $params;
	}

	$params['content_name'] = $post->post_title;
	$params['category_name'] = implode( ', ', \orderflow\Facebook\getObjectTerms( 'download_category', $post_id ) );

	return $params;

}



function getCompleteRegistrationOrderParams() {
    $params = array();
    $order_key = sanitize_key( $_REQUEST['key']);
    $cache_key = 'order_id_' . $order_key;
    $order_id = get_transient( $cache_key );
    if ( empty($order_id) ) {
        $order_id = (int) wc_get_order_id_by_order_key( $order_key );
        set_transient( $cache_key, $order_id, HOUR_IN_SECONDS );
    }
    $order    = wc_get_order( $order_id );
    if(!$order) return false;

    $value_option   = \orderflow\Facebook\Facebook::instance()->getOption( 'woo_complete_registration_custom_value' );
    $global_value   = \orderflow\Facebook\Facebook::instance()->getOption( 'woo_complete_registration_global_value', 0 );
    $percents_value = \orderflow\Facebook\Facebook::instance()->getOption( 'woo_complete_registration_percent_value', 100 );

    $params['value'] = \orderflow\Facebook\getWooEventValueOrder( $value_option, $order, $global_value, $percents_value );
    $params['currency'] = strtoupper(get_woocommerce_currency());
    return $params;
}