<?php
/**
 * Helper class to log campaign.
 *
 * @package     EDD\Pro\CampaignTracker\Campaigns
 * @copyright   Copyright (c) 2025, Sandhills Development, LLC
 * @license     https://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since       3.6.3
 */

namespace EDD\Pro\CampaignTracker\Campaigns;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore

use EDD\EventManagement\SubscriberInterface;
use EDD\Pro\CampaignTracker\Campaigns\Parser\GoogleAnalytics;

/**
 * Campaign Logger Class.
 *
 * @since 3.6.3
 */
class Logger implements SubscriberInterface {
	use Traits\Order;

	/**
	 * Returns an array of events that this subscriber wants to listen to.
	 *
	 * @since 3.6.3
	 * @return array
	 */
	public static function get_subscribed_events() {
		return array(
			'init'            => 'store_campaign',
			'edd_built_order' => 'add_campaign_order_meta',
		);
	}

	/**
	 * Adds the campaign info to the order meta.
	 *
	 * @since 3.6.3
	 * @param int $order_id The order ID.
	 * @return void
	 */
	public function add_campaign_order_meta( $order_id ) {
		$this->add_meta( $order_id, $this->get_campaign_info() );
	}

	/**
	 * Store campaign information in EDD Session.
	 *
	 * @since 3.6.3
	 * @return void
	 */
	public function store_campaign() {
		// phpcs:disable WordPress.Security.NonceVerification.Recommended
		$campaign_source   = isset( $_GET['utm_source'] ) ? sanitize_text_field( wp_unslash( $_GET['utm_source'] ) ) : '';
		$campaign_campaign = isset( $_GET['utm_campaign'] ) ? sanitize_text_field( wp_unslash( $_GET['utm_campaign'] ) ) : '';
		$campaign_medium   = isset( $_GET['utm_medium'] ) ? sanitize_text_field( wp_unslash( $_GET['utm_medium'] ) ) : '';
		$campaign_term     = isset( $_GET['utm_term'] ) ? sanitize_text_field( wp_unslash( $_GET['utm_term'] ) ) : '';
		$campaign_content  = isset( $_GET['utm_content'] ) ? sanitize_text_field( wp_unslash( $_GET['utm_content'] ) ) : '';
		// phpcs:enable WordPress.Security.NonceVerification.Recommended

		if ( ! empty( $campaign_source ) && ! empty( $campaign_campaign ) && ! empty( $campaign_medium ) ) {
			EDD()->session->set( $this->get_session_id( 'source' ), $campaign_source );
			EDD()->session->set( $this->get_session_id( 'campaign' ), $campaign_campaign );
			EDD()->session->set( $this->get_session_id( 'medium' ), $campaign_medium );
			EDD()->session->set( $this->get_session_id( 'term' ), $campaign_term );
			EDD()->session->set( $this->get_session_id( 'content' ), $campaign_content );
		}
	}

	/**
	 * Gets the campaign info.
	 *
	 * @since 3.6.3
	 * @return array
	 */
	private function get_campaign_info() {
		// Try to get campaign data from Google Analytics cookie first.
		$ga_data = GoogleAnalytics::parse();
		if ( $ga_data ) {
			return array(
				'source'  => trim( $ga_data['source'] ?? '' ),
				'name'    => trim( $ga_data['name'] ?? '' ),
				'medium'  => trim( $ga_data['medium'] ?? '' ),
				'term'    => trim( $ga_data['term'] ?? '' ),
				'content' => trim( $ga_data['content'] ?? '' ),
			);
		}

		// Fall back to session data.
		$campaign_source   = EDD()->session->get( $this->get_session_id( 'source' ) );
		$campaign_campaign = EDD()->session->get( $this->get_session_id( 'campaign' ) );
		$campaign_medium   = EDD()->session->get( $this->get_session_id( 'medium' ) );
		$campaign_term     = EDD()->session->get( $this->get_session_id( 'term' ) );
		$campaign_content  = EDD()->session->get( $this->get_session_id( 'content' ) );

		if ( ! empty( $campaign_source ) && ! empty( $campaign_campaign ) && ! empty( $campaign_medium ) ) {
			return array(
				'source'  => trim( $campaign_source ),
				'name'    => trim( $campaign_campaign ),
				'medium'  => trim( $campaign_medium ),
				'term'    => trim( $campaign_term ?? '' ),
				'content' => trim( $campaign_content ?? '' ),
			);
		}

		return array();
	}

	/**
	 * Returns the unique CT session keys for this EDD installation.
	 *
	 * @since 3.6.3
	 * @param string $type Type of key.
	 * @return string Key identifier for stored sessions.
	 */
	protected function get_session_id( $type = 'campaign' ) {
		return sprintf( 'edd_ct_%1$s_%2$s_id', substr( $this->get_store_id(), 0, 10 ), $type );
	}

	/**
	 * Returns the store ID variable for use in the campaign tracking.
	 *
	 * @since 3.6.3
	 * @return string
	 */
	protected function get_store_id() {
		return md5( home_url() );
	}
}
