<?php

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

class AIEO_Google_Tag {

	
	private static $instance = null;

	public static function instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	public function register() {
		add_action( 'wp_head', array( $this, 'emit_tag' ), 2 );
		add_action( 'wp_body_open', array( $this, 'emit_gtm_noscript' ) );
		add_action( 'wp_footer', array( $this, 'emit_purchase' ), 20 );
		
		
		
		
		add_action( 'wp_footer', array( $this, 'emit_ga4_events' ), 21 );
		add_action( 'woocommerce_add_to_cart', array( $this, 'stash_add_to_cart' ), 10, 4 );
		
		
		add_action( 'wp_footer', array( $this, 'emit_wishlist_listener' ), 22 );
		
		
		
		
		
		
		
		add_filter( 'rocket_delay_js_exclusions', array( $this, 'rocket_exclusions' ) );
		add_filter( 'rocket_exclude_defer_js', array( $this, 'rocket_exclusions' ) );
	}

	
	public function rocket_exclusions( $excluded ) {
		$excluded = is_array( $excluded ) ? $excluded : array();
		$mode     = $this->mode( $this->config() );
		if ( 'off' === $mode ) {
			return $excluded;
		}
		$excluded[] = 'aieo-google-tag';                   
		if ( 'gtag' === $mode ) {
			$excluded[] = 'googletagmanager.com/gtag/js';  
		}
		return $excluded;
	}

	
	
	

	private function config() {
		if ( class_exists( 'AIEO_DMM_Conversions' ) && method_exists( 'AIEO_DMM_Conversions', 'get_config' ) ) {
			return AIEO_DMM_Conversions::get_config();
		}
		$o = get_option( 'aieo_dmm_conversions', array() );
		return is_array( $o ) ? $o : array();
	}

	private function mode( $c ) {
		$m = isset( $c['google_tag_mode'] ) ? $c['google_tag_mode'] : 'off';
		return in_array( $m, array( 'off', 'gtag', 'gtm' ), true ) ? $m : 'off';
	}

	private function ga_id( $c )    { return isset( $c['ga_measurement_id'] ) ? trim( (string) $c['ga_measurement_id'] ) : ''; }
	private function ads_id( $c )   { return isset( $c['ads_conversion_id'] ) ? trim( (string) $c['ads_conversion_id'] ) : ''; }
	private function gtm_id( $c )   { return isset( $c['gtm_container_id'] ) ? trim( (string) $c['gtm_container_id'] ) : ''; }
	private function ads_label( $c ){ return isset( $c['ads_conversion_label'] ) ? trim( (string) $c['ads_conversion_label'] ) : ''; }

	
	private function marketing_blocked() {
		if ( class_exists( 'AIEO_Session_Tracker' ) && method_exists( 'AIEO_Session_Tracker', 'is_marketing_consent_blocking' ) ) {
			return AIEO_Session_Tracker::is_marketing_consent_blocking();
		}
		return false;
	}

	
	
	

	public function emit_tag() {
		$c    = $this->config();
		$mode = $this->mode( $c );

		if ( 'gtag' === $mode ) {
			$ga      = $this->ga_id( $c );
			$ads     = $this->ads_id( $c );
			$primary = '' !== $ga ? $ga : $ads;
			if ( '' === $primary ) {
				return;
			}
			echo "\n<!-- AIEO Google tag (gtag.js) -->\n";
			echo '<script async data-cfasync="false" src="https://www.googletagmanager.com/gtag/js?id=' . esc_attr( $primary ) . '"></script>' . "\n";
			$js  = 'window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag("js",new Date());';
			if ( '' !== $ga ) {
				$js .= 'gtag("config",' . wp_json_encode( $ga ) . ');';
			}
			if ( '' !== $ads ) {
				
				$js .= 'gtag("config",' . wp_json_encode( $ads ) . ',{"allow_enhanced_conversions":true});';
			}
			echo '<script data-cfasync="false">/*aieo-google-tag*/' . $js . '</script>' . "\n"; 
		} elseif ( 'gtm' === $mode ) {
			$gtm = $this->gtm_id( $c );
			if ( '' === $gtm ) {
				return;
			}
			echo "\n<!-- AIEO Google Tag Manager -->\n";
			echo '<script data-cfasync="false">/*aieo-google-tag*/(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({"gtm.start":new Date().getTime(),event:"gtm.js"});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!="dataLayer"?"&l="+l:"";j.async=true;j.src="https://www.googletagmanager.com/gtm.js?id="+i+dl;f.parentNode.insertBefore(j,f);})(window,document,"script","dataLayer",' . wp_json_encode( $gtm ) . ');</script>' . "\n"; 
		}
	}

