<?php
/**
 * Frontend events tracking.
 *
 * @since 6.0.0
 *
 * @package MonsterInsights
 * @author  Chris Christoff
 */

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

// Clear snoozed notifications on login.
// Registered here (frontend) because the notifications class file is only
// loaded inside is_admin(), but wp_login fires on the frontend login form.
add_action( 'wp_login', 'monsterinsights_clear_snoozed_on_login', 10, 2 );

/**
 * Clear snoozed notifications when a user logs in.
 *
 * @param string   $user_login Username.
 * @param \WP_User $user       WP_User object.
 */
function monsterinsights_clear_snoozed_on_login( $user_login, $user ) {
	delete_user_meta( $user->ID, 'monsterinsights_notifications_snoozed' );
}

/**
 * Check if we are in an AMP context
 *
 * @return bool
 * @since 8.0.0
 */
function monsterinsights_is_amp() {
	// Check for AMP plugin
	if ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() ) {
		return true;
	}

	// Check for AMP theme
	if ( function_exists( 'amp_is_request' ) && amp_is_request() ) {
		return true;
	}

	// Check for AMP query parameter
	if ( isset( $_GET['amp'] ) && '1' === $_GET['amp'] ) {
		return true;
	}

	// Check for AMP in URL path
	if ( isset( $_SERVER['REQUEST_URI'] ) && false !== strpos( $_SERVER['REQUEST_URI'], '/amp/' ) ) {
		return true;
	}

	// Check for AMP in theme
	if ( function_exists( 'amp_is_canonical' ) && amp_is_canonical() ) {
		return true;
	}

	return false;
}

/**
 * Print Monsterinsights frontend tracking script.
 *
 * @return void
 * @since 7.0.0
 * @access public
 */
function monsterinsights_tracking_script() {
	// Check if we're in AMP context - if so, don't output any scripts
	if ( monsterinsights_is_amp() ) {
		return;
	}

	if ( monsterinsights_skip_tracking() ) {
		return;
	}

	require_once plugin_dir_path( MONSTERINSIGHTS_PLUGIN_FILE ) . 'includes/frontend/class-tracking-abstract.php';

	$mode = is_preview() ? 'preview' : MonsterInsights()->get_tracking_mode();

	do_action( 'monsterinsights_tracking_before_' . $mode );
	do_action( 'monsterinsights_tracking_before', $mode );
	if ( 'preview' === $mode ) {
		require_once plugin_dir_path( MONSTERINSIGHTS_PLUGIN_FILE ) . 'includes/frontend/tracking/class-tracking-preview.php';
		$tracking = new MonsterInsights_Tracking_Preview();
		// Escaped in frontend_output function
		echo $tracking->frontend_output(); // phpcs:ignore
	} else {
		require_once plugin_dir_path( MONSTERINSIGHTS_PLUGIN_FILE ) . 'includes/frontend/tracking/class-tracking-gtag.php';
		$tracking = new MonsterInsights_Tracking_Gtag();
		// Escaped in frontend_output function
		echo $tracking->frontend_output(); // phpcs:ignore
	}

	do_action( 'monsterinsights_tracking_after_' . $mode );
	do_action( 'monsterinsights_tracking_after', $mode );
}

add_action( 'wp_head', 'monsterinsights_tracking_script', 6 );
// add_action( 'login_head', 'monsterinsights_tracking_script', 6 );

/**
 * Get frontend tracking options.
 *
 * This function is used to return an array of parameters
 * for the frontend_output() function to output. These are
 * generally dimensions and turned on GA features.
 *
 * @return array Array of the options to use.
 * @since 6.0.0
 * @access public
 */
function monsterinsights_events_tracking() {
	if ( monsterinsights_skip_tracking() ) {
		return;
	}

	$track_user = monsterinsights_track_user();

	if ( $track_user ) {
		require_once plugin_dir_path( MONSTERINSIGHTS_PLUGIN_FILE ) . 'includes/frontend/events/class-gtag-events.php';
		new MonsterInsights_Gtag_Events();
	} else {
		// User is in the disabled group or events mode is off
	}
}

add_action( 'template_redirect', 'monsterinsights_events_tracking', 9 );

