<?php
namespace ActirisePublic\Includes;

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

use Actirise\Includes\Helpers;
use Actirise\Includes\Cron;
use Actirise\Includes\Options;

/**
 * This class handles the head script integration
 *
 * @link       https://actirise.com
 * @since      2.0.0
 * @package    actirise
 * @subpackage actirise/public/includes
 * @author     actirise <wordpress@actirise.com>
 */
final class Script {
	/**
	 * The unique identifier of this plugin.
	 *
	 * @since    2.0.0
	 * @access   protected
	 * @var      string    $plugin_name    The string used to uniquely identify this plugin.
	 */

	protected $plugin_name;
	/**
	 * The current version of the plugin.
	 *
	 * @since    2.0.0
	 * @access   protected
	 * @var      string    $version    The current version of the plugin.
	 */
	private $version;

	/**
	 * No pub Class
	 *
	 * @since    2.0.0
	 * @access   private
	 * @var      NoPub    $no_pub    The no pub class.
	 */
	private $no_pub;

	/**
	 * Define the core functionality of the plugin.
	 *
	 * @since    2.0.0
	 * @param    string $plugin_name The name of this plugin.
	 * @param    string $version     The version of this plugin.
	 * @param    NoPub  $no_pub      The no pub class.
	 */
	public function __construct( $plugin_name, $version, $no_pub ) {
		$this->plugin_name = $plugin_name;
		$this->version     = $version;
		$this->no_pub      = $no_pub;

		if ( ACTIRISE_CRON !== 'true' ) {
			$this->update_fastcmp();
		}
	}

	/**
	 * Register all of the hooks related to the public-facing functionality
	 * of the plugin.
	 *
	 * @since    2.0.0
	 * @return void
	 */
	public function head_integration() {
		/** @var string $uuid  */
		$uuid = Options::get( 'settings-uuid', '' );
		/** @var string $type_tag  */
		$type_tag = Options::get( 'settings-uuid-type', 'boot' );
		/** @var string $custom_value1 */
		$custom_value1 = Options::get( 'custom1', 'author_ID' );
		/** @var string $custom_value2 */
		$custom_value2 = Options::get( 'custom2', 'category_0_slug' );
		/** @var string $custom_value3 */
		$custom_value3 = Options::get( 'custom3', 'post_ID' );
		/** @var string $custom_value4 */
		$custom_value4 = Options::get( 'custom4', '' );
		/** @var string $custom_value5 */
		$custom_value5 = Options::get( 'custom5', '' );

		$script_option = version_compare( get_bloginfo( 'version' ), '6.3', '>=' ) ? array(
			'in_footer' => false,
		) : false;

		if ( Options::get( 'fastcmp-enabled', false ) === true ) {
			$fastcmp_options = Helpers::get_fastcmp_options( true );

			if ( $fastcmp_options['privacyPolicy'] !== '' && $fastcmp_options['uuid'] !== '' ) {
				/** @var string $exclude_iab_vendors */
				$exclude_iab_vendors = wp_json_encode( $fastcmp_options['excludedIabVendors'] );
				/** @var string $exclude_google_vendors */
				$exclude_google_vendors = wp_json_encode( $fastcmp_options['excludedGoogleVendors'] );

				$custom_vendor        = '';
				$custom_vendor_string = '';

				if ( count( $fastcmp_options['customsVendor'] ) > 0 ) {
					$custom_vendor_string = '[';

					/** @var object{name: string, id: string} $customs_vendor */
					foreach ( $fastcmp_options['customsVendor'] as $customs_vendor ) {
						$custom_vendor_string .= '{name: "' . esc_attr( $customs_vendor->name ) . '", id: "' . esc_attr( $customs_vendor->id ) . '"},';
					}
					$custom_vendor_string  = substr( $custom_vendor_string, 0, -1 );
					$custom_vendor_string .= ']';

					$custom_vendor .= 'custom: {vendors: ' . $custom_vendor_string . '},';
				}

				$consentModeOptions = '';

				if ( $fastcmp_options['googleTagsStatus'] === true ) {
					$consentModeDefaultOptions = sprintf(
						"{
							ad_storage: '%s',
							analytics_storage: '%s',
							personalization_storage: '%s',
							functionality_storage: '%s',
							security_storage: '%s',
							ad_personalization: '%s',
							ad_user_data: '%s'
						}",
						$fastcmp_options['googleAdStorage'] === true ? 'granted' : 'denied',
						$fastcmp_options['googleAnalyticsStorage'] === true ? 'granted' : 'denied',
						$fastcmp_options['googlePersonalizationStorage'] === true ? 'granted' : 'denied',
						$fastcmp_options['googleFunctionalityStorage'] === true ? 'granted' : 'denied',
						$fastcmp_options['googleSecurityStorage'] === true ? 'granted' : 'denied',
						$fastcmp_options['googleAdPersonalization'] === true ? 'granted' : 'denied',
						$fastcmp_options['googleAdUserData'] === true ? 'granted' : 'denied'
					);

					/** @var string $google_specific_data */
					$google_specific_data = $fastcmp_options['googleSpecificData'];
					if ( $fastcmp_options['googleSpecificEnabled'] === true &&
						! is_wp_error( Helpers::cmp_consent_valid_code( $google_specific_data ) ) &&
						! empty( $google_specific_data )
					) {
						$consentModeOptions = sprintf(
							'default: [
								%s,
								%s
							],',
							$consentModeDefaultOptions,
							$google_specific_data
						);
					} else {
						$consentModeOptions = sprintf(
							'default: %s,',
							$consentModeDefaultOptions
						);
					}
				}

				$consentMode = sprintf(
					'googleConsentMode: {
						enabled: %s,
						%s
					},',
					$fastcmp_options['consentV2'] === true ? 'true' : 'false',
					$consentModeOptions
				);