	public function emit_gtm_noscript() {
		$c = $this->config();
		if ( 'gtm' !== $this->mode( $c ) ) {
			return;
		}
		$gtm = $this->gtm_id( $c );
		if ( '' === $gtm ) {
			return;
		}
		echo '<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=' . esc_attr( $gtm ) . '" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>' . "\n";
	}

	
	
	

	public function emit_purchase() {
		$c    = $this->config();
		$mode = $this->mode( $c );
		if ( 'off' === $mode ) {
			return;
		}
		if ( ! function_exists( 'is_wc_endpoint_url' ) || ! is_wc_endpoint_url( 'order-received' ) ) {
			return;
		}
		$oid = function_exists( 'get_query_var' ) ? absint( get_query_var( 'order-received' ) ) : 0;
		if ( $oid <= 0 || ! function_exists( 'wc_get_order' ) ) {
			return;
		}
		$order = wc_get_order( $oid );
		if ( ! $order ) {
			return;
		}

		$value    = (float) $order->get_total();
		$currency = (string) $order->get_currency();
		$txn      = (string) $order->get_id();
		$ads_id   = $this->ads_id( $c );
		$label    = $this->ads_label( $c );

		
		$ud = ( ! $this->marketing_blocked() && class_exists( 'AIEO_PII_Hasher' ) )
			? AIEO_PII_Hasher::google_gtag_user_data( $order )
			: array();

		if ( 'gtag' === $mode ) {
			if ( '' === $ads_id ) {
				return; 
			}
			$send_to = $ads_id . ( '' !== $label ? '/' . $label : '' );
			$js      = '';
			if ( ! empty( $ud ) ) {
				$js .= 'gtag("set","user_data",' . wp_json_encode( $ud ) . ');';
			}
			$js .= 'gtag("event","conversion",{send_to:' . wp_json_encode( $send_to ) . ',value:' . wp_json_encode( $value ) . ',currency:' . wp_json_encode( $currency ) . ',transaction_id:' . wp_json_encode( $txn ) . '});';
			echo "\n<!-- AIEO Google Ads conversion + Enhanced Conversions -->\n";
			echo '<script>if(typeof gtag==="function"){' . $js . '}</script>' . "\n"; 
		} elseif ( 'gtm' === $mode ) {
			$payload = array(
				'event'          => 'aieo_purchase',
				'value'          => $value,
				'currency'       => $currency,
				'transaction_id' => $txn,
			);
			if ( '' !== $ads_id ) { $payload['ads_conversion_id'] = $ads_id; }
			if ( '' !== $label )  { $payload['ads_conversion_label'] = $label; }
			if ( ! empty( $ud ) ) { $payload['user_data'] = $ud; }

			
			
			
			
			
			
			
			
			
			
			
			
			$fb_mode = isset( $c['fb_mode'] ) ? (string) $c['fb_mode'] : 'off';
			if ( in_array( $fb_mode, array( 'capi', 'both' ), true ) && class_exists( 'AIEO_CAPI_Sender' ) ) {
				$payload['fb_event_id']  = AIEO_CAPI_Sender::get_or_mint_event_id( $order );
				$payload['content_type'] = 'product';
				$cap = AIEO_CAPI_Sender::instance()->build_purchase_payload( $order, $c );
				$cd  = ( isset( $cap['custom_data'] ) && is_array( $cap['custom_data'] ) ) ? $cap['custom_data'] : array();
				if ( ! empty( $cd['content_ids'] ) ) { $payload['content_ids'] = $cd['content_ids']; }
				if ( ! empty( $cd['contents'] ) )    { $payload['contents']    = $cd['contents']; }
				if ( isset( $cd['num_items'] ) )     { $payload['num_items']   = (int) $cd['num_items']; }
				$fbp = (string) $order->get_meta( '_aieo_fbp' );
				$fbc = (string) $order->get_meta( '_aieo_fbc' );
				if ( '' !== $fbp ) { $payload['fbp'] = $fbp; }
				if ( '' !== $fbc ) { $payload['fbc'] = $fbc; }
			}

			
			
			
			if ( isset( $c['ga_send_server'] ) && 'yes' === $c['ga_send_server'] ) {
				$cid = (string) $order->get_meta( '_aieo_ga_cid' );
				if ( '' !== $cid ) { $payload['ga_client_id'] = $cid; }
			}

			echo "\n<script>window.dataLayer=window.dataLayer||[];dataLayer.push(" . wp_json_encode( $payload ) . ");</script>\n"; 
		}
	}

	
	
	

	
	public function emit_ga4_events() {
		$c = $this->config();
		if ( 'gtag' !== $this->mode( $c ) || '' === $this->ga_id( $c ) ) {
			return;
		}
		if ( 'yes' !== ( isset( $c['ga_send_browser'] ) ? $c['ga_send_browser'] : 'no' ) ) {
			return;
		}
		if ( ! function_exists( 'WC' ) || ! function_exists( 'get_woocommerce_currency' ) ) {
			return;
		}
		$events = array();
		$cur    = get_woocommerce_currency();

		
		if ( WC()->session ) {
			$atc = WC()->session->get( 'aieo_ga4_atc', array() );
			if ( ! empty( $atc ) && is_array( $atc ) ) {
				WC()->session->set( 'aieo_ga4_atc', array() );
				$val = 0;
				foreach ( $atc as $it ) { $val += (float) $it['price'] * (int) $it['quantity']; }
				$events[] = array( 'name' => 'add_to_cart', 'params' => array( 'currency' => $cur, 'value' => round( $val, 2 ), 'items' => array_values( $atc ) ) );
			}
		}

		
		
		
		if ( function_exists( 'is_search' ) && is_search() ) {
			$q = function_exists( 'get_search_query' ) ? trim( (string) get_search_query() ) : '';
			if ( '' !== $q ) {
				$events[] = array( 'name' => 'search', 'params' => array( 'search_term' => $q ) );
			}
		}

		if ( function_exists( 'is_product' ) && is_product() ) {
			
			$it = $this->ga4_item( function_exists( 'wc_get_product' ) ? wc_get_product( get_queried_object_id() ) : null, 1 );
			if ( $it ) {
				$events[] = array( 'name' => 'view_item', 'params' => array( 'currency' => $cur, 'value' => $it['price'], 'items' => array( $it ) ) );
			}
		} elseif ( ( function_exists( 'is_shop' ) && is_shop() ) || ( function_exists( 'is_product_category' ) && is_product_category() ) || ( function_exists( 'is_product_tag' ) && is_product_tag() ) ) {
			
			global $wp_query;
			$items = array();
			$i     = 1;
			foreach ( (array) ( isset( $wp_query->posts ) ? $wp_query->posts : array() ) as $post ) {
				if ( count( $items ) >= 20 ) { break; }
				$it = $this->ga4_item( function_exists( 'wc_get_product' ) ? wc_get_product( $post ) : null, 1 );
				if ( $it ) { $it['index'] = $i++; $items[] = $it; }
			}
			if ( ! empty( $items ) ) {
				$qo   = get_queried_object();
				$name = ( is_object( $qo ) && isset( $qo->name ) ) ? (string) $qo->name : __( 'Shop', 'ai-eshop-optimizer' );
				$events[] = array( 'name' => 'view_item_list', 'params' => array( 'item_list_name' => $name, 'items' => $items ) );
			}
		}

		
		if ( function_exists( 'is_checkout' ) && is_checkout()
			&& ! ( function_exists( 'is_wc_endpoint_url' ) && is_wc_endpoint_url( 'order-received' ) )
			&& WC()->cart && ! WC()->cart->is_empty() ) {
			$items = array();
			$val   = 0;
			foreach ( WC()->cart->get_cart() as $ci ) {
				$it = $this->ga4_item( isset( $ci['data'] ) ? $ci['data'] : null, isset( $ci['quantity'] ) ? $ci['quantity'] : 1 );
				if ( $it ) { $items[] = $it; $val += $it['price'] * $it['quantity']; }
			}
			if ( ! empty( $items ) ) {
				$events[] = array( 'name' => 'begin_checkout', 'params' => array( 'currency' => $cur, 'value' => round( $val, 2 ), 'items' => $items ) );
			}
		}

		
		
		if ( function_exists( 'is_wc_endpoint_url' ) && is_wc_endpoint_url( 'order-received' ) && function_exists( 'wc_get_order' ) ) {
			$oid   = function_exists( 'get_query_var' ) ? absint( get_query_var( 'order-received' ) ) : 0;
			$order = $oid ? wc_get_order( $oid ) : null;
			if ( $order ) {
				$items = array();
				foreach ( $order->get_items() as $li ) {
					if ( ! is_a( $li, 'WC_Order_Item_Product' ) ) { continue; }
					$qty = (int) $li->get_quantity();
					$it  = $this->ga4_item( $li->get_product(), $qty );
					if ( $it ) {
						$it['price'] = $qty > 0 ? round( (float) $li->get_total() / $qty, 2 ) : $it['price'];
						$items[]     = $it;
					}
				}
				$events[] = array( 'name' => 'purchase', 'params' => array(
					'transaction_id' => (string) $order->get_id(),
					'currency'       => $order->get_currency(),
					'value'          => (float) $order->get_total(),
					'tax'            => (float) $order->get_total_tax(),
					'shipping'       => (float) $order->get_shipping_total(),
					'items'          => $items,
				) );
			}
		}

		if ( empty( $events ) ) {
			return;
		}
		$js = '';
		foreach ( $events as $ev ) {
			$js .= 'gtag("event",' . wp_json_encode( $ev['name'] ) . ',' . wp_json_encode( $ev['params'] ) . ');';
		}
		echo "\n<!-- AIEO GA4 ecommerce events -->\n";
		echo '<script data-cfasync="false">/*aieo-google-tag*/if(typeof gtag==="function"){' . $js . '}</script>' . "\n"; 
	}

	
	public function emit_wishlist_listener() {
		$c = $this->config();
		if ( 'gtag' !== $this->mode( $c ) || '' === $this->ga_id( $c ) ) {
			return;
		}
		if ( 'yes' !== ( isset( $c['ga_send_browser'] ) ? $c['ga_send_browser'] : 'no' ) ) {
			return;
		}
		$cur = function_exists( 'get_woocommerce_currency' ) ? get_woocommerce_currency() : 'EUR';
		$js  = 'if(window.jQuery){jQuery(window).on("aieo_wishlist_updated",function(e,pid,isAdd,itemType){'
			. 'try{if(isAdd&&pid&&(!itemType||"product"===itemType)&&typeof gtag==="function"){'
			. 'gtag("event","add_to_wishlist",{currency:' . wp_json_encode( $cur ) . ',items:[{item_id:String(pid),quantity:1}]});'
			. '}}catch(e){}});}';
		echo "\n<!-- AIEO GA4 add_to_wishlist listener -->\n";
		echo '<script data-cfasync="false">/*aieo-google-tag*/' . $js . '</script>' . "\n"; 
	}

	
	private function ga4_item( $product, $qty = 1 ) {
		if ( ! is_a( $product, 'WC_Product' ) ) {
			return null;
		}
		
		
		
		$item = array(
			'item_id'   => (string) $product->get_id(),
			'item_name' => $product->get_name(),
			'price'     => function_exists( 'wc_get_price_to_display' ) ? round( (float) wc_get_price_to_display( $product ), 2 ) : round( (float) $product->get_price(), 2 ),
			'quantity'  => max( 1, (int) $qty ),
		);
		$cats = function_exists( 'wc_get_product_terms' ) ? wc_get_product_terms( $product->get_id(), 'product_cat', array( 'fields' => 'names' ) ) : array();
		if ( ! empty( $cats ) ) {
			$item['item_category'] = (string) $cats[0];
		}
		return $item;
	}

	
	public function stash_add_to_cart( $cart_item_key, $product_id, $quantity, $variation_id ) {
		unset( $cart_item_key );
		if ( ! function_exists( 'WC' ) || ! WC()->session ) {
			return;
		}
		$pid = $variation_id ? (int) $variation_id : (int) $product_id;
		$it  = $this->ga4_item( function_exists( 'wc_get_product' ) ? wc_get_product( $pid ) : null, $quantity );
		if ( ! $it ) {
			return;
		}
		$pending   = WC()->session->get( 'aieo_ga4_atc', array() );
		$pending   = is_array( $pending ) ? $pending : array();
		$pending[] = $it;
		WC()->session->set( 'aieo_ga4_atc', $pending );
	}
}