/**
 * Add the UTM source parameters in the RSS feeds to track traffic.
 *
 * @param string $guid The link for the RSS feed.
 *
 * @return string The new link for the RSS feed.
 * @since 6.0.0
 * @access public
 */
function monsterinsights_rss_link_tagger( $guid ) {
	global $post;

	if (
		monsterinsights_get_option( 'tag_links_in_rss', false )
		&& is_feed()
		&& ! empty( $post->post_name )
	) {
		if ( monsterinsights_get_option( 'allow_anchor', false ) ) {
			$delimiter = '#';
		} else {
			$delimiter = '?';
			if ( strpos( $guid, $delimiter ) > 0 ) {
				$delimiter = '&amp;';
			}
		}

		return $guid . $delimiter . 'utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=' . urlencode( $post->post_name );
	}

	return $guid;
}

add_filter( 'the_permalink_rss', 'monsterinsights_rss_link_tagger', 99 );


/**
 * Checks used for loading the frontend scripts/admin bar button.
 */
function monsterinsights_prevent_loading_frontend_reports() {
	return ! current_user_can( 'monsterinsights_view_dashboard' ) || monsterinsights_get_option( 'hide_admin_bar_reports' );
}

/**
 * Whether the built React admin bar bundle exists on disk.
 *
 * The top-level "Insights" admin bar button is interactive only when the
 * React app is enqueued and mounts. If the bundle is missing (e.g. a
 * release packaging gap), the rendered link has no click handler and
 * appears broken to users. This helper lets callers gate on availability.
 *
 * @return bool
 */
function monsterinsights_admin_bar_assets_available() {
	$version    = monsterinsights_is_pro_version() ? 'pro' : 'lite';
	$asset_file = MONSTERINSIGHTS_PLUGIN_DIR . "{$version}/assets/admin-bar/index.asset.php";

	return file_exists( $asset_file );
}

/**
 * Add an admin bar menu item on the frontend.
 *
 * @return void
 * @since 7.5.0
 */
function monsterinsights_add_admin_bar_menu() {
	if ( monsterinsights_prevent_loading_frontend_reports() ) {
		return;
	}

	// If the React admin bar bundle is missing, skip adding the button —
	// otherwise it renders as an inert link and looks broken. The
	// "Insights" entry under wp-logo (see em-admin.php) still works.
	if ( ! monsterinsights_admin_bar_assets_available() ) {
		return;
	}

	global $wp_admin_bar;

	// Fallback href so the button degrades to navigation if the React
	// app fails to mount for any reason (JS error, CSP, extension).
	$reports_url = is_network_admin()
		? add_query_arg( 'page', 'monsterinsights_overview_report', network_admin_url( 'admin.php' ) )
		: add_query_arg( 'page', 'monsterinsights_reports', admin_url( 'admin.php' ) );

	$args = array(
		'id'    => 'monsterinsights_frontend_button',
		'title' => '<span class="ab-icon dashicons-before dashicons-chart-bar"></span> Insights',
		// Maybe allow translation?
		'href'  => $reports_url,
	);

	if ( method_exists( $wp_admin_bar, 'add_menu' ) ) {
		$wp_admin_bar->add_menu( $args );
	}
}

add_action( 'admin_bar_menu', 'monsterinsights_add_admin_bar_menu', 999 );

/**
 * Load the scripts needed for the admin bar.
 *
 * @return void
 * @since 7.5.0
 */