				$consentMode = preg_replace( '/\s\s+/', '', $consentMode );

				$appearance_json   = $this->build_fastcmp_appearance( $fastcmp_options );
				$appearance_config = $appearance_json !== '' ? 'appearance: ' . $appearance_json . ',' : '';

				$fastcmp_config = sprintf(
					"window.FAST_CMP_OPTIONS = {
					configType: 'actirise-wp',
					domainUid: '%s',
					countryCode: '%s',
					policyUrl: '%s',
					displaySynchronous: false,
					publisherName: '%s',
					bootstrap: {
						excludedIABVendors: %s,
						excludedGoogleVendors: %s,
					},
					jurisdiction: '%s',
					%s
					%s
					%s
					%s
				};",
					esc_js( $fastcmp_options['uuid'] ),
					esc_js( $fastcmp_options['headOffice'] ),
					esc_js( $fastcmp_options['privacyPolicy'] ),
					esc_js( $fastcmp_options['name'] ),
					esc_js( $exclude_iab_vendors ),
					esc_js( $exclude_google_vendors ),
					esc_js( $fastcmp_options['targetedAudience'] ),
					$consentMode,
					$fastcmp_options['logo'] !== '' ? "publisherLogo: function (c) { return c.createElement('img', { src: '" . $fastcmp_options['logo'] . "', height: '40' }) }," : '',
					$custom_vendor,
					$appearance_config
				);

				$stublight = $fastcmp_options['stubLight'];

				$fast_cmp_options_script = array(
					'data-no-optimize'         => '1',
					'data-wpmeteor-nooptimize' => 'true',
					'data-cfasync'             => 'false',
					'nowprocket'               => '',
				);

				if ( defined( 'WP_ROCKET_VERSION' ) === false ) {
					$fast_cmp_options_script['charset'] = 'UTF-8';
				}

				wp_enqueue_script(
					'fastcmp',
					'https://static.fastcmp.com/fast-cmp-stub.js',
					array(),
					'latest',
					$script_option
				);

				wp_add_inline_script( 'fastcmp', $fastcmp_config . "\n" . $stublight, 'before' );

				$fastcmp_options = Helpers::get_fastcmp_options( true );

				$this->add_fastcmp_style( $fastcmp_options );
			}
		}

		$this->add_presized_style();

		if ( $uuid === '' ) {
			return;
		}

		$presized_slots_json = wp_json_encode( $this->get_presized_slot_active() );

		if ( ! is_string( $presized_slots_json ) ) {
			$presized_slots_json = '[]';
		}

		$no_pub = ! $this->no_pub->ads_enabled() ? 'no_pub: true,' : '';

		wp_enqueue_script(
			'actirise',
			ACTIRISE_URL_FLASHBID . esc_js( $type_tag ) . '/' . esc_js( $uuid ) . '.js',
			array(),
			'latest',
			$script_option
		);

		$data_var = sprintf(
			"window._hbdbrk=window._hbdbrk||[];window._hbdbrk.push(['_vars', {page_type:'%s',pid:3,custom1:'%s',custom2:'%s',custom3:'%s',custom4:'%s',custom5:'%s',%s}]);",
			esc_attr( Helpers::get_page_type() ),
			esc_attr( Helpers::get_custom_value( $custom_value1, 'custom1' ) ),
			esc_attr( Helpers::get_custom_value( $custom_value2, 'custom2' ) ),
			esc_attr( Helpers::get_custom_value( $custom_value3, 'custom3' ) ),
			esc_attr( Helpers::get_custom_value( $custom_value4, 'custom4' ) ),
			esc_attr( Helpers::get_custom_value( $custom_value5, 'custom5' ) ),
			esc_attr( $no_pub )
		);

		/** @var string $adstxt_active */
		$adstxt_active = Options::get( 'adstxt-active', false ) ? '1' : '0';
		/** @var string $presizeddiv_active */
		$presizeddiv_active = Options::get( 'presizeddiv-active', false ) ? '1' : '0';
		/** @var string $adstxt_last_update */
		$adstxt_last_update = Options::get( 'adstxt-lastupdate', '-1' );
		/** @var string $presizeddiv_last_update */
		$presizeddiv_last_update = Options::get( 'presizeddiv-lastupdate', '-1' );
		/** @var string $presizeddiv_last_update */
		$version_lastupdate = Options::get( 'version-lastupdate', '-1' );

		$actirise_plugin = sprintf(
			"window.actirisePlugin=window.actirisePlugin||{};window.actirisePlugin.version='%s';window.actirisePlugin.version_lastupdate=%s;window.actirisePlugin.adsTxt={active:%s,lastUpdate:%s};window.actirisePlugin.presized={active:%s,lastUpdate:%s,slots:%s};window.actirisePlugin.cron=%s;window.actirisePlugin.fastcmp=%s;window.actirisePlugin.autoUpdate=%s;window.actirisePlugin.debug=%s;",
			esc_attr( $this->version ),
			esc_attr( $version_lastupdate === '-1' ? '-1' : 'new Date(' . $version_lastupdate . ' * 1000)' ),
			esc_attr( $adstxt_active ),
			esc_attr( $adstxt_last_update === '-1' ? '-1' : 'new Date(' . $adstxt_last_update . ' * 1000)' ),
			esc_attr( $presizeddiv_active ),
			esc_attr( $presizeddiv_last_update === '-1' ? '-1' : 'new Date(' . $presizeddiv_last_update . ' * 1000)' ),
			$presized_slots_json,
			esc_attr( ( defined( 'ACTIRISE_CRON' ) && ACTIRISE_CRON === 'true' ) === true ? 'true' : 'false' ),
			esc_attr( Options::get( 'fastcmp-enabled', false ) === true ? 'true' : 'false' ),
			esc_attr( Helpers::has_auto_update() ? 'true' : 'false' ),
			esc_attr( Options::get( 'debug-enabled', false ) === true ? 'true' : 'false' )
		);

		wp_add_inline_script( 'actirise', $data_var . "\n" . $actirise_plugin, 'after' );
	}

	/**
	 * Change js attribute.
	 *
	 * @since 2.5.7
	 * @param string $tag The tag.
	 * @param string $handle The handle.
	 * @return string
	 */
	public function change_js_attribute( $tag, $handle ) {
		if ( 'actirise' === $handle ) {
			/** @var string $tag */
			$tag = preg_replace( '#\sid=([\'"])actirise-js([\'"])#', '', $tag );
			/** @var string $tag */
			$tag = str_replace( 'src=', 'data-cfasync="false" defer src=', $tag );
			/** @var string $tag */
			$tag = preg_replace( '#\sid=([\'"])actirise-js-after([\'"])#', '', $tag );
			/** @var string $tag */
			$tag = preg_replace( '/\?ver=[0-9.a-z]+/', '', $tag );
		}

		if ( 'fastcmp' === $handle ) {
			/** @var string $tag */
			$tag = preg_replace( '#\sid=([\'"])fastcmp-js-before([\'"])#', ' data-no-optimize="1" data-wpmeteor-nooptimize="true" data-cfasync="false" nowprocket="" charset="UTF-8"', $tag );
			/** @var string $tag */
			$tag = str_replace( 'src=', 'async data-no-optimize="1" data-wpmeteor-nooptimize="true" data-cfasync="false" nowprocket="" charset="UTF-8" src=', $tag );
			/** @var string $tag */
			$tag = preg_replace( '#\sid=([\'"])fastcmp-js([\'"])#', '', $tag );
			/** @var string $tag */
			$tag = preg_replace( '/\?ver=[0-9.a-z]+/', '', $tag );
		}

		return $tag;
	}

	/**
	 * Add custom CSS style for FastCMP.
	 *
	 * Button styles are now handled via the appearance attribute in FAST_CMP_OPTIONS.
	 * This method only injects user-provided custom CSS overrides.
	 *
	 * @since 2.4.0
	 * @param array{customStyle: string} $fastcmp_options The fastcmp options.
	 * @return void
	 */
	public function add_fastcmp_style( $fastcmp_options ) {
		$custom_style = preg_replace( '/\s\s+/', '', $fastcmp_options['customStyle'] );

		if ( is_null( $custom_style ) || $custom_style === '' ) {
			return;
		}

		wp_register_style( 'fast-cmp-custom-styles', false, array(), $this->version );
		wp_enqueue_style( 'fast-cmp-custom-styles' );
		wp_add_inline_style( 'fast-cmp-custom-styles', trim( $custom_style ) );
	}

	/**
	 * Inject CSS for Presized Div
	 *
	 * @since    3.2.0
	 *
	 * @return void
	 */
	public function add_presized_style() {
		$version = intval( time() / 3600 );

		wp_register_style( 'actirise-presized', false, array(), strval( $version ) );
		wp_enqueue_style( 'actirise-presized', '', array(), strval( $version ) );

		/** @var array<string> $css_code */
		$css_code = array();
		/** @var array<array{cssCode: string}> $slots */
		$slots = Options::get( 'presizeddiv-actirise', array() );

		foreach ( $slots as $slot ) {
			$css_code[] = $slot['cssCode'];
		}

		$clear_css = array_map(
			function ( $css ) {
				/** @var string $css */
				return str_replace( array( '<style type="text/css">', '</style>' ), '', $css );
			},
			$css_code
		);

		$css = implode( '', $clear_css );

		wp_add_inline_style( 'actirise-presized', $css );
	}

	/**
	 * Get presized slot active.
	 *
	 * @since 2.0.0
	 * @return array<array{slotName: string, active: bool}>
	 */
	private function get_presized_slot_active() {
		/** @var array<array{slotName: string, active: bool}> $presized_div_selected */
		$presized_div_selected = Options::get( 'presizeddiv-selected', array() );

		if ( ! is_array( $presized_div_selected ) ) {
			return array();
		}

		return $presized_div_selected;
	}

	/**
	 * Build the FastCMP appearance theme object from button style settings.
	 *
	 * Maps acceptButtonStyle → primary, declineButtonStyle → secondary,
	 * parametersButtonStyle → tertiary in the FastCMP appearance.theme.colors structure.
	 *
	 * @since 4.1.2
	 * @param array{acceptButtonStyle: array{bg: string, font: string}, declineButtonStyle: array{bg: string, font: string, border: string}, parametersButtonStyle: array{bg: string, font: string, border: string}} $fastcmp_options The fastcmp options.
	 * @return string JSON-encoded appearance object, or empty string if no colors are customized.
	 */
	private function build_fastcmp_appearance( $fastcmp_options ) {
		$text_colors   = array();
		$bg_colors     = array();
		$border_colors = array();

		$accept  = $fastcmp_options['acceptButtonStyle'];
		$decline = $fastcmp_options['declineButtonStyle'];
		$params  = $fastcmp_options['parametersButtonStyle'];

		// Accept button → primary
		if ( $accept['bg'] !== '' ) {
			$bg_colors['primary']       = $accept['bg'];
			$bg_colors['primaryHover']  = $accept['bg'];
			$bg_colors['primaryActive'] = $accept['bg'];
			$border_colors['primary']   = $accept['bg'] === 'transparent' ? '#6f6f6f' : $accept['bg'];
		}
		if ( $accept['font'] !== '' ) {
			$text_colors['onPrimary']       = $accept['font'];
			$text_colors['onPrimaryHover']  = $accept['font'];
			$text_colors['onPrimaryActive'] = $accept['font'];
		}

		// Decline button → secondary
		if ( $decline['bg'] !== '' ) {
			$bg_colors['secondary']       = $decline['bg'];
			$bg_colors['secondaryHover']  = $decline['bg'];
			$bg_colors['secondaryActive'] = $decline['bg'];
		}
		if ( $decline['font'] !== '' ) {
			$text_colors['onSecondary']       = $decline['font'];
			$text_colors['onSecondaryHover']  = $decline['font'];
			$text_colors['onSecondaryActive'] = $decline['font'];
			$border_colors['secondary']       = $decline['font'];
		}

		// Parameters button → tertiary
		if ( $params['bg'] !== '' ) {
			$bg_colors['tertiary']       = $params['bg'];
			$bg_colors['tertiaryHover']  = $params['bg'];
			$bg_colors['tertiaryActive'] = $params['bg'];
		}
		if ( $params['font'] !== '' ) {
			$text_colors['onTertiary']       = $params['font'];
			$text_colors['onTertiaryHover']  = $params['font'];
			$text_colors['onTertiaryActive'] = $params['font'];
			$border_colors['tertiary']       = $params['font'];
			$border_colors['tertiaryHover']  = $params['font'];
			$border_colors['tertiaryActive'] = $params['font'];
		}
		if ( $params['border'] !== '' ) {
			$border_colors['tertiaryHover']  = $params['border'];
			$border_colors['tertiaryActive'] = $params['border'];
		}

		$colors = array();
		if ( ! empty( $text_colors ) ) {
			$colors['text'] = $text_colors;
		}
		if ( ! empty( $bg_colors ) ) {
			$colors['background'] = $bg_colors;
		}
		if ( ! empty( $border_colors ) ) {
			$colors['border'] = $border_colors;
		}

		if ( empty( $colors ) ) {
			return '';
		}

		/** @var string $json */
		$json = wp_json_encode(
			array(
				'theme' => array(
					'colors' => $colors,
				),
			)
		);

		return $json;
	}

	/**
	 * Update fastcmp.
	 *
	 * @since 2.2.0
	 * @return void
	 */
	private function update_fastcmp() {
		$cron = new Cron();
		$cron->check_scheduled_task_with_transient(
			'get_fast_cmp',
			array(
				$cron,
				'get_fast_cmp',
			)
		);
	}
}
