<?php

if( !defined( 'MAP_PLUGIN_NAME' ) )
{
	exit('Not allowed.');
}


/**
 * My Agile Privacy core renderer.
 *
 *
 * @package    MyAgilePrivacy
 * @subpackage MyAgilePrivacy/includes
 * @author     https://www.myagileprivacy.com/
 */

/**
 * Renderer class for the My Agile Privacy notification banner and cookie settings modal.
 */
if( !class_exists( 'MyAgilePrivacyBannerRenderer' ) )
{
	final class MyAgilePrivacyBannerRenderer
	{
		/** @var array */
		private $the_settings;

		/** @var array */
		private $rconfig;

		/** @var array */
		private $the_translations;

		/** @var string */
		private $current_lang;

		/** @var bool */
		private $is_polylang_enabled;

		/** @var bool */
		private $is_wpml_enabled;

		/** @var array|null */
		private $clarity_consent_mode_consents;

		/** @var array|null */
		private $microsoft_consent_mode_consents;

		/** @var array|null */
		private $consent_mode_consents;

		/** @var MyAgilePrivacyFrontend */
		private $frontend;

		/**
		 * Lazy-loaded cache for cookie categories data.
		 * Populated on first call to get_cookies_categories_data().
		 *
		 * @var array|null
		 */
		private $cookies_categories_data = null;

		/**
		 * @param array                  $the_settings
		 * @param array                  $rconfig
		 * @param array                  $the_translations
		 * @param string                 $current_lang
		 * @param bool                   $is_polylang_enabled
		 * @param bool                   $is_wpml_enabled
		 * @param array|null             $clarity_consent_mode_consents
		 * @param array|null             $microsoft_consent_mode_consents
		 * @param array|null             $consent_mode_consents
		 * @param MyAgilePrivacyFrontend $frontend
		 */
		public function __construct(
			$the_settings,
			$rconfig,
			$the_translations,
			$current_lang,
			$is_polylang_enabled,
			$is_wpml_enabled,
			$clarity_consent_mode_consents,
			$microsoft_consent_mode_consents,
			$consent_mode_consents,
			$frontend
		)
		{
			$this->the_settings                    = $the_settings;
			$this->rconfig                         = $rconfig;
			$this->the_translations                = $the_translations;
			$this->current_lang                    = $current_lang;
			$this->is_polylang_enabled             = $is_polylang_enabled;
			$this->is_wpml_enabled                 = $is_wpml_enabled;
			$this->clarity_consent_mode_consents   = $clarity_consent_mode_consents;
			$this->microsoft_consent_mode_consents = $microsoft_consent_mode_consents;
			$this->consent_mode_consents           = $consent_mode_consents;
			$this->frontend                        = $frontend;
		}

		/**
		 * Returns the full HTML output for the banner and modal.
		 *
		 * @return string
		 */
		public function render()
		{
			$html  = '<!-- Consent Management Platform and Privacy Management by My Agile Privacy® | www.myagileprivacy.com -->'.PHP_EOL;
			$html .= '<!--googleoff: all-->'.PHP_EOL;
			$html .= $this->render_banner();
			$html .= $this->render_blocked_content_notification();
			$html .= $this->render_modal();
			$html .= $this->render_custom_css();
			$html .= '<!--googleon: all-->'.PHP_EOL;

			return $html;
		}

		/**
		 * Returns (and caches) the cookie categories data.
		 * Calls get_cookie_categories_description() only once per render lifecycle.
		 *
		 * @return array
		 */
		private function get_cookies_categories_data()
		{
			if( $this->cookies_categories_data === null )
			{
				$this->cookies_categories_data = $this->frontend->get_cookie_categories_description( 'publish' );
			}

			return $this->cookies_categories_data;
		}

		/**
		 * Returns true if the cookie list for the second layer contains zero items.
		 *
		 * @return bool
		 */
		private function has_no_cookies()
		{
			$cookies_categories_data = $this->get_cookies_categories_data();

			foreach( $cookies_categories_data as $v )
			{
				foreach( $v as $value )
				{
					// At least one item found — not empty.
					return false;
				}
			}

			return true;
		}

		/**
		 * Returns the computed style variables used across multiple render methods.
		 *
		 * @return array
		 */
		private function get_style_vars()
		{
		    $s = $this->the_settings;
		    $color_style         = ( $s['text'] != '' ) ? 'color:'.$s['text'].' !important' : '';
		    $background_style    = $s['background'] != '' ? 'background-color:'.$s['background'] : '';
		    $border_radius_style = 'border-radius:'.$s['elements_border_radius'].'px';

		    $text_size_val       = (int) $s['text_size'];
		    $text_lineheight_val = (int) $s['text_lineheight'];

			$text_size       = '--map-text-size:'.$text_size_val.'px; font-size:var(--map-text-size)';
			$text_lineheight = '--map-text-lh:'.$text_lineheight_val.'px; line-height:var(--map-text-lh)';

		    return array(
		        'color_style'                           => $color_style,
		        'background_style'                      => $background_style,
		        'border_radius_style'                   => $border_radius_style,
		        'text_size'                             => $text_size,
		        'text_lineheight'                       => $text_lineheight,
		        'composed_style'                        => implode( ';', array( $color_style, $background_style, $border_radius_style, $text_size, $text_lineheight ) ),
		        'composed_style_paragraph_first_layer'  => implode( ';', array( $text_size, $text_lineheight, $color_style ) ),
		        'composed_style_paragraph_second_layer' => implode( ';', array( $text_size, $text_lineheight ) ),
		        'notification_bar_composed_style'       => implode( ';', array( $color_style, $background_style, $border_radius_style ) ),
		    );
		}

		/**
		 * Returns the computed position and size CSS classes for the banner.
		 *
		 * @return array
		 */
		private function get_position_vars()
		{
			$s = $this->the_settings;

			$iab_tcf_context = $this->is_iab_tcf_context();
			$no_cookies = $this->has_no_cookies();

			$cookie_banner_vertical_position   = $s['cookie_banner_vertical_position'];
			$cookie_banner_horizontal_position = $s['cookie_banner_horizontal_position'];

			$with_no_cookies_class = ( $no_cookies && !$iab_tcf_context ) ? 'mapNoCookies' : '';
			$with_css_effects_class = ( $s['with_css_effects'] == true ) ? 'withEffects' : '';
			$map_shadow_class       = ( $s['cookie_banner_shadow'] == false ) ? '' : $s['cookie_banner_shadow'];
			$floating_banner        = ( $s['floating_banner'] == false ) ? '' : 'map_floating_banner';
			$animation_class        = 'map_animation_'.$s['cookie_banner_animation'];

			$new_position = null;
			$new_size     = 'mapSizeBoxed';

			if( $cookie_banner_vertical_position )
			{
				switch( $s['cookie_banner_size'] )
				{
					case 'sizeWideBranded':
						$new_size = 'mapSizeWideBranded';
						$cookie_banner_horizontal_position = 'Center';
						break;
					case 'sizeWide':
						$new_size = 'mapSizeWide';
						$cookie_banner_horizontal_position = 'Center';
						break;
					case 'sizeBig':
						$new_size = 'mapSizeBig mapSizeBoxed';
						break;
					case 'sizeBoxed':
						$new_size = 'mapSizeBoxed';
						break;
					default:
						$new_size = 'mapSizeBoxed';
				}

				$new_position = 'mapPosition'.$cookie_banner_vertical_position.$cookie_banner_horizontal_position;
			}

			if( !$new_position )
			{
				$new_position = $s['is_bottom'] ? 'mapPositionBottomCenter' : 'mapPositionTopCenter';
				$new_size     = 'mapSizeBoxed';
			}

			if( !( isset( $s['pa'] ) && $s['pa'] ) ||
				( isset( $this->rconfig['expired_60_days'] ) && $this->rconfig['expired_60_days'] )
			)
			{
				$new_size = 'mapSizeWideBranded';
			}

			$composed_class = implode( ' ', array( $with_no_cookies_class, $new_position, $new_size, $floating_banner, $with_css_effects_class, $animation_class, $map_shadow_class ) );

			if( !$new_position )
			{
				$position_class_alt = ( $s['is_bottom'] == false ) ? 'isBottom' : 'isTop';
			}
			else
			{
				$position_class_alt = ( $cookie_banner_vertical_position == 'Top' ) ? 'isBottom' : 'isTop';
			}

			return array(
				'new_position'                    => $new_position,
				'new_size'                        => $new_size,
				'composed_class'                  => $composed_class,
				'position_class_alt'              => $position_class_alt,
				'with_css_effects_class'          => $with_css_effects_class,
				'map_shadow_class'                => $map_shadow_class,
				'cookie_banner_vertical_position' => $cookie_banner_vertical_position,
			);
		}

		/**
		 * Returns whether the IAB TCF context is active.
		 *
		 * @return bool
		 */
		private function is_iab_tcf_context()
		{
			return (
				$this->rconfig &&
				isset( $this->rconfig['allow_iab'] ) &&
				$this->rconfig['allow_iab'] == 1 &&
				$this->the_settings['enable_iab_tcf']
			);
		}

		/**
		 * Returns the resolved cookie policy URL, taking WPML and Polylang into account.
		 *
		 * @return string|null
		 */
		private function get_cookie_policy_url()
		{
			$s = $this->the_settings;

			$is_url = isset( $s['is_cookie_policy_url'] )   ? $s['is_cookie_policy_url']   : null;
			$url    = isset( $s['cookie_policy_url'] )       ? $s['cookie_policy_url']       : null;
			$page   = isset( $s['cookie_policy_page'] )      ? $s['cookie_policy_page']      : null;

			if( $is_url && $url ) return $url;

			if( !$is_url && $page )
			{
				if( $this->is_wpml_enabled )    return get_permalink( icl_object_id( $page, 'page', true ) );
				if( $this->is_polylang_enabled ) return get_permalink( pll_get_post( $page ) );
				return get_permalink( $page );
			}

			return null;
		}

		/**
		 * Returns the resolved personal data policy URL, taking WPML and Polylang into account.
		 *
		 * @return string|null
		 */
		private function get_personal_data_policy_url()
		{
			$s = $this->the_settings;

			$is_url = isset( $s['is_personal_data_policy_url'] ) ? $s['is_personal_data_policy_url'] : null;
			$url    = isset( $s['personal_data_policy_url'] )    ? $s['personal_data_policy_url']    : null;
			$page   = isset( $s['personal_data_policy_page'] )   ? $s['personal_data_policy_page']   : null;

			if( $is_url && $url ) return $url;

			if( !$is_url && $page )
			{
				if( $this->is_wpml_enabled )    return get_permalink( icl_object_id( $page, 'page', true ) );
				if( $this->is_polylang_enabled ) return get_permalink( pll_get_post( $page ) );
				return get_permalink( $page );
			}

			return null;
		}

		/**
		 * Returns the branded content HTML block, or empty string if not applicable.
		 *
		 * @param string $new_size
		 * @return string
		 */
		private function render_branded_content( $new_size )
		{
			if( $new_size == 'mapSizeWideBranded' ||
				!( isset( $this->the_settings['pa'] ) && $this->the_settings['pa'] ) ||
				( isset( $this->rconfig['expired_60_days'] ) && $this->rconfig['expired_60_days'] )
			)
			{
				if( isset( $this->rconfig['expired_60_days'] ) && $this->rconfig['expired_60_days'] )
				{
					$the_url = '#';

					if( defined( 'MAP_EXPIRED_CALLBACK_URL') && MAP_EXPIRED_CALLBACK_URL )
					{
						$the_key = 'default';

						if( $this->current_lang == 'it_IT' )
						{
							$the_key = $this->current_lang;
						}

						$the_url = MAP_EXPIRED_CALLBACK_URL[ $the_key ];
					}

					return
						'<div class="map_branded-box">'.
							'<a href="'.esc_url( $the_url ).'" target="blank">'.
								'<img width="80" src="'.esc_attr( plugin_dir_url( __DIR__ ) ).'frontend/img/warning_triangle.png" alt="'.esc_attr( __( 'Some features of My Agile Privacy® are currently unavailable. Please check your license to restore full functionality.', 'MAP_txt' ) ).'">'.
							'</a>'.
						'</div>';
				}
				else
				{
					return
						'<div class="map_branded-box">'.
							'<img src="'.esc_attr( plugin_dir_url( __DIR__ ) ).'frontend/img/map_logo_branded.svg" width="300" height="141" alt="Privacy and Consent by My Agile Privacy®">'.
						'</div>';
				}
			}

			return '';
		}

		/**
		 * Returns the button shortcode string based on the configured button order.
		 *
		 * @return string
		 */
		private function get_button_shortcode_string()
		{
			$default = '[myagileprivacy_cookie_accept][myagileprivacy_cookie_reject][myagileprivacy_cookie_customize]';
			$order   = $this->the_settings['layer_1_button_order'];
			$parts   = explode( '_', $order );

			if( count( $parts ) == 3 )
			{
				$result = '';
				foreach( $parts as $part )
				{
					$result .= '[myagileprivacy_cookie_'.$part.']';
				}
				return $result;
			}

			return $default;
		}

		/**
		 * Returns the notification message HTML, applying paragraph split if applicable.
		 *
		 * @param bool   $iab_tcf_context
		 * @param string $composed_style_paragraph_first_layer
		 * @param string $iab_extra_class
		 * @param string $cookie_policy_html_inside_popup
		 * @param string $personal_data_policy_html_inside_popup
		 * @param string $button_shortcode_string
		 * @return string
		 */
		private function render_notify_message(
			$iab_tcf_context,
			$composed_style_paragraph_first_layer,
			$iab_extra_class,
			$cookie_policy_html_inside_popup,
			$personal_data_policy_html_inside_popup,
			$button_shortcode_string
		)
		{
			$lang = $this->current_lang;
			$t    = $this->the_translations[ $lang ];
			$s    = $this->the_settings;

			$no_cookies = $this->has_no_cookies();

			$allowed_paragraph_split         = false;
			$map_notification_container_flex = '';

			if( $iab_tcf_context )
			{
			    $notify_message_text = $t['notify_message_v2'];
			}
			elseif( $no_cookies )
			{
			    $notify_message_text             = $t['notify_message_nocookie'];
			    $allowed_paragraph_split         = true;
			    $map_notification_container_flex = 'map_flex';
			}
			else
			{
			    $notify_message_text = $t['notify_message_v2'];

			    if( $t['notify_message_v2'] == $t['notify_message_v2_short'] )
			    {
			        $allowed_paragraph_split         = true;
			        $map_notification_container_flex = 'map_flex';
			    }
			}

			$notify_message = do_shortcode( stripslashes( esc_html( $notify_message_text.'[myagileprivacy_extra_info]' ) ) );

			if( $allowed_paragraph_split )
			{
				$paragraphs = preg_split( '/\.(?!\d)/', $notify_message );
				$paragraphs = array_map( 'trim', $paragraphs );
				$paragraphs = array_filter( $paragraphs );

				if( count( $paragraphs ) > 1 )
				{
					$notify_message = '';
					foreach( $paragraphs as $paragraph )
					{
						if( $paragraph && $paragraph != '' )
						{
							$notify_message .= '<p class="map_p_splitted" style="'.esc_attr( $composed_style_paragraph_first_layer ).'">'.$paragraph.'.&nbsp;</p>';
						}
					}
				}
			}

			$first_layer_extra_text = '';

			$cookie_policy_first_layer_check = ( $cookie_policy_html_inside_popup &&
				isset( $s['add_cookie_policy_to_first_layer'] ) &&
				$s['add_cookie_policy_to_first_layer'] );

			$personal_data_policy_first_layer_check = ( $personal_data_policy_html_inside_popup &&
				isset( $s['add_personal_policy_to_first_layer'] ) &&
				$s['add_personal_policy_to_first_layer'] );

			if( $cookie_policy_first_layer_check || $personal_data_policy_first_layer_check )
			{
				$first_layer_extra_text = '<div class="map-modal-cookie-policy-link">';

				if( $cookie_policy_first_layer_check )
				{
					$first_layer_extra_text .= wp_kses( $cookie_policy_html_inside_popup, MyAgilePrivacy::allowed_html_tags() );
				}

				if( $personal_data_policy_first_layer_check )
				{
					$first_layer_extra_text .= wp_kses( $personal_data_policy_html_inside_popup, MyAgilePrivacy::allowed_html_tags() );
				}

				$first_layer_extra_text .= '</div>';
			}

			$map_notification_container_extra_class = implode( ' ', array( $iab_extra_class, $map_notification_container_flex ) );

			return do_shortcode(
				'<div class="map-area-container">'.
					'<div data-nosnippet class="map_notification-message '.esc_attr( $map_notification_container_extra_class ).'">'.
						$notify_message.$first_layer_extra_text.
					'</div>'.
					'<div class="map_notification_container '.esc_attr( $iab_extra_class ).'">'.
						esc_attr( $button_shortcode_string ).
					'</div>'.
				'</div>'
			);
		}

		/**
		 * Returns the full first-layer banner HTML.
		 *
		 * @return string
		 */
		private function render_banner()
		{
			$s    = $this->the_settings;
			$lang = $this->current_lang;
			$t    = $this->the_translations[ $lang ];

			$style_vars    = $this->get_style_vars();
			$position_vars = $this->get_position_vars();

			$iab_tcf_context = $this->is_iab_tcf_context();
			$iab_extra_class = $iab_tcf_context ? 'map-iab-context' : '';

			$cookie_policy_url        = $this->get_cookie_policy_url();
			$personal_data_policy_url = $this->get_personal_data_policy_url();

			$cookie_policy_html_inside_popup        = '';
			$personal_data_policy_html_inside_popup = '';
			$cookie_policy_html_inside_banner       = '';

			if( $cookie_policy_url )
			{
				$cookie_policy_html_inside_popup = '<a target="blank" href="'.esc_url( $cookie_policy_url ).'" tabindex="0" aria-label="Cookie Policy">'.esc_html( $t['view_the_cookie_policy'] ).'</a>';
			}

			if( $personal_data_policy_url )
			{
				$personal_data_policy_html_inside_popup = '<a target="blank" href="'.esc_url( $personal_data_policy_url ).'" tabindex="0" aria-label="Personal Data Policy">'.esc_html( $t['view_the_personal_data_policy'] ).'</a>';
			}

			if( isset( $s['cookie_policy_link'] ) && $s['cookie_policy_link'] && $cookie_policy_url )
			{
				$cookie_policy_html_inside_banner = $cookie_policy_html_inside_popup;
			}

			$spacing_text = ( isset( $s['cookie_policy_link'] ) && $s['cookie_policy_link'] && $cookie_policy_html_inside_banner ) ? ' / ' : '';

			$_s_bg_color            = ( preg_match( '/^#[0-9a-fA-F]{3,6}$/', $s['heading_background_color'] ) ) ? $s['heading_background_color'] : '';
			$_s_txt_color           = ( preg_match( '/^#[0-9a-fA-F]{3,6}$/', $s['heading_text_color'] ) )        ? $s['heading_text_color']        : '';
			$map_heading_style      = 'background-color:'.$_s_bg_color.'; color: '.$_s_txt_color.';';
			$map_heading_class      = ( $s['title_is_on'] == true ) ? '' : 'map_displayNone';
			$map_close_button_style = ( $s['title_is_on'] == true ) ? 'color: '.$_s_txt_color.'!important;' : 'color: '.esc_attr( $s['text'] ).'!important;';
			$notify_logo_color      = ( $s['heading_background_color'] == '#ffffff' ) ? '#F93F00' : $_s_bg_color;
			$banner_logo_color      = $_s_txt_color;
			$banner_title           = esc_html( $t['banner_title'] );

			$notify_message = $this->render_notify_message(
				$iab_tcf_context,
				$style_vars['composed_style_paragraph_first_layer'],
				$iab_extra_class,
				$cookie_policy_html_inside_popup,
				$personal_data_policy_html_inside_popup,
				$this->get_button_shortcode_string()
			);

			$notify_title =
				'<div class="map_notify_title '.esc_attr( $map_heading_class ).'" style="'.esc_attr( $map_heading_style ).';">'.
					( $banner_title != '' ? esc_html( $banner_title ) : '<div class="banner-title-logo" style="background:'.esc_attr( $banner_logo_color ).';"></div> My Agile Privacy®' ).
				'</div>';

			$notify_close_button =
				'<div class="map-closebutton-right">'.
					'<a tabindex="0" role="button" class="map-button map-reject-button" data-map_action="reject" style="'.esc_attr( $map_close_button_style ).'">&#x2715;</a>'.
				'</div>';

			$html =
				'<div'.
					' role="dialog"'.
					' aria-label="My Agile Privacy®"'.
					' tabindex="0"'.
					' id="my-agile-privacy-notification-area"'.
					' class="'.esc_attr( $position_vars['composed_class'] ).' mapButtonsAside"'.
					' data-nosnippet="true"'.
					' style="'.esc_attr( $style_vars['composed_style'] ).'"'.
					' data-animation="'.esc_attr( $s['cookie_banner_animation'] ).'"'.
					' data-wg-notranslate '.
					'>'.
					$notify_title.
					$notify_close_button.
					'<div id="my-agile-privacy-notification-content">'.
						$this->render_branded_content( $position_vars['new_size'] ).
						$notify_message.
					'</div>'.
				'</div>';

			$html .= $this->render_show_again_widget(
				$notify_logo_color,
				$cookie_policy_html_inside_banner,
				$spacing_text,
				$style_vars['border_radius_style']
			);

			return $html;
		}

		/**
		 * Returns the "show again" consent widget HTML.
		 *
		 * @param string $notify_logo_color
		 * @param string $cookie_policy_html_inside_banner
		 * @param string $spacing_text
		 * @param string $border_radius_style
		 * @return string
		 */
		private function render_show_again_widget( $notify_logo_color, $cookie_policy_html_inside_banner, $spacing_text, $border_radius_style )
		{
			$s    = $this->the_settings;
			$lang = $this->current_lang;

			$consent_widget_style       = isset( $s['consent_widget_style'] ) ? $s['consent_widget_style'] : 'text_and_logo';
			$disable_logo               = $s['disable_logo'];
			$showagain_tab              = $s['showagain_tab'];
			$notify_position_horizontal = $s['notify_position_horizontal'];

			$show_again            = esc_html( $this->the_translations[ $lang ]['manage_consent'] );
			$showagain_div_classes = 'map_displayNone';
			$the_empty_href        = '#';

			if( $disable_logo )                         $showagain_div_classes .= ' nologo';
			if( $consent_widget_style === 'logo_only' ) $showagain_div_classes .= ' notext';
			if( $consent_widget_style === 'text_only' ) $showagain_div_classes .= ' nologo';
			if( $showagain_tab == 0 )                   $showagain_div_classes .= ' disactive';
			if( $s['with_css_effects'] == true )        $showagain_div_classes .= ' withEffects';

			switch( $notify_position_horizontal )
			{
				case 'left':   $showagain_div_classes .= ' left_position';   break;
				case 'center': $showagain_div_classes .= ' center_position'; break;
				case 'right':  $showagain_div_classes .= ' right_position';  break;
			}

			$widget_inner_html = '';

			if( $consent_widget_style === 'logo_only' )
			{
				$widget_inner_html = '<button class="map_logo_container map_logo_only showConsent" tabindex="0" role="button" style="background-color:'.esc_attr( $notify_logo_color ).';" aria-label="'.wp_kses( $show_again, MyAgilePrivacy::allowed_html_tags() ).'"></button>';
			}
			elseif( $consent_widget_style === 'text_only' )
			{
				$widget_inner_html = '<a tabindex="0" role="button" class="showConsent" href="'.$the_empty_href.'" data-nosnippet>'.wp_kses( $show_again, MyAgilePrivacy::allowed_html_tags() ).'</a>'.$spacing_text.$cookie_policy_html_inside_banner;
			}
			else
			{
				$widget_inner_html = '<div class="map_logo_container" style="background-color:'.esc_attr( $notify_logo_color ).';"></div><a tabindex="0" role="button" class="showConsent" href="'.$the_empty_href.'" data-nosnippet>'.wp_kses( $show_again, MyAgilePrivacy::allowed_html_tags() ).'</a>'.$spacing_text.$cookie_policy_html_inside_banner;
			}

			return
				'<div data-nosnippet class="'.esc_attr( $showagain_div_classes ).'" id="'.esc_attr( $s['showagain_div_id'] ).'" style="'.esc_attr( $border_radius_style ).'">'.
					$widget_inner_html.
				'</div>';
		}

		/**
		 * Returns the blocked content notification bar HTML, or empty string if disabled.
		 *
		 * @return string
		 */
		private function render_blocked_content_notification()
		{
			$s = $this->the_settings;

			if( !( $s['pa'] == 1 && $s['blocked_content_notify'] ) )
			{
				return '';
			}

			$style_vars    = $this->get_style_vars();
			$position_vars = $this->get_position_vars();

			$blocked_content_text = esc_html( $this->the_translations[ $this->current_lang ]['blocked_content'] ).':';
			$autoclose            = ( $s['blocked_content_notify_auto_shutdown'] == false ) ? '' : 'autoShutDown';
			$composed_class_alt   = implode( ' ', array( $position_vars['position_class_alt'], $autoclose, $position_vars['with_css_effects_class'], $position_vars['map_shadow_class'] ) );

			return
				'<div'.
					' class="map-blocked-content-notification-area '.esc_attr( $composed_class_alt ).'"'.
					' id="map-blocked-content-notification-area"'.
					' style="'.esc_attr( $style_vars['notification_bar_composed_style'] ).'"'.
				'>'.
					'<div class="map-area-container">'.
						'<div class="map_notification-message data-nosnippet">'.
							$blocked_content_text.'<br>'.
							'<span class="map_blocked_elems_desc"></span>'.
						'</div>'.
					'</div>'.
				'</div>';
		}

		/**
		 * Returns the full cookie settings modal HTML.
		 *
		 * @return string
		 */
		private function render_modal()
		{
			$s    = $this->the_settings;
			$lang = $this->current_lang;
			$t    = $this->the_translations[ $lang ];

			$style_vars    = $this->get_style_vars();
			$position_vars = $this->get_position_vars();

			$iab_tcf_context = $this->is_iab_tcf_context();
			$no_cookies      = $this->has_no_cookies();

			$cookie_policy_url        = $this->get_cookie_policy_url();
			$personal_data_policy_url = $this->get_personal_data_policy_url();

			$cookie_policy_html_inside_popup        = '';
			$personal_data_policy_html_inside_popup = '';

			if( $cookie_policy_url )
			{
				$cookie_policy_html_inside_popup = '<a target="blank" href="'.esc_url( $cookie_policy_url ).'" tabindex="0" aria-label="Cookie Policy">'.esc_html( $t['view_the_cookie_policy'] ).'</a>';
			}

			if( $personal_data_policy_url )
			{
				$personal_data_policy_html_inside_popup = '<a target="blank" href="'.esc_url( $personal_data_policy_url ).'" tabindex="0" aria-label="Personal Data Policy">'.esc_html( $t['view_the_personal_data_policy'] ).'</a>';
			}

			$layer2_overflow_wrapper_class = 'map-cookielist-overflow-container';

			if( $this->rconfig &&
				isset( $this->rconfig['disable_layer2_overflow'] ) &&
				$this->rconfig['disable_layer2_overflow'] )
			{
				$layer2_overflow_wrapper_class = '';
			}

			$with_no_cookies_class = ( $no_cookies && !$iab_tcf_context ) ? 'mapNoCookies' : '';

			$html  = '<div class="map-modal '.esc_attr( $with_no_cookies_class ).'" id="mapSettingsPopup" data-nosnippet="true" role="dialog" tabindex="0" aria-labelledby="mapSettingsPopup" data-wg-notranslate>';
			$html .= '<div class="map-modal-dialog">';
			$html .= '<div class="map-modal-content map-bar-popup '.esc_attr( $position_vars['with_css_effects_class'] ).'">';
			$html .= '<div class="map-modal-body">';
			$html .= '<div class="map-container-fluid map-tab-container">';

			$html .= '<div class="map-privacy-overview">';
			$html .= '<p class="map-h4-heading" data-nosnippet>'.esc_html( $t['privacy_settings'] ).'</p>';
			$html .= '</div>';

			$html .= '<p data-nosnippet style="'.esc_attr( $style_vars['composed_style_paragraph_second_layer'] ).'">';
			$html .= esc_html( $t['this_website_uses_cookies'] ).'<br>';
			$html .= '<span class="map-modal-cookie-policy-link">'.wp_kses( $cookie_policy_html_inside_popup, MyAgilePrivacy::allowed_html_tags() ).' '.wp_kses( $personal_data_policy_html_inside_popup, MyAgilePrivacy::allowed_html_tags() ).'</span>';
			$html .= '</p>';

			$html .= '<div class="'.esc_attr( $layer2_overflow_wrapper_class ).'">';

			if( $iab_tcf_context )
			{
				$thirdypart_active_class = $no_cookies ? '' : 'map-wrappertab-active';
				$iab_active_class        = $no_cookies ? 'map-wrappertab-active' : '';

				if( !$no_cookies )
				{
					$html .= $this->render_iab_tabs_header(); // opens map-consent-extrawrapper + nav tabs
				}
				else
				{
					$html .= '<div class="map-consent-extrawrapper">'; // opens the wrapper without nav tabs
				}

				$html .= '<div id="map-privacy-cookie-thirdypart-wrapper" class="map-wrappertab '.esc_attr( $thirdypart_active_class ).' map-privacy-cookie-thirdypart-wrapper">';
			}

			if( $no_cookies && !$iab_tcf_context )
			{
				$html .= '<p>'.esc_html( $t['layer2_nocookie'] ).'</p>';
			}
			else
			{
				$html .= $this->render_cookie_list( $position_vars['with_css_effects_class'] );
			}

			if( $iab_tcf_context )
			{
				$html .= '</div>'; // map-privacy-cookie-thirdypart-wrapper
				$html .= '<div id="map-privacy-iab-tcf-wrapper" class="map-wrappertab '.esc_attr( $iab_active_class ).' map-privacy-iab-tcf-wrapper"></div>';
				$html .= '</div>'; // map-consent-extrawrapper
			}

			$html .= '</div>'; // overflow-cookielist-container
			$html .= '</div>'; // map-container-fluid

			$html .= $this->render_credits();

			$html .= '</div>'; // map-modal-body
			$html .= '<button type="button" tabindex="0" class="map-modal-close" id="mapModalClose">✕<span class="sr-only">'.esc_html( $t['close'] ).'</span></button>';
			$html .= '</div>'; // map-modal-content
			$html .= '</div>'; // map-modal-dialog
			$html .= '</div>'; // map-modal

			$html .= '<div class="map-modal-backdrop map-fade map-settings-overlay"></div>';
			$html .= '<div class="map-modal-backdrop map-fade map-popupbar-overlay"></div>';

			return $html;
		}

		/**
		 * Returns the IAB TCF tab navigation header HTML.
		 *
		 * @return string
		 */
		private function render_iab_tabs_header()
		{
			$t = $this->the_translations[ $this->current_lang ];

			$html  = '<div class="map-consent-extrawrapper">';
			$html .= '<ul class="map-wrappertab-navigation">';
				$html .= '<li><a href="#map-privacy-cookie-thirdypart-wrapper" class="map-tab-navigation active-wrappertab-nav" role="button" tabindex="0">'.esc_html( $t['cookies_and_thirdy_part_software'] ).'</a></li>';
				$html .= '<li><a href="#map-privacy-iab-tcf-wrapper" class="map-tab-navigation" role="button" tabindex="0">'.esc_html( $t['advertising_preferences'] ).'</a></li>';
			$html .= '</ul>';

			return $html;
		}

		/**
		 * Returns the full cookie list HTML for the modal second layer.
		 *
		 * @param string $with_css_effects_class
		 * @return string
		 */
		private function render_cookie_list( $with_css_effects_class )
		{
			$s    = $this->the_settings;
			$lang = $this->current_lang;
			$t    = $this->the_translations[ $lang ];

			$is_enabled_text    = esc_html( $t['is_enabled'] );
			$is_disabled_text   = esc_html( $t['is_disabled'] );
			$always_enable_text = esc_html( $t['always_enable'] );

			$enable_cmode_v2        = ( isset( $s['enable_cmode_v2'] ) && $s['enable_cmode_v2'] && !( isset( $s['bypass_cmode_enable'] ) && $s['bypass_cmode_enable'] ) );
			$enable_microsoft_cmode = ( isset( $s['enable_microsoft_cmode'] ) && $s['enable_microsoft_cmode'] );
			$enable_clarity_cmode   = ( isset( $s['enable_clarity_cmode'] ) && $s['enable_clarity_cmode'] );

			$consent_mode_valid_post_api_key           = array( 'my_agile_pixel_ga', 'google_analytics', 'google_tag_manager', 'stape' );
			$microsoft_consent_mode_valid_post_api_key = array( 'microsoft_ads' );
			$clarity_consent_mode_valid_post_api_key   = array( 'microsoft_clarity' );

			$consent_mode_options_shown           = false;
			$microsoft_consent_mode_options_shown = false;
			$clarity_consent_mode_options_shown   = false;

			$cookies_categories_data = $this->get_cookies_categories_data();

			$all_remote_ids = array();
			$html           = '';

			foreach( $cookies_categories_data as $k => $v )
			{
				foreach( $v as $key => $value )
				{
					$the_remote_id = $value['remote_id'];

					if( in_array( $the_remote_id, $all_remote_ids ) ) continue;
					$all_remote_ids[] = $the_remote_id;

					//fallback if post_data->post_title empty
					$cookie_display_title = !empty( $value['post_title'] ) ? $value['post_title'] : $value['post_data']->post_title;

					$cleaned_cookie_name         = str_replace( '"', '', $cookie_display_title );
					$the_post_is_readonly        = isset( $value['post_meta']['_map_is_readonly'][0] )                 ? $value['post_meta']['_map_is_readonly'][0]                 : false;
					$the_post_installation_type  = isset( $value['post_meta']['_map_installation_type'][0] )           ? $value['post_meta']['_map_installation_type'][0]           : 'js_noscript';
					$the_post_code               = isset( $value['post_meta']['_map_code'][0] )                        ? $value['post_meta']['_map_code'][0]                        : null;
					$the_noscript                = isset( $value['post_meta']['_map_noscript'][0] )                    ? $value['post_meta']['_map_noscript'][0]                    : null;
					$the_post_raw_code           = isset( $value['post_meta']['_map_raw_code'][0] )                    ? $value['post_meta']['_map_raw_code'][0]                    : null;
					$the_post_api_key            = isset( $value['post_meta']['_map_api_key'][0] )                     ? $value['post_meta']['_map_api_key'][0]                     : null;
					$page_reload_on_user_consent = isset( $value['post_meta']['_map_page_reload_on_user_consent'][0] ) ? $value['post_meta']['_map_page_reload_on_user_consent'][0] : null;

					$this_to_show_consent_mode           = false;
					$this_to_show_microsoft_consent_mode = false;
					$this_to_show_clarity_consent_mode   = false;
					$this_extra_header_class             = '';
					$this_extra_content_class            = '';
					$this_content_display                = 'display:none;';

					if( !$consent_mode_options_shown && $enable_cmode_v2 && $the_post_api_key && in_array( $the_post_api_key, $consent_mode_valid_post_api_key ) )
					{
						$this_to_show_consent_mode  = true;
						$consent_mode_options_shown = true;
						$this_extra_header_class    = ' map-tab-active map-do-not-collapse';
						$this_extra_content_class   = ' map-do-not-collapse';
						$this_content_display       = 'display:block;';
					}

					if( !$microsoft_consent_mode_options_shown && $enable_microsoft_cmode && $the_post_api_key && in_array( $the_post_api_key, $microsoft_consent_mode_valid_post_api_key ) )
					{
						$this_to_show_microsoft_consent_mode  = true;
						$microsoft_consent_mode_options_shown = true;
						$this_extra_header_class              = ' map-tab-active map-do-not-collapse';
						$this_extra_content_class             = ' map-do-not-collapse';
						$this_content_display                 = 'display:block;';
					}

					if( !$clarity_consent_mode_options_shown && $enable_clarity_cmode && $the_post_api_key && in_array( $the_post_api_key, $clarity_consent_mode_valid_post_api_key ) )
					{
						$this_to_show_clarity_consent_mode  = true;
						$clarity_consent_mode_options_shown = true;
						$this_extra_header_class            = ' map-tab-active map-do-not-collapse';
						$this_extra_content_class           = ' map-do-not-collapse';
						$this_content_display               = 'display:block;';
					}

					$wrapper_added_class = '';

					if( $k == 'necessary' )
					{
						$wrapper_added_class .= ' _always_on';
					}
					else
					{
						if( $page_reload_on_user_consent ) $wrapper_added_class .= ' map_page_reload_on_user_consent';
					}

					if( $the_post_code || $the_post_raw_code ) $wrapper_added_class .= ' _with_code';

					$html .= $this->render_cookie_item(
						$k,
						$value,
						$the_remote_id,
						$cleaned_cookie_name,
						$the_post_api_key,
						$the_post_code,
						$the_post_raw_code,
						$the_noscript,
						$the_post_installation_type,
						$the_post_is_readonly,
						$wrapper_added_class,
						$with_css_effects_class,
						$this_extra_header_class,
						$this_extra_content_class,
						$this_content_display,
						$always_enable_text,
						$is_enabled_text,
						$is_disabled_text,
						$this_to_show_consent_mode,
						$this_to_show_microsoft_consent_mode,
						$this_to_show_clarity_consent_mode
					);
				}
			}

			return $html;
		}

		/**
		 * Returns the HTML for a single cookie item row in the modal list.
		 *
		 * @param string $k
		 * @param array  $value
		 * @param string $the_remote_id
		 * @param string $cleaned_cookie_name
		 * @param string $the_post_api_key
		 * @param string $the_post_code
		 * @param string $the_post_raw_code
		 * @param string $the_noscript
		 * @param string $the_post_installation_type
		 * @param bool   $the_post_is_readonly
		 * @param string $wrapper_added_class
		 * @param string $with_css_effects_class
		 * @param string $this_extra_header_class
		 * @param string $this_extra_content_class
		 * @param string $this_content_display
		 * @param string $always_enable_text
		 * @param string $is_enabled_text
		 * @param string $is_disabled_text
		 * @param bool   $this_to_show_consent_mode
		 * @param bool   $this_to_show_microsoft_consent_mode
		 * @param bool   $this_to_show_clarity_consent_mode
		 * @return string
		 */
		private function render_cookie_item(
			$k,
			$value,
			$the_remote_id,
			$cleaned_cookie_name,
			$the_post_api_key,
			$the_post_code,
			$the_post_raw_code,
			$the_noscript,
			$the_post_installation_type,
			$the_post_is_readonly,
			$wrapper_added_class,
			$with_css_effects_class,
			$this_extra_header_class,
			$this_extra_content_class,
			$this_content_display,
			$always_enable_text,
			$is_enabled_text,
			$is_disabled_text,
			$this_to_show_consent_mode,
			$this_to_show_microsoft_consent_mode,
			$this_to_show_clarity_consent_mode
		)
		{
			$s = $this->the_settings;
			$t = $this->the_translations[ $this->current_lang ];

			//fallback if post_data->post_title empty
			$cookie_display_title = !empty( $value['post_title'] ) ? $value['post_title'] : $value['post_data']->post_title;

			$html  = '<div class="map-tab-section map_cookie_description_wrapper '.esc_attr( $wrapper_added_class ).'" data-cookie-baseindex="'.esc_attr( $the_remote_id ).'" data-cookie-name="'.esc_attr( $cleaned_cookie_name ).'" data-cookie-api-key="'.esc_attr( $the_post_api_key ).'">';
			$html .= '<div class="map-tab-header map-standard-header '.esc_attr( $with_css_effects_class.$this_extra_header_class ).'">';
			$html .= '<a class="map_expandItem map-nav-link map-settings-mobile" data-toggle="map-toggle-tab" role="button" tabindex="0">'.esc_html( $cookie_display_title ).'</a>';

			if( $k == 'necessary' )
			{
				$html .= '<span class="map-necessary-caption" role="button" tabindex="0">'.esc_html( $always_enable_text ).'</span>';
			}
			else
			{
				$html .=
					'<div class="map-switch">'.
						'<input data-cookie-baseindex="'.esc_attr( $the_remote_id ).'" type="hidden" id="map-checkbox-'.esc_attr( $the_remote_id ).'" class="map-user-preference-checkbox MapDoNotTouch" value="0"/>'.
						'<div class="map-slider map-for-map-checkbox-'.esc_attr( $the_remote_id ).'" role="checkbox" aria-label="'.esc_attr( $cookie_display_title ).'" tabindex="0" aria-checked="mixed" data-map-enable="'.esc_attr( $is_enabled_text ).'" data-map-disable="'.esc_attr( $is_disabled_text ).'">'.
							'<span class="sr-only">'.esc_html( $cookie_display_title ).'</span>'.
						'</div>'.
					'</div>';
			}

			$html .= '</div>'; // map-tab-header

			$html .= '<div class="map-tab-content'.esc_attr( $this_extra_content_class ).'" style="'.esc_attr( $this_content_display ).'">';
			$html .= '<div data-nosnippet class="map-tab-pane map-fade">'.wp_kses_post( $value['post_content'] ).'</div>';

			if( isset( $s['pa'] ) && $s['pa'] == 1 && $this_to_show_clarity_consent_mode && is_array( $this->clarity_consent_mode_consents ) )
			{
				$html .= '<p>'.esc_html( $t['additional_consents'] ).':</p>';
				foreach( $this->clarity_consent_mode_consents as $vv )
				{
					$html .= $this->render_consent_mode_item( $vv, $is_enabled_text, $is_disabled_text, 'map-consent-clarity' );
				}
			}

			if( isset( $s['pa'] ) && $s['pa'] == 1 && $this_to_show_microsoft_consent_mode && is_array( $this->microsoft_consent_mode_consents ) )
			{
				$html .= '<p>'.esc_html( $t['additional_consents'] ).':</p>';
				foreach( $this->microsoft_consent_mode_consents as $vv )
				{
					$html .= $this->render_consent_mode_item( $vv, $is_enabled_text, $is_disabled_text, 'map-consent-microsoft' );
				}
			}

			if( isset( $s['pa'] ) && $s['pa'] == 1 && $this_to_show_consent_mode && is_array( $this->consent_mode_consents ) )
			{
				$html .= '<p>'.esc_html( $t['additional_consents'] ).':</p>';
				foreach( $this->consent_mode_consents as $vv )
				{
					$html .= $this->render_consent_mode_item( $vv, $is_enabled_text, $is_disabled_text, 'map-consent-google' );
				}
			}

			$html .= '</div>'; // map-tab-content

			if( $the_post_is_readonly == false && $the_post_installation_type == 'js_noscript' && $the_post_code )
			{
				$html .= '<script type="text/plain" class="my_agile_privacy_activate _js_noscript_type_mode" data-cookie-baseindex="'.esc_attr( $the_remote_id ).'" data-cookie-name="'.esc_attr( $cleaned_cookie_name ).'" data-cookie-api-key="'.esc_attr( $the_post_api_key ).'">'.strip_tags( stripslashes( $the_post_code ) ).'</script>';

				if( $the_noscript )
				{
					$html .= '<noscript data-cookie-baseindex="'.esc_attr( $the_remote_id ).'" data-cookie-name="'.esc_attr( $cleaned_cookie_name ).'" data-cookie-api-key="'.esc_attr( $the_post_api_key ).'">'.htmlspecialchars_decode( stripslashes( $the_noscript ), ENT_QUOTES ).'</noscript>';
				}
			}
			elseif( $the_post_is_readonly == false && $the_post_installation_type == 'raw_code' && $the_post_raw_code )
			{
				$html .= '<textarea aria-hidden="true" aria-label="'.esc_attr( $cleaned_cookie_name ).' raw script" style="display:none;" class="my_agile_privacy_activate _raw_type_mode" data-cookie-baseindex="'.esc_attr( $the_remote_id ).'" data-cookie-name="'.esc_attr( $cleaned_cookie_name ).'" data-cookie-api-key="'.esc_attr( $the_post_api_key ).'">'.htmlspecialchars_decode( stripslashes( $the_post_raw_code ), ENT_QUOTES ).'</textarea>';
			}

			$html .= '</div>'; // map_cookie_description_wrapper

			return $html;
		}

		/**
		 * Returns the HTML for a single consent mode item (Google, Microsoft, Clarity).
		 *
		 * @param array  $vv               Consent item with keys: key, human_name, human_desc
		 * @param string $is_enabled_text
		 * @param string $is_disabled_text
		 * @param string $extra_class      e.g. 'map-consent-google'
		 * @return string
		 */
		private function render_consent_mode_item( $vv, $is_enabled_text, $is_disabled_text, $extra_class )
		{
			$html  = '<div class="map-tab-section map_consent_description_wrapper" data-consent-key="'.esc_attr( $vv['key'] ).'">';
				$html .= '<div class="map-tab-header map-standard-header map-nocursor withEffects">';
					$html .= '<a class="map_expandItem map-contextual-expansion map-nav-link map-consent-mode-link map-settings-mobile" data-toggle="map-toggle-tab" role="button" tabindex="0">'.esc_html( $vv['human_name'] ).'</a>';
					$html .= '<div class="map-switch">';
						$html .= '<input type="hidden" id="map-consent-'.esc_attr( $vv['key'] ).'" class="map-consent-mode-preference-checkbox '.esc_attr( $extra_class ).' MapDoNotTouch" data-consent-key="'.esc_attr( $vv['key'] ).'" value="0">';
						$html .=
							'<div'.
								' class="map-slider map-nested map-for-map-consent-'.esc_attr( $vv['key'] ).'"'.
								' data-map-enable="'.esc_attr( $is_enabled_text ).'"'.
								' data-map-disable="'.esc_attr( $is_disabled_text ).'"'.
								' role="checkbox"'.
								' aria-label="'.esc_attr( $vv['human_name'] ).'"'.
								' tabindex="0"'.
								' aria-checked="mixed">'.
								'<span class="sr-only">'.esc_html( $vv['human_name'] ).'</span>'.
							'</div>';
						$html .= '</div>'; // map-switch
					$html .= '</div>'; // map-tab-header
					$html .= '<div class="map-tab-content" style="display: none;">';
					$html .= '<div data-nosnippet="" class="map-tab-pane map-fade">'.esc_html( $vv['human_desc'] ).'</div>';
					$html .= '</div>'; // map-tab-content
			$html .= '</div>'; // map_consent_description_wrapper

			return $html;
		}

		/**
		 * Returns the credits footer HTML for the modal.
		 *
		 * @return string
		 */
		private function render_credits()
		{
			$s    = $this->the_settings;
			$wl_b = isset( $s['wl_b'] ) ? intval( $s['wl_b'] ) : 0;

			if( $wl_b != 0 ) return '<br>';

			$anchor_texts = array();

			$anchor_texts[] = $this->the_translations[ $this->current_lang ]['anchor_text_1'];
			$anchor_texts[] = $this->the_translations[ $this->current_lang ]['anchor_text_2'];
			$anchor_texts[] = $this->the_translations[ $this->current_lang ]['anchor_text_3'];
			$anchor_texts[] = $this->the_translations[ $this->current_lang ]['anchor_text_4'];
			$anchor_texts[] = $this->the_translations[ $this->current_lang ]['anchor_text_5'];
			$anchor_texts[] = $this->the_translations[ $this->current_lang ]['anchor_text_6'];

			$site_name = get_bloginfo( 'name' );
			if( empty( $site_name ) )
			{
			    $site_name = home_url();
			}
			$anchor_text_index = abs( crc32( $site_name ) ) % count( $anchor_texts );
			$anchor_text = $anchor_texts[$anchor_text_index];

			$is_pro         = isset( $s['pa'] ) && $s['pa'] == 1;
			$img_pro        = '<img src="'.esc_attr( plugin_dir_url( __DIR__ ) ).'frontend/img/privacy-by-pro.png" alt="'.esc_attr( $anchor_text ).'" width="111" height="50">';
			$img_basic      = '<img src="'.esc_attr( plugin_dir_url( __DIR__ ) ).'frontend/img/privacy-by-basic.png" alt="'.esc_attr( $anchor_text ).'" width="111" height="50">';
			$img_pro_wide   = '<img src="'.esc_attr( plugin_dir_url( __DIR__ ) ).'frontend/img/privacy-by-pro.png" alt="'.esc_attr( $anchor_text ).'" width="435" height="40">';
			$img_basic_wide = '<img src="'.esc_attr( plugin_dir_url( __DIR__ ) ).'frontend/img/privacy-by-basic.png" alt="'.esc_attr( $anchor_text ).'" width="435" height="40">';

			$html = '<div data-nosnippet class="modal_credits">';

			if( isset( $this->rconfig ) && isset( $this->rconfig['credits_image_only'] ) && $this->rconfig['credits_image_only'] == 1 )
			{
				$html .= $is_pro ? $img_pro_wide : $img_basic_wide;
			}
			else
			{
				$about_url = 'https://www.myagileprivacy.com/en/you-are-visiting-from-a-trusted-site/?utm_source=referral&utm_medium=plugin-pro&utm_campaign=customize';
				$about_url_basic = 'https://www.myagileprivacy.com/en/?utm_source=referral&utm_medium=plugin-pro&utm_campaign=customize_free';

				if( $this->current_lang && $this->current_lang == 'it_IT' )
				{
					$about_url = 'https://www.myagileprivacy.com/about/?utm_source=referral&utm_medium=plugin-pro&utm_campaign=customize';
					$about_url_basic = 'https://www.myagileprivacy.com/?utm_source=referral&utm_medium=plugin-pro&utm_campaign=customize_free';
				}

				if( $is_pro )
				{
					$html .= '<a href="'.esc_attr( $about_url ).'" target="_blank" rel="nofollow" tabindex="-1" aria-label="'.esc_attr( $anchor_text ).'">'.$img_pro.'</a>';
				}
				else
				{
					$html .= '<a href="'.esc_attr( $about_url_basic ).'" target="_blank" tabindex="-1" aria-label="'.esc_attr( $anchor_text ).'">'.$img_basic.'</a>';
				}
			}

			$html .= '</div>';

			return $html;
		}

		/**
		 * Returns the custom CSS block HTML, or empty string if no custom CSS is set.
		 *
		 * @return string
		 */
		private function render_custom_css()
		{
			$custom_css = $this->the_settings['custom_css'];

			if( !$custom_css )
			{
				$custom_css = '';
			}

		    // Inline notify styles
		    $notify_styles = array();

		    $_inline_bg    = ( preg_match( '/^#[0-9a-fA-F]{3,6}$/', $this->the_settings['map_inline_notify_background'] ) ) ? $this->the_settings['map_inline_notify_background'] : '';
		    $_inline_color = ( preg_match( '/^#[0-9a-fA-F]{3,6}$/', $this->the_settings['map_inline_notify_color'] ) )        ? $this->the_settings['map_inline_notify_color']        : '';

		    if( $_inline_bg )
		    {
		        $notify_styles[] = 'background: ' . $_inline_bg . ';';
		    }
		    if( $_inline_color )
		    {
		        $notify_styles[] = 'color: ' . $_inline_color . ';';
		    }
		    if( count( $notify_styles ) > 0 )
		    {
		        $custom_css .= '.map_custom_notify { ' . implode( ' ', $notify_styles ) . ' }';
		    }

			return '<style type="text/css">'.esc_attr( $custom_css ).'</style>'.PHP_EOL;
		}
	}
}

// --- instantiate and render ---

$renderer = new MyAgilePrivacyBannerRenderer(
	$the_settings,
	$rconfig,
	$the_translations,
	$current_lang,
	$is_polylang_enabled,
	$is_wpml_enabled,
	$clarity_consent_mode_consents,
	$microsoft_consent_mode_consents,
	$consent_mode_consents,
	$this
);

return $renderer->render();