function monsterinsights_frontend_admin_bar_scripts() {
	global $current_user;
	global $pagenow;
	if ( monsterinsights_prevent_loading_frontend_reports() ) {
		return;
	}

	// Avoid loading scripts on pages that don't have admin bar such as WPBakery Page Builder.
	if (isset($_GET['vc_editable']) && isset($_GET['vc_post_id']) && $_GET['vc_editable'] === 'true') {
		return;
	}

	// Avoid adding admin bar scripts in Elementor's preview which is done via admin-ajax(where $pagenow = 'index.php')
	if ($pagenow === 'index.php' && isset($_GET['elementor-preview'])) {
		return;
	}

	// React-based admin bar implementation
	$version = monsterinsights_is_pro_version() ? 'pro' : 'lite';
	$asset_file = MONSTERINSIGHTS_PLUGIN_DIR . "{$version}/assets/admin-bar/index.asset.php";

	if ( ! monsterinsights_admin_bar_assets_available() ) {
		return;
	}

	// phpcs:ignore PHPCS_SecurityAudit.Misc.IncludeMismatch.ErrMiscIncludeMismatchNoExt -- File path is validated with file_exists() above.
	$asset_data = require $asset_file;

	// Enqueue styles
	wp_enqueue_style(
		'monsterinsights-admin-bar',
		plugins_url("{$version}/assets/admin-bar/insights.css", MONSTERINSIGHTS_PLUGIN_FILE),
		array('wp-components'),
		$asset_data['version']
	);

	// Ensure wp-util is loaded (provides wp.ajax)
	wp_enqueue_script('wp-util');

	// Enqueue script
	wp_enqueue_script(
		'monsterinsights-admin-bar',
		plugins_url("{$version}/assets/admin-bar/index.js", MONSTERINSIGHTS_PLUGIN_FILE),
		$asset_data['dependencies'],
		$asset_data['version'],
		true
	);

	// Set script translations for the admin bar app
	$textdomain = monsterinsights_is_pro_version() ? 'google-analytics-premium' : 'google-analytics-for-wordpress';
	wp_set_script_translations(
		'monsterinsights-admin-bar',
		$textdomain,
		plugin_dir_path( MONSTERINSIGHTS_PLUGIN_FILE ) . $version . '/languages'
	);

	// Skip localizing the shared `monsterinsights` global if another MI app already owns it —
	// otherwise this admin-bar payload would clobber config like relay_api_url / license / reporting_api.
	$competing_handles = array(
		'monsterinsights-vue-script',
		'monsterinsights-vue-reports',
		'monsterinsights-vue-widget',
		'monsterinsights-vue3-custom-dashboard',
		'monsterinsights-vue3-reports',
	);

	foreach ( $competing_handles as $handle ) {
		if ( wp_script_is( $handle ) ) {
			return;
		}
	}

	// Localize data (same structure as Vue version for compatibility)
	$page_title  = is_singular() ? get_the_title() : monsterinsights_get_page_title();
	$site_auth   = MonsterInsights()->auth->get_viewname();
	$ms_auth     = is_multisite() && MonsterInsights()->auth->get_network_viewname();
	$reports_url = is_network_admin() ? add_query_arg( 'page', 'monsterinsights_overview_report', network_admin_url( 'admin.php' ) ) : add_query_arg( 'page', 'monsterinsights_reports', admin_url( 'admin.php' ) );
	wp_localize_script(
		'monsterinsights-admin-bar',
		'monsterinsights',
		array(
			'ajax'                 => admin_url( 'admin-ajax.php' ),
			'nonce'                => wp_create_nonce( 'mi-admin-nonce' ),
			'network'              => is_network_admin(),
			'assets'               => plugins_url( $version . '/assets/admin-bar', MONSTERINSIGHTS_PLUGIN_FILE ),
			'addons_url'           => is_multisite() ? network_admin_url( 'admin.php?page=monsterinsights_network#/addons' ) : admin_url( 'admin.php?page=monsterinsights_settings#/addons' ),
			'page_id'              => is_singular() ? get_the_ID() : false,
			'page_title'           => $page_title,
			'plugin_version'       => MONSTERINSIGHTS_VERSION,
			'shareasale_id'        => monsterinsights_get_shareasale_id(),
			'shareasale_url'       => monsterinsights_get_shareasale_url( monsterinsights_get_shareasale_id(), '' ),
			'is_admin'             => is_admin(),
			'reports_url'          => $reports_url,
			'authed'               => $site_auth || $ms_auth,
			'auth_connect_url'     => is_network_admin() ? network_admin_url( 'index.php?page=monsterinsights-onboarding' ) : admin_url( 'index.php?page=monsterinsights-onboarding' ),
			'getting_started_url'  => is_multisite() ? network_admin_url( 'admin.php?page=monsterinsights_network#/about/getting-started' ) : admin_url( 'admin.php?page=monsterinsights_settings#/about/getting-started' ),
			'wizard_url'           => is_network_admin() ? network_admin_url( 'index.php?page=monsterinsights-onboarding' ) : admin_url( 'index.php?page=monsterinsights-onboarding' ),
			'roles_manage_options' => monsterinsights_get_manage_options_roles(),
			'user_roles'           => $current_user->roles,
			'roles_view_reports'   => monsterinsights_get_option('view_reports'),
		)
	);
}

