<?php
/**
 * Google Tag Manager Module.
 *
 * Injects the GTM container the correct way — script high in <head> (priority
 * 2, before our own schema at 5), no-script fallback right after <body> opens.
 * A lean alternative to a dedicated GTM plugin. Off by default; turn on after
 * entering a container ID and removing any existing GTM injection.
 *
 * @package Platform\Helm\Modules\Gtm
 */

declare( strict_types = 1 );

namespace Platform\Helm\Modules\Gtm;

use Platform\Helm\Contracts\ModuleInterface;
use Platform\Helm\Core\Assets;

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

final class GtmModule implements ModuleInterface {

	private GtmSettingsPage $settings;

	public function __construct( Assets $assets ) {
		unset( $assets ); // No asset bundle; inline output only.
		$this->settings = new GtmSettingsPage();
	}

	public function id(): string {
		return 'gtm';
	}

	public function name(): string {
		return __( 'Google Tag Manager', 'platform-helm' );
	}

	public function description(): string {
		return __( 'Injects your GTM container correctly — script high in the head, no-script after the body opens. Lightweight alternative to a GTM plugin. Off by default; remove any existing GTM injection before enabling.', 'platform-helm' );
	}

	public function default_enabled(): bool {
		return false;
	}

	public function boot(): void {
		$this->settings->register_hooks();

		if ( '' !== GtmSettingsPage::container_id() ) {
			add_action( 'wp_head', [ $this, 'print_head' ], 2 );
			add_action( 'wp_body_open', [ $this, 'print_body' ] );
		}
	}

	public function print_head(): void {
		$id = GtmSettingsPage::container_id();
		if ( '' === $id ) {
			return;
		}

		if ( GtmSettingsPage::datalayer_enabled() ) {
			$dl = $this->data_layer();
			echo "<script>window.dataLayer = window.dataLayer || [];";
			if ( ! empty( $dl ) ) {
				echo 'window.dataLayer.push(' . wp_json_encode( $dl ) . ');';
			}
			echo "</script>\n";
		}

		// Standard GTM snippet; container ID is strictly validated (GTM-XXXXXX).
		echo "<!-- Google Tag Manager (Platform Helm) -->\n";
		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo "<script>(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','" . esc_js( $id ) . "');</script>\n";
		echo "<!-- End Google Tag Manager -->\n";
	}

	public function print_body(): void {
		$id = GtmSettingsPage::container_id();
		if ( '' === $id ) {
			return;
		}
		echo "<!-- Google Tag Manager (noscript) -->\n";
		echo '<noscript><iframe src="' . esc_url( 'https://www.googletagmanager.com/ns.html?id=' . $id ) . '" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>' . "\n";
		echo "<!-- End Google Tag Manager (noscript) -->\n";
	}

	/**
	 * A light, cheap dataLayer pushed before GTM loads.
	 *
	 * @return array<string,string>
	 */
	private function data_layer(): array {
		$dl = [ 'loggedIn' => is_user_logged_in() ? 'yes' : 'no' ];

		if ( is_front_page() ) {
			$dl['pageType'] = 'home';
		} elseif ( is_singular() ) {
			$dl['pageType'] = 'single';
			$dl['postType'] = (string) get_post_type();
		} elseif ( is_archive() ) {
			$dl['pageType'] = 'archive';
		} elseif ( is_search() ) {
			$dl['pageType'] = 'search';
		}

		/**
		 * Filter the GTM dataLayer values.
		 *
		 * @param array<string,string> $dl
		 */
		return (array) apply_filters( 'platform_helm_gtm_datalayer', $dl );
	}
}