add_action( 'wp_enqueue_scripts', 'monsterinsights_frontend_admin_bar_scripts' );
add_action( 'admin_enqueue_scripts', 'monsterinsights_frontend_admin_bar_scripts', 1005 );


/**
 * Load the tracking notice for logged in users.
 */
function monsterinsights_administrator_tracking_notice() {
	// Don't do anything for guests.
	if ( ! is_user_logged_in() ) {
		return;
	}

	// Only show this to users who are not tracked.
	if ( monsterinsights_track_user() ) {
		return;
	}

	// Only show when tracking.
	$tracking_tag = monsterinsights_get_v4_id();
	if ( empty( $tracking_tag ) ) {
		return;
	}

	// Don't show if already dismissed.
	if ( get_option( 'monsterinsights_frontend_tracking_notice_viewed', false ) ) {
		return;
	}

	// Automatically dismiss when loaded.
	update_option( 'monsterinsights_frontend_tracking_notice_viewed', 1 );

	?>
<div class="monsterinsights-tracking-notice monsterinsights-tracking-notice-hide">
	<div class="monsterinsights-tracking-notice-icon">
		<img src="<?php echo esc_url( plugins_url( 'assets/images/mascot.png', MONSTERINSIGHTS_PLUGIN_FILE ) ); ?>"
			width="40" alt="MonsterInsights Mascot" />
	</div>
	<div class="monsterinsights-tracking-notice-text">
		<h3><?php esc_html_e( 'Tracking is Disabled for Administrators', 'google-analytics-for-wordpress' ); ?></h3>
		<p>
			<?php
				$doc_url = 'https://monsterinsights.com/docs/tracking-disabled-administrators-editors';
				$doc_url = add_query_arg(
					array(
						'utm_source'   => monsterinsights_is_pro_version() ? 'proplugin' : 'liteplugin',
						'utm_medium'   => 'frontend-notice',
						'utm_campaign' => 'admin-tracking-doc',
					),
					$doc_url
				);
				// Translators: %s is the link to the article where more details about tracking are listed.
				printf( esc_html__( 'To keep stats accurate, we do not load Google Analytics scripts for admin users. %1$sLearn More &raquo;%2$s', 'google-analytics-for-wordpress' ), '<a href="' . esc_url( $doc_url ) . '" target="_blank">', '</a>' );
			?>
		</p>
	</div>
	<div class="monsterinsights-tracking-notice-close">&times;</div>
</div>
<style type="text/css">
.monsterinsights-tracking-notice {
	position: fixed;
	bottom: 20px;
	right: 15px;
	font-family: Arial, Helvetica, "Trebuchet MS", sans-serif;
	background: #fff;
	box-shadow: 0 0 10px 0 #dedede;
	padding: 6px 5px;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 380px;
	max-width: calc(100% - 30px);
	border-radius: 6px;
	transition: bottom 700ms ease;
	z-index: 10000;
}

.monsterinsights-tracking-notice h3 {
	font-size: 13px;
	color: #222;
	font-weight: 700;
	margin: 0 0 8px;
	padding: 0;
	line-height: 1;
	border: none;
}

.monsterinsights-tracking-notice p {
	font-size: 13px;
	color: #7f7f7f;
	font-weight: 400;
	margin: 0;
	padding: 0;
	line-height: 1.2;
	border: none;
}

.monsterinsights-tracking-notice p a {
	color: #7f7f7f;
	font-size: 13px;
	line-height: 1.2;
	margin: 0;
	padding: 0;
	text-decoration: underline;
	font-weight: 400;
}

.monsterinsights-tracking-notice p a:hover {
	color: #7f7f7f;
	text-decoration: none;
}

.monsterinsights-tracking-notice-icon img {
	height: auto;
	display: block;
	margin: 0;
}

.monsterinsights-tracking-notice-icon {
	padding: 14px;
	background-color: #f2f6ff;
	border-radius: 6px;
	flex-grow: 0;
	flex-shrink: 0;
	margin-right: 12px;
}

.monsterinsights-tracking-notice-close {
	padding: 0;
	margin: 0 3px 0 0;
	border: none;
	box-shadow: none;
	border-radius: 0;
	color: #7f7f7f;
	background: transparent;
	line-height: 1;
	align-self: flex-start;
	cursor: pointer;
	font-weight: 400;
}

.monsterinsights-tracking-notice.monsterinsights-tracking-notice-hide {
	bottom: -200px;
}
</style>
<?php

	if ( ! wp_script_is( 'jquery', 'queue' ) ) {
		wp_enqueue_script( 'jquery' );
	}
	?>
<script>
if ('undefined' !== typeof jQuery) {
	jQuery(document).ready(function($) {
		/* Don't show the notice if we don't have a way to hide it (no js, no jQuery). */
		$(document.querySelector('.monsterinsights-tracking-notice')).removeClass(
			'monsterinsights-tracking-notice-hide');
		$(document.querySelector('.monsterinsights-tracking-notice-close')).on('click', function(e) {
			e.preventDefault();
			$(this).closest('.monsterinsights-tracking-notice').addClass(
				'monsterinsights-tracking-notice-hide');
			$.ajax({
				url: '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>',
				method: 'POST',
				data: {
					action: 'monsterinsights_dismiss_tracking_notice',
					nonce: '<?php echo esc_js( wp_create_nonce( 'monsterinsights-tracking-notice' ) ); ?>',
				}
			});
		});
	});
}
</script>
<?php
}

add_action( 'wp_footer', 'monsterinsights_administrator_tracking_notice', 300 );

/**
 * Ajax handler to hide the tracking notice.
 */
function monsterinsights_dismiss_tracking_notice() {

	check_ajax_referer( 'monsterinsights-tracking-notice', 'nonce' );

	update_option( 'monsterinsights_frontend_tracking_notice_viewed', 1 );

	wp_die();

}

add_action( 'wp_ajax_monsterinsights_dismiss_tracking_notice', 'monsterinsights_dismiss_tracking_notice' );

/**
 * If the legacy shortcodes are not registered, make sure they don't output.
 */
function monsterinsights_maybe_handle_legacy_shortcodes() {

	if ( ! shortcode_exists( 'gadwp_useroptout' ) ) {
		add_shortcode( 'gadwp_useroptout', '__return_empty_string' );
	}

}

add_action( 'init', 'monsterinsights_maybe_handle_legacy_shortcodes', 1000 );

/**
 * Remove Query String from a Vue Settings before sending the data to GA.
 *
 * @return void
 */
function monsterinsights_exclude_query_params_v4() {
	global $wp;

	if ( ! monsterinsights_get_option( 'exclude_query_params', false ) ) {
		return;
	}

	$current_page_url = add_query_arg( !empty($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : '', '', trailingslashit( home_url( $wp->request ) ) ); // phpcs:ignore
	$query_options    = monsterinsights_get_option( 'exclude_query_params_options', false );
	$pg_options       = $query_options ? explode( ',', $query_options ) : array();

	if ( is_array( $pg_options ) && empty( $pg_options ) ) {
		return;
	}

	$filtered_options                  = array();
	$filtered_url                      = remove_query_arg( $pg_options, $current_page_url );
	$filtered_options['page_location'] = $filtered_url;

	if ( wp_get_referer() ) {
		$filtered_page_ref_url             = remove_query_arg( $pg_options, wp_get_referer() );
		$filtered_options['page_referrer'] = $filtered_page_ref_url;
	}

	printf( "var MonsterInsightsExcludeQuery = %s;\n", wp_json_encode( $filtered_options ) );
}

add_action( 'monsterinsights_tracking_gtag_frontend_output_after_mi_track_user', 'monsterinsights_exclude_query_params_v4' );
