<?php
// Make sure this file isn't accessed directly
if (! defined('ABSPATH')) exit;
if (!is_admin()) {
    add_action('wp', 'gam_ads_ad_manager_and_ad_exchange_render_ads_based_on_position');
}
/**
 * Security & Implementation Notes
 *
 * @security All ad content is sanitized using:
 *           - `wp_kses()` inside `gamadsmbai_output_ad_html()` for safe HTML tag/attribute control.
 *           - `wp_kses_post()` for any user-provided custom ad code.
 *
 * @script The Google Publisher Tag (GPT) script must remain inline and cache-free,
 *         as per Google’s official documentation:
 *         https://developers.google.com/publisher-tag/
 *         This ensures proper asynchronous ad loading and prevents stale ad responses.
 *
 * @reason  Enqueueing GPT via wp_enqueue_script() is avoided intentionally,
 *          since it can cause script caching and delayed initialization issues
 *          that break Google Ad Manager ad delivery.
 */


function gam_ads_ad_manager_and_ad_exchange_render_ads_based_on_position()
{
    global $wpdb;
    $table_name = $wpdb->prefix . 'gamadsmbai_ads';
    /** @noinspection SqlResolve */
    /** @noinspection SqlNoDataSourceInspection */
    // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,PluginCheck.Security.DirectDB.UnescapedDBParameter -- No need of cache;$table_name is derived from $wpdb->prefix and therefore safe.
    $ads = $wpdb->get_results("SELECT * FROM $table_name WHERE is_active = 1");

    if (empty($ads)) return;

    $GAMADSCommentTop = "\n" . '<!-- GAM Ads Integration by Magicbid  -->' . "\n";
    $GAMADSCommentBottom = "\n" . '<!-- GAM Ads Integration END -->' . "\n";

    add_action('wp_head', function () use ($ads, $GAMADSCommentTop, $GAMADSCommentBottom) {
        $paths = get_option('save_path', []);
        if (!is_array($paths) || empty($paths)) {
            $paths = [];
        }
        $htmlHD = '';
        $pads = ['flying_carpet', 'push_down', 'sticky', 'rewarded'];
        /* Check if at least one premium ad exists */
        $has_premium_ad = false;
        foreach ($ads as $ad) {
            if (in_array($ad->ad_type, $pads, true)) {
                $has_premium_ad = true;
                break;
            }
        }
        if ($has_premium_ad && is_array($paths)) {
            foreach ($paths as $value) {
                $src = base64_decode($value, true);
                if ($src === false || !wp_http_validate_url($src)) {
                    continue;
                }
                // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript -- Part Of MagicTag SDKs and GPT must load inline via <script> tags per vendor requirements.
                $htmlHD .= "\n" . '<script src="' . $src . '"></script>' . "\n";
            }
        }
        echo wp_kses(
            // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript -- GPT and MagicTag SDKs must load inline via <script> tags per vendor requirements. Enqueueing would break ad rendering.
            $GAMADSCommentTop . '<script async src="https://securepubads.g.doubleclick.net/tag/js/gpt.js"></script>' . "\n" . '<script id="magictag-new-v2" src="https://magictag.digislots.in/657asds90/magic-shield-v=2.js"></script>' . $htmlHD . $GAMADSCommentBottom,
            array(
                'script' => array(
                    'async' => true,
                    'src'   => true,
                    'id'    => true,
                ),
            )
        );
    }, 1);


    foreach ($ads as $ad) {
        if (! gam_ads_ad_manager_and_ad_exchange_should_display_ad($ad)) continue;

        $ad_content = $GAMADSCommentTop . gam_ads_ad_manager_and_ad_exchange_get_ad_html($ad) . $GAMADSCommentBottom;

        switch ($ad->ad_position) {

            case 'before_content':
                add_filter('the_content', function ($content) use ($ad_content) {
                    if (!is_singular() || !in_the_loop() || !is_main_query()) {
                        return $content;
                    }
                    return $ad_content . $content;
                }, 5);
                break;

            case 'after_content':
                add_filter('the_content', function ($content) use ($ad_content) {
                    if (!is_singular() || !in_the_loop() || !is_main_query()) {
                        return $content;
                    }
                    return $content . $ad_content;
                }, 20);
                break;

            case 'middle_page':
                add_filter('the_content', function ($content) use ($ad_content) {
                    if (!is_singular() || !in_the_loop() || !is_main_query()) {
                        return $content;
                    }
                    $paragraphs = explode('</p>', $content);
                    $midpoint = floor(count($paragraphs) / 2);
                    array_splice($paragraphs, $midpoint, 0, $ad_content);
                    return implode('</p>', $paragraphs);
                }, 15);
                break;

            case 'before_paragraph':
                add_filter('the_content', function ($content) use ($ad, $ad_content) {
                    if (!is_singular() || !in_the_loop() || !is_main_query()) {
                        return $content;
                    }
                    $counts = array_filter(array_map('intval', explode(',', $ad->paragraph_counts ?? '')));
                    if (empty($counts)) return $content;

                    $paragraphs = explode('</p>', $content);
                    foreach ($counts as $count) {
                        $index = $count - 1; // paragraph numbers are human-friendly (1-based)
                        if (isset($paragraphs[$index])) {
                            $paragraphs[$index] .= $ad_content; // insert right before closing </p>
                        }
                    }
                    return implode('</p>', $paragraphs);
                }, 12);
                break;

            case 'after_paragraph':
                add_filter('the_content', function ($content) use ($ad, $ad_content) {
                    if (!is_singular() || !in_the_loop() || !is_main_query()) {
                        return $content;
                    }
                    $counts = array_filter(array_map('intval', explode(',', $ad->paragraph_counts ?? '')));
                    if (empty($counts)) return $content;

                    $paragraphs = explode('</p>', $content);
                    foreach ($counts as $count) {
                        $index = $count - 1;
                        if (isset($paragraphs[$index])) {
                            $paragraphs[$index] .= '</p>' . $ad_content;
                        }
                    }
                    return implode('</p>', $paragraphs);
                }, 12);
                break;

            case 'before_image':
                add_filter('the_content', function ($content) use ($ad, $ad_content) {
                    if (!is_singular() || !in_the_loop() || !is_main_query()) {
                        return $content;
                    }
                    $counts = array_filter(array_map(
                        'intval',
                        explode(',', $ad->paragraph_counts ?? '')
                    ));
                    if (empty($counts)) {
                        return $content;
                    }
                    // Split content by image tags (keep delimiters)
                    $parts = preg_split('/(<img[^>]+>)/i', $content, -1, PREG_SPLIT_DELIM_CAPTURE);
                    $imgIndex = 0;
                    foreach ($parts as $k => $part) {
                        if (preg_match('/<img/i', $part)) {
                            $imgIndex++;

                            if (in_array($imgIndex, $counts, true)) {
                                // Insert ad BEFORE image
                                $parts[$k] = $ad_content . $part;
                            }
                        }
                    }
                    return implode('', $parts);
                }, 12);
                break;

            case 'after_image':
                add_filter('the_content', function ($content) use ($ad, $ad_content) {
                    if (!is_singular() || !in_the_loop() || !is_main_query()) {
                        return $content;
                    }
                    $counts = array_filter(array_map('intval', explode(',', $ad->paragraph_counts ?? '')));
                    if (empty($counts)) return $content;

                    $images = preg_split('/(<img[^>]+>)/i', $content, -1, PREG_SPLIT_DELIM_CAPTURE);
                    $imgIndex = 0;

                    foreach ($images as $k => $part) {
                        if (preg_match('/<img/i', $part)) {
                            $imgIndex++;
                            if (in_array($imgIndex, $counts)) {
                                $images[$k] = $part . $ad_content; // append after image tag
                            }
                        }
                    }
                    return implode('', $images);
                }, 12);
                break;

            case 'between_posts':
                add_action('loop_start', function ($query) {
                    if (! $query->is_main_query()) {
                        return;
                    }
                    // Reset counter at beginning of each main loop
                    global $gamadsmbai_position_between_post_counter;
                    $gamadsmbai_position_between_post_counter = 0;
                });
                add_action('the_post', function ($post) use ($ad, $ad_content) {
                    if (is_admin() || !is_main_query() || is_singular()) {
                        return;
                    }
                    global $gamadsmbai_position_between_post_counter;
                    $gamadsmbai_position_between_post_counter++;
                    $positions = array_values(array_filter(array_map(
                        'intval',
                        explode(',', $ad->paragraph_counts ?? '')
                    )));
                    if (empty($positions)) {
                        return;
                    }
                    sort($positions);
                    $total = count($positions);
                    for ($i = 0; $i < $total; $i += 2) {
                        // Case 1: Proper pair
                        if (isset($positions[$i + 1])) {
                            // Insert BEFORE second post in pair
                            if ($gamadsmbai_position_between_post_counter === $positions[$i + 1]) {
                                // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
                                echo gamadsmbai_output_ad_html($ad_content);
                                return;
                            }
                        }
                        // Case 2: Odd leftover → insert before that post
                        else {
                            if ($gamadsmbai_position_between_post_counter === $positions[$i]) {
                                // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
                                echo gamadsmbai_output_ad_html($ad_content);
                                return;
                            }
                        }
                    }
                });
                break;


            case 'before_posts':
                add_action('loop_start', function ($query) use ($ad_content) {
                    if (is_admin() || !$query->is_main_query()) return;
                    static $shown = false;
                    if ($shown) {
                        return;
                    }
                    $shown = true;
                    // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
                    echo gamadsmbai_output_ad_html($ad_content);
                });
                break;

            case 'after_posts':
                add_action('loop_end', function ($query) use ($ad_content) {
                    if (is_admin() || !$query->is_main_query()) return;
                    static $shown = false;
                    if ($shown) {
                        return;
                    }
                    $shown = true;
                    // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
                    echo gamadsmbai_output_ad_html($ad_content);
                });
                break;

            case 'head': // NEW: outputs directly inside <head>
                add_action('wp_head', function () use ($ad_content) {
                    // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- HTML sanitized in gamadsmbai_output_ad_html().
                    echo gamadsmbai_output_ad_html($ad_content);
                }, 1); // priority 1 to ensure it loads early
                break;

            case 'header':
                add_action('wp_body_open', function () use ($ad_content) {
                    // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- HTML sanitized in gamadsmbai_output_ad_html().
                    echo gamadsmbai_output_ad_html($ad_content);
                });
                break;

            case 'footer':
                add_action('wp_footer', function () use ($ad_content) {
                    // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- HTML sanitized in gamadsmbai_output_ad_html().
                    echo gamadsmbai_output_ad_html($ad_content);
                });
                break;

            case 'floating_left':
                add_action('wp_footer', function () use ($ad_content) {
                    // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- HTML sanitized in gamadsmbai_output_ad_html().
                    echo gamadsmbai_output_ad_html('<div class="gam-floating-left" style="position:fixed;left:0;top:50%;transform:translateY(-50%);z-index:9999;">' . $ad_content . '</div>');
                });
                break;

            case 'floating_right':
                add_action('wp_footer', function () use ($ad_content) {
                    // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- HTML sanitized in gamadsmbai_output_ad_html().
                    echo gamadsmbai_output_ad_html('<div class="gam-floating-right" style="position:fixed;right:0;top:50%;transform:translateY(-50%);z-index:9999;">' . $ad_content . '</div>');
                });
                break;

            case 'sidebar':
                add_action('get_sidebar', function () use ($ad_content) {
                    // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- HTML sanitized in gamadsmbai_output_ad_html().
                    echo gamadsmbai_output_ad_html($ad_content);;
                });
                break;

            case 'custom':
                if (! empty($ad->custom_ad_position)) {
                    add_action('wp_footer', function () use ($ad_content, $ad) {
?>
                        <script>
                            document.addEventListener('DOMContentLoaded', function() {
                                const _GAMADSMBAICUSTOMel = document.querySelector('<?php echo esc_js($ad->custom_ad_position); ?>');
                                if (_GAMADSMBAICUSTOMel) {
                                    const _GAMADSMBAICUSTOMtemp = document.createElement('div');
                                    _GAMADSMBAICUSTOMtemp.innerHTML = <?php echo wp_json_encode($ad_content); ?>;
                                    const _GAMADSMBAICUSTOMscripts = _GAMADSMBAICUSTOMtemp.querySelectorAll('script');
                                    _GAMADSMBAICUSTOMscripts.forEach(script => script.remove());
                                    _GAMADSMBAICUSTOMel.insertAdjacentHTML(<?php echo $ad->ad_alignment === 'start' ? "'beforebegin'" : "'beforeend'"; ?>, _GAMADSMBAICUSTOMtemp.innerHTML);
                                    _GAMADSMBAICUSTOMscripts.forEach(oldScript => {
                                        const newScript = document.createElement('script');
                                        [...oldScript.attributes].forEach(attr => {
                                            newScript.setAttribute(attr.name, attr.value);
                                        });
                                        newScript.textContent = oldScript.textContent;
                                        document.body.appendChild(newScript);
                                    });
                                }
                            });
                        </script>
<?php
                    });
                }
                break;
        }
    }
}

function gam_ads_ad_manager_and_ad_exchange_should_display_ad($ad)
{
    // Device check first
    if (!empty($ad->gam_active_devices)) {
        $active_devices = explode(',', $ad->gam_active_devices);
        $active_devices = array_map('trim', $active_devices);

        $is_mobile  = wp_is_mobile();
        $device     = $is_mobile ? 'mobile' : 'desktop';

        // Optional: tablet detection if you want separate logic
        if ($is_mobile && preg_match(
            '/(tablet|ipad|playbook)|(android(?!.*mobile))/i',
            isset($_SERVER['HTTP_USER_AGENT']) ?
                sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : ''
        )) {
            $device = 'tablet';
        }

        if (!in_array($device, $active_devices, true)) {
            return false; // Device not active → no ad
        }
    }

    // 1. Check if already shown (show_once logic)
    // if (! empty($ad->show_once) && $ad->show_once == 1) {
    //     $cookie_key = 'gam_ad_shown_' . $ad->id;
    //     if (! empty($_COOKIE[$cookie_key])) {
    //         return false;
    //     }
    // }

    // 2. Entire site check
    if ($ad->show_entire_site) return true;

    // 3. Page-type check
    $visible_pages = maybe_unserialize($ad->visible_pages);
    if (empty($visible_pages)) return false;

    // Map WP conditionals to our values
    $page_types = [];

    if (is_front_page()) {
        $page_types[] = 'homepage';
    }
    if (is_single() && get_post_type() === 'post') {
        $page_types[] = 'post';
    }
    if (is_category()) {
        $page_types[] = 'category';
    }
    if (is_page()) {
        $page_types[] = 'page';
    }
    if (is_search()) {
        $page_types[] = 'search';
    }
    if (is_tag() || is_archive()) {
        $page_types[] = 'archive';
    }

    // If any match, show ad
    return (bool) array_intersect($visible_pages, $page_types);
}

function gam_ads_ad_manager_and_ad_exchange_get_ad_html($ad)
{

    $html = '';
    $sitename = home_url();
    $alignment_class = '';
    if ($ad->ad_alignment === 'left') {
        $alignment_class = 'gamadsmbai-align-left';
    } elseif ($ad->ad_alignment === 'center' || $ad->ad_alignment === 'start' || $ad->ad_alignment === 'end') {
        $alignment_class = 'gamadsmbai-align-center';
    } elseif ($ad->ad_alignment === 'right') {
        $alignment_class = 'gamadsmbai-align-right';
    } elseif ($ad->ad_alignment === 'top') {
        $alignment_class = 'gamadsmbai-align-fixed-top';
    } elseif ($ad->ad_alignment === 'bottom') {
        $alignment_class = 'gamadsmbai-align-fixed-bottom';
    }

    $sizes = [];
    if (!empty($ad->gam_ad_sizes)) {
        $parts = explode(',', $ad->gam_ad_sizes);
        foreach ($parts as $p) {
            $p = trim($p);
            if (strtolower($p) === 'fluid') {
                $sizes[] = 'fluid'; // keep as string
            } else {
                $xy = explode('x', $p);
                if (count($xy) === 2) {
                    $sizes[] = [(int) $xy[0], (int) $xy[1]];
                }
            }
        }
    }

    $deskD = [];
    $tabD = [];
    $mobD = [];

    if (!empty($ad->gam_responsive_sizes)) {
        $responsive = json_decode($ad->gam_responsive_sizes, true);
        if (json_last_error() === JSON_ERROR_NONE && is_array($responsive)) {
            foreach (['desktop' => &$deskD, 'tablet' => &$tabD, 'mobile' => &$mobD] as $device => &$bucket) {
                if (!empty($responsive[$device])) {
                    $parts = explode(',', $responsive[$device]);
                    foreach ($parts as $p) {
                        $p = trim($p);
                        if (strtolower($p) === 'fluid') {
                            $bucket[] = 'fluid';
                        } else {
                            $xy = explode('x', $p);
                            if (count($xy) === 2) {
                                $bucket[] = [(int) $xy[0], (int) $xy[1]];
                            }
                        }
                    }
                }
            }
        }
    }

    if ($ad->ad_type === 'custom_ad' && ! empty($ad->custom_code)) {
        if ($alignment_class) {
            $html  = "\n" . '<div class="gamadsmbai-custom ' . esc_attr($alignment_class) . ' ">' . "\n";
            $html .= gamadsmbai_output_ad_html($ad->custom_code, false);
            $html .= "\n" . '</div>' . "\n";
        } else {
            $html = $ad->custom_code;
        }
    } elseif (! empty($ad->gam_ad_unit)) {
        if ($ad->ad_type === 'banner') {
            $wrapper = '';
            $wrapperEnd = '';
            if ($alignment_class) {
                $lbl = ((int) get_option('gamadsmbai_lbl_advertisement', 0) !== 1)  ? ("\n" . '<small>' . base64_decode('QWR2ZXJ0aXNlbWVudA==', true) . '</small>' . "\n") : '';
                $wrapper = '<div class="gamadsmbai_banner_flex_box ' . $alignment_class . '">' . "\n" . '<div class="gamadsmbai_center_all">' . $lbl;
                $wrapperEnd = '</div>' . "\n" . '</div>';
            }
            $blockid = intval($ad->blockid);
            $html = $wrapper . '
            <div id="it_me_gamadsmbai_banner_block_' . $blockid . '">
            <script>
                window.googletag = window.googletag || {cmd: []};
                googletag.cmd.push(function() {
                let _0xesdhslt;' . (intval($ad->is_responsive) === 1 ? '
                var mapping' . $blockid . ' = googletag.sizeMapping().
                    addSize([800, 90], ' . wp_json_encode($deskD) . ').
                    addSize([580, 90], ' . wp_json_encode($tabD) . ').
                    addSize([0, 0], ' . wp_json_encode($mobD) . ').
                    build();' : '') . '
                _0xesdhslt = googletag.defineSlot("' . esc_attr($ad->gam_ad_unit) . '", ' . (!empty($sizes) ? wp_json_encode($sizes) : '[0, 0]') . ', "it_me_gamadsmbai_banner_block_' . $blockid . '")' . (intval($ad->is_responsive) === 1 ? '.defineSizeMapping(mapping' . $blockid . ')' : '') . '.addService(googletag.pubads());
                googletag.pubads().set("page_url", "' . $sitename . '"); ' . (intval($ad->is_refreshad) === 1 ? '
                googletag.pubads().addEventListener("impressionViewable", function (event) {
                const _0xrfslt = event.slot;
                if(_0xrfslt === _0xesdhslt){
                    const bnnrAdtimeup = setInterval(() => {
                        console.log("ready to refresh");
                        googletag.pubads().refresh([_0xrfslt]);
                        clearInterval(bnnrAdtimeup);
                        }, ' . intval($ad->refreshad_intervel) . ' * 1000);
                    }
                });' : '') . 'googletag.enableServices();
                googletag.display("it_me_gamadsmbai_banner_block_' . $blockid . '");
                });
            </script>
            </div>
            ' . $wrapperEnd;
        } else if ($ad->ad_type === 'interstitial') {
            $html = '<script>window.googletag = window.googletag || {cmd: []};var GmaConnecinterstitialSlot;googletag.cmd.push(function() {GmaConnecinterstitialSlot = googletag.defineOutOfPageSlot("' . esc_attr($ad->gam_ad_unit) . '", googletag.enums.OutOfPageFormat.INTERSTITIAL);if (GmaConnecinterstitialSlot) {GmaConnecinterstitialSlot.addService(googletag.pubads());}googletag.setConfig({ singleRequest: true });googletag.enableServices();googletag.display(GmaConnecinterstitialSlot);});</script>';
        } else if ($ad->ad_type === 'anchor') {
            if ($ad->ad_alignment === 'top') {
                $position = 'TOP_ANCHOR';
            } else {
                $position = 'BOTTOM_ANCHOR';
            }
            $html = '<script>window.googletag = window.googletag || {cmd: []};var GmaConnectanchorSlot;googletag.cmd.push(function() {GmaConnectanchorSlot = googletag.defineOutOfPageSlot("' . esc_attr($ad->gam_ad_unit) . '", googletag.enums.OutOfPageFormat.' . $position . ');if (GmaConnectanchorSlot) {GmaConnectanchorSlot.addService(googletag.pubads());}googletag.setConfig({ singleRequest: true });googletag.enableServices();googletag.display(GmaConnectanchorSlot);});</script>';
        } else if ($ad->ad_type === 'floater') {
            $pwrdblbl = ((int) get_option('gamadsmbai_lbl_credit', 0) !== 1) ? base64_decode("UG93ZXJlZCBCeSA8c3BhbiBzdHlsZT0nY29sb3I6IzIwNmNkNyc+PGEgc3R5bGU9J3RleHQtZGVjb3JhdGlvbjpub25lO2NvbG9yOiMyMDZjZDcnIGhyZWY9J2h0dHBzOi8vd3d3Lm1hZ2ljYmlkLmFpP3V0bV9zb3VyY2U9UHJvbW90aW9uJnV0bV9tZWRpdW09QmFubmVyJnV0bV9jYW1wYWlnbj1Qb3B1cF9BZCc+TWFnaWNiaWQuYWk8L2E+PC9zcGFuPg==") : '';
            $html = '<script>(()=>{
            const createElementSide = document.createElement("div");
            document.querySelector("body").append(createElementSide);
            createElementSide.setAttribute("id", "ad-side");
            createElementSide.innerHTML = ' . "'" . '<style id="stylefs"></style><div class="fixed-width-fs"><div id="close-popup-fs"> <span class="close-btn-fs"><svg width="18px" height="18px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" stroke="#000000" stroke-width="0.096"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path fill-rule="evenodd" clip-rule="evenodd" d="M19.207 6.207a1 1 0 0 0-1.414-1.414L12 10.586 6.207 4.793a1 1 0 0 0-1.414 1.414L10.586 12l-5.793 5.793a1 1 0 1 0 1.414 1.414L12 13.414l5.793 5.793a1 1 0 0 0 1.414-1.414L13.414 12l5.793-5.793z" fill="#000000"></path></g></svg></span> <span class="ourPowerOf-s"></span></div> <div id="magicbidfloaterad"> </div> </div>' . "'" . ';
            document.getElementById("magicbidfloaterad").setAttribute("style", "padding: 10px 8px 10px 8px; border-radius: 2px; overflow: hidden;}");
            document.querySelector(".close-btn-fs").setAttribute("style", "width: auto;height: auto; color: #00c2ff;text-align: center;cursor:pointer");
            document.getElementById("stylefs").innerHTML = ".slide-left{left: 0.5% !important;}.slide-left-close{left: -350% !important;}.slide-right{right: 0.5% !important;}.slide-right-close{right: -350% !important;}.ourPowerOf-s{font-size:12px;}@media(max-width:459px){#magicbidfloaterad{max-width:auto;max-height:auto}}";
            document.querySelector(".fixed-width-fs").setAttribute("style", "background-color: #ffffff;border-radius: 8px; padding: 5px;  box-shadow: 0px 10px 20px 0px rgba(128, 128, 128, 0.645);");
            document.getElementById("close-popup-fs").setAttribute("style", "width: 100%;display: flex;flex-direction: row-reverse;justify-content: space-between;align-items: center;color: gray; font-family: helvetica, sans-sarif; border: solid #9a9a9a 0px; border-width:0px 0px 1px 0px");
            document.getElementById("ad-side").setAttribute("style", "display: flex;width: auto;height: auto;position: fixed;bottom: 18%;' . ($ad->ad_alignment === 'left' ? 'left' : 'right') . ': -110%;flex-direction: column;justify-content: center;align-items: center;flex-wrap: nowrap;box-sizing:border-box; z-index: +999999999999999999999999999; transition: 1s !important;");
            window.googletag = window.googletag || { cmd: [] };
            ' . (intval($ad->is_refreshad) === 1 ? 'let rfrsAdtimeup = null;' : '') . '
            googletag.cmd.push(function () {
            ' . (intval($ad->is_responsive) === 1 ? '
                    var mappingfltr = googletag.sizeMapping().
                    addSize([800, 90], ' . wp_json_encode($deskD) . ').
                    addSize([580, 90], ' . wp_json_encode($tabD) . ').
                    addSize([0, 0], ' . wp_json_encode($mobD) . ').
                    build();' : '') . '
            var slotFS = googletag.defineSlot("' . esc_attr($ad->gam_ad_unit) . '", ' . wp_json_encode($sizes) . ', "magicbidfloaterad")' . (intval($ad->is_responsive) === 1 ? '.defineSizeMapping(mappingfltr)' : '') . '.addService(googletag.pubads());
            googletag.pubads().set("page_url", "' . $sitename . '");
            googletag.enableServices();
            googletag.display(magicbidfloaterad);
            googletag.pubads().addEventListener("slotRenderEnded", function (event) {
            if (event.slot == slotFS) {
            if (event.isEmpty) {
            createElementSide.style.display = "none";
            createElementSide.innerHTML = "";
            createElementSide.setAttribute("id", "ad-closed");
            } else {
                window.addEventListener("scroll", function () {
            if (window.pageYOffset >= 200) {
            const fixedD = document.querySelector(".fixed-width-fs");
            fixedD ? fixedD.style.display = "block" : false;
            const OurPower = document.querySelector(".ourPowerOf-s");
            OurPower ? OurPower.innerHTML = "' . $pwrdblbl . '" : false;
            if (document.getElementById("ad-side")) {
            document.getElementById("ad-side").setAttribute("style", "display: flex;width: auto;height: auto;position: fixed;bottom: 18%;' . ($ad->ad_alignment === 'left' ? 'left' : 'right') . ': -35%;flex-direction: column;justify-content: center;align-items: center;flex-wrap: nowrap;box-sizing:border-box; z-index: +999999999999999999999999999; transition: 1s !important;");
            setTimeout(() => {
            document.getElementById("ad-side").classList.add("slide-' . ($ad->ad_alignment === 'left' ? 'left' : 'right') . '");
            }, 500);
            }} else {}});
             }}});
             ' . (intval($ad->is_refreshad) === 1 ? '
            googletag.pubads().addEventListener("impressionViewable", function (event) {
                const _0xrfslt = event.slot;
                if(_0xrfslt === slotFS){
                    rfrsAdtimeup = setInterval(() => {
                        googletag.pubads().refresh([_0xrfslt]);
                        clearInterval(rfrsAdtimeup);
                        }, ' . intval($ad->refreshad_intervel) . ' * 1000);
                }
            });
            ' : '') . '
             });
             document.querySelector(".close-btn-fs").addEventListener("click", function () {
             if(rfrsAdtimeup != null) clearInterval(rfrsAdtimeup);
             document.getElementById("ad-side").classList.add("slide-' . ($ad->ad_alignment === 'left' ? 'left' : 'right') . '-close");
             document.getElementById("ad-side").classList.remove("slide-' . ($ad->ad_alignment === 'left' ? 'left' : 'right') . '");
             setTimeout(() => {
             createElementSide.style.display = "none";
             createElementSide.setAttribute("id", "ad-closed");
             }, 500);})
             })();
             </script>';
        } else if ($ad->ad_type === 'popup') {
            $pwrdblbl = ((int) get_option('gamadsmbai_lbl_credit', 0) !== 1) ? base64_decode("PHNwYW4gc3R5bGU9J2NvbG9yOiM1YTVhNWE7Zm9udC1zaXplOjExcHg7cGFkZGluZzogMHB4IDEwcHgnPlBvd2VyZWQgQnkgPGEgc3R5bGU9J3RleHQtZGVjb3JhdGlvbjpub25lO2NvbG9yOiMwMDA7Zm9udC1zaXplOjEycHgnIHJlbD0nbm9mb2xsb3cnIGhyZWY9J2h0dHBzOi8vd3d3Lm1hZ2ljYmlkLmFpP3V0bV9zb3VyY2U9UHJvbW90aW9uJnV0bV9tZWRpdW09QmFubmVyJnV0bV9jYW1wYWlnbj1Qb3B1cF9BZCc+TWFnaWNiaWQuYWk8L2E+PC9zcGFuPg==") : '';

            $DelayOrScroll = '4';
            $isScrollActive = false;
            $isLoadOnceActive = false;
            if (str_starts_with($ad->ad_alignment, 'delay')) {
                $DelayOrScroll = str_replace('delay', '', $ad->ad_alignment);
            } else if (str_starts_with($ad->ad_alignment, 'loadonce')) {
                $DelayOrScroll = str_replace('loadonce', '', $ad->ad_alignment);
                $isLoadOnceActive = true;
            } else if (str_starts_with($ad->ad_alignment, 'scrollonce')) {
                $DelayOrScroll = str_replace('scrollonce', '', $ad->ad_alignment);
                $isScrollActive = true;
                $isLoadOnceActive = true;
            } else if (str_starts_with($ad->ad_alignment, 'scroll')) {
                $DelayOrScroll = str_replace('scroll', '', $ad->ad_alignment);
                $isScrollActive = true;
            }

            $html = '<script>
            (() => {
                ' . ($isLoadOnceActive ? 'if(window.sessionStorage.getItem("gamadsmbai_popup_ad_loaded") === "true") return;' : '') . '
                window.addEventListener("DOMContentLoaded", () => {
                const createElementPop = document.createElement("div");
                createElementPop.setAttribute("id", "ad-popup");
                createElementPop.setAttribute("style", "width: 100%;height: 100vh;position: fixed;top:0%;left: 0;display: none;flex-direction: column;justify-content: center;align-items: center;flex-wrap: nowrap;gap: 1px;background-color: #0000008f;box-sizing:border-box; z-index: +999999999999999999999999999");
                document.querySelector("body").append(createElementPop);
                createElementPop.innerHTML = ' . "'" . '<style id="style"></style><div class="fixed-width"> <div class="close-popup"> <span class="close-btn"><svg width="18px" height="18px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" stroke="#000000" stroke-width="0.096"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path fill-rule="evenodd" clip-rule="evenodd" d="M19.207 6.207a1 1 0 0 0-1.414-1.414L12 10.586 6.207 4.793a1 1 0 0 0-1.414 1.414L10.586 12l-5.793 5.793a1 1 0 1 0 1.414 1.414L12 13.414l5.793 5.793a1 1 0 0 0 1.414-1.414L13.414 12l5.793-5.793z" fill="#000000"></path></g></svg></span> <span class="ourPowerOf"><span style="color:#5a5a5a;font-size:11px;padding: 0px 10px">Ad</span></span></div> <div id="magicbidpopupadgamadsplgn"> </div> </div>' . "'" . ';
                document.getElementById("style").innerHTML = "@media(max-width:459px){.fixed-width{width: 100%;min-width: auto !important;padding: 0% !important;}.close-popup{max-width:none !important; width: 100% !important;top: 0px !important;min-width: auto !important;height: auto !important;padding: 10px !important;}#ad-popup{ padding: 10px;}#magicbidpopupadgamadsplgn, #magicbidpopupadgamadsplgn>div{display: flex !important;flex-direction: row;flex-wrap: wrap;align-content: center;justify-content: center;align-items: center;}}";
                document.querySelectorAll(".fixed-width").forEach((e)=>e.setAttribute("style", "position:relative;display:none;min-width: 316px; background-color: #ffffff03;border-radius: 4px; padding: 0px;"));
                document.querySelectorAll(".close-popup").forEach((e)=>e.setAttribute("style", "position:relative;top:0px;right:0px;width:100%;height: 30px;padding: 0px 0px;background-color:#fff;border-radius:2px 2px 0px 0px;display: flex;flex-direction: row-reverse;justify-content: space-between;align-items: center;color: gray; font-family: helvetica, sans-sarif;"));
                document.getElementById("magicbidpopupadgamadsplgn").setAttribute("style", "padding: 10px 8px 10px 8px;border:solid 1px #adadad; box-shadow: 0px 10px 20px 0px rgba(128, 128, 128, 0.645); border-radius: 0px 0px 2px 2px; overflow: hidden;}");
                document.querySelectorAll(".close-btn").forEach((e)=>e.setAttribute("style", "width: auto;height: auto; color: #00c2ff;text-align: center;cursor:pointer;padding: 0px 10px;display:flex;justify-content:center;align-items:center;"));
                ' .
                ($isScrollActive ?
                    '
                let pageScrolled = false;
                window.addEventListener("scroll", (e) => {
                    if (pageScrolled) return;
                    const scrollTop = window.scrollY;
                    const docHeight = document.documentElement.scrollHeight - window.innerHeight;
                    if (docHeight <= 0) return;
                    const scrollPercent = (scrollTop / docHeight) * 100;
                    if (scrollPercent >= ' . $DelayOrScroll . ') {
                        console.log(scrollPercent);
                        pageScrolled = true;
                '
                    :
                    'setTimeout(() => {'
                ) . '
                    window.googletag = window.googletag || { cmd: [] };
                    googletag.cmd.push(function () {
                        ' . (intval($ad->is_responsive) === 1 ? '
                        var mappingp = googletag.sizeMapping().
                        addSize([800, 90], ' . wp_json_encode($deskD) . ').
                        addSize([580, 90], ' . wp_json_encode($tabD) . ').
                        addSize([0, 0], ' . wp_json_encode($mobD) . ').
                        build();' : '') . '
                        var slot = googletag.defineSlot("' . esc_attr($ad->gam_ad_unit) . '", ' . wp_json_encode($sizes) . ', "magicbidpopupadgamadsplgn")' . (intval($ad->is_responsive) === 1 ? '.defineSizeMapping(mappingp)' : '') . '.addService(googletag.pubads());
                        googletag.pubads().set("page_url", "' . $sitename . '");
                        googletag.enableServices();
                        googletag.display("magicbidpopupadgamadsplgn");
                        googletag.pubads().addEventListener("slotRenderEnded", function (event) {
                            if (event.slot == slot) {
                                if (event.isEmpty) {
                                    const fixedD = document.querySelectorAll(".fixed-width")[event.slot === slot ? 0 : 1];
                                    if(fixedD) fixedD.style.display = "none";
                                } else {
                                    const fixedD = document.querySelectorAll(".fixed-width");
                                    if(fixedD) fixedD[event.slot === slot ? 0 : 1].style.display = "block";
                                    const OurPower = document.querySelector(".ourPowerOf");
                                    if(OurPower) OurPower.innerHTML = "' . $pwrdblbl . '";
                                    if (document.getElementById("ad-popup")) document.getElementById("ad-popup").style.display= "flex";
                                    ' . ($isLoadOnceActive ? 'window.sessionStorage.setItem("gamadsmbai_popup_ad_loaded", "true");' : '') . '
                                }
                            }
                        });
                    });
                ' . ($isScrollActive ?
                    ' };
                });'
                    : '}, ' . $DelayOrScroll . '000);') . '
                document.querySelectorAll("span.close-btn")?.forEach((e)=>e.addEventListener("click", function () {
                    createElementPop.style.display = "none";
                    createElementPop.innerHTML = "";
                    createElementPop.setAttribute("id", "ad-closed");
                })
                );
                });
            })();
            </script>';
        } else if ($ad->ad_type === 'flying_carpet') {
            $html = '<div id="gamadsmb_flying_carpet_container"> <!-- GAM Press Placeholder --> </div>';
        } else {
            $html = '<div class="gam-ad-unit" data-unit="' . esc_attr($ad->gam_ad_unit) . '"> <!-- GAM Press Placeholder --> </div>';
        }
    }

    // If show_once is enabled, set a cookie for 24 hours
    // if (! empty($ad->show_once) && $ad->show_once == 1) {
    //     $cookie_key = 'gam_ad_shown_' . $ad->id;
    //     if (! headers_sent()) {
    //         setcookie($cookie_key, 1, time() + 86400, COOKIEPATH, COOKIE_DOMAIN);
    //     } else {
    //         // Fallback for cases when headers are already sent
    //         echo "<script>document.cookie='{$cookie_key}=1;path=/;max-age=" . 86400 . "';</script>";
    //     }
    // }

    return $html;
}


/**
 * Safely outputs or returns ad HTML content.
 *
 * Allows a limited set of tags, including <script> for Google Ad Manager or ad network code.
 * Inline <script> content is sanitized using a regex fallback.
 *
 * @param string $content The ad HTML content.
 * @param bool   $echo    Whether to echo (true) or return (false) the sanitized content.
 * @return string|null
 */
function gamadsmbai_output_ad_html($content, $echo = true)
{
    if (empty($content)) {
        return;
    }
    /**
     * 1. Skip sanitization completely for admins OR trusted roles
     *    This matches how classic WP editors bypass kses.
     */
    if (current_user_can('unfiltered_html')) {
        if ($echo) {
            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Skiping the senitization if user is admin
            echo $content;
            return null;
        }
        return $content;
    }

    // 1. Extract all script tags FIRST (before wp_kses)
    $scripts = [];
    $styles = [];
    if (preg_match_all('#<script\b[^>]*>(.*?)</script>#is', $content, $matches)) {
        $scripts = $matches[0];
        $content = preg_replace('#<script\b[^>]*>.*?</script>#is', '', $content);
    }
    if (preg_match_all('#<style\b[^>]*>.*?</style>#is', $content, $m)) {
        $styles  = $m[0];
        $content = preg_replace('#<style\b[^>]*>.*?</style>#is', '', $content);
    }

    // 2. Allowed HTML (WITHOUT scripts now)
    $allowed_tags = [
        'div' => [
            'class' => true,
            'id'    => true,
            'style' => true,
            'data-*' => true,
            'role'    => true,
        ],
        'ins' => [
            'class'          => true,
            'style'          => true,
            'data-ad-client' => true,
            'data-ad-slot'   => true,
            'data-*'         => true,
        ],
        'span' => [
            'class' => true,
            'id'    => true,
            'style' => true,
        ],
        // Text & Headings
        'p' => [
            'class' => true,
            'id'    => true,
            'style' => true,
        ],

        'h1' => ['class' => true, 'id' => true, 'style' => true],
        'h2' => ['class' => true, 'id' => true, 'style' => true],
        'h3' => ['class' => true, 'id' => true, 'style' => true],
        'h4' => ['class' => true, 'id' => true, 'style' => true],
        'h5' => ['class' => true, 'id' => true, 'style' => true],
        'h6' => ['class' => true, 'id' => true, 'style' => true],

        // Text Formatting
        'b' => true,
        'strong' => true,
        'i' => true,
        'em' => true,
        'u' => true,
        'small' => true,
        'mark' => true,
        'del' => true,
        'sup' => true,
        'sub' => true,

        // Lists
        'ul' => ['class' => true, 'style' => true],
        'ol' => ['class' => true, 'style' => true],
        'li' => ['class' => true, 'style' => true],

        // Line breaks
        'br' => true,
        'hr' => ['class' => true, 'style' => true],

        // Links (SAFE clickable ads)
        'a' => [
            'href'   => true,
            'target' => true,
            'rel'    => true,
            'class'  => true,
            'id'     => true,
            'style'  => true,
            'title'  => true,
        ],

        // Images (SAFE)
        'img' => [
            'src'     => true,
            'alt'     => true,
            'width'   => true,
            'height'  => true,
            'loading' => true,
            'class'   => true,
            'id'      => true,
            'style'   => true,
            'srcset'  => true,
            'sizes'   => true,
        ],

        // Video (SAFE without JS)
        'video' => [
            'src'      => true,
            'controls' => true,
            'autoplay' => true,
            'muted'    => true,
            'loop'     => true,
            'poster'   => true,
            'width'    => true,
            'height'   => true,
            'class'    => true,
            'style'    => true,
            'playsinline' => true,
        ],

        'source' => [
            'src'  => true,
            'type' => true,
        ],

        // Tables
        'table' => ['class' => true, 'style' => true],
        'thead' => true,
        'tbody' => true,
        'tfoot' => true,
        'tr'    => true,
        'th'    => ['colspan' => true, 'rowspan' => true],
        'td'    => ['colspan' => true, 'rowspan' => true],

        // Ad-specific
        'ins' => [
            'class'          => true,
            'style'          => true,
            'data-ad-client' => true,
            'data-ad-slot'   => true,
            'data-*'         => true,
        ],
    ];

    // 3. Sanitize ONLY NON-JS HTML
    $safe_html = wp_kses($content, $allowed_tags);

    /**
     * WordPress strips inline <script> content by default.
     * We allow it here *only* for known ad network tags.
     * This regex safely restores <script>...</script> blocks that were stripped.
     */
    // 4. Restore SAFE <style> blocks
    foreach ($styles as $style_tag) {
        if (preg_match('#<style\b[^>]*>(.*?)</style>#is', $style_tag, $m)) {
            $css = $m[1];
            // Basic CSS safety check (blocks JS-injection vectors)
            if (! preg_match('/expression|javascript:|@import/i', $css)) {
                $safe_html .= '<style>' . $css . '</style>';
            }
        }
    }
    // 4. Restore ONLY VERIFIED SAFE SCRIPTS (RAW, UNESCAPED)
    foreach ($scripts as $script_tag) {
        // External script
        if (preg_match('/src=["\']([^"\']+)["\']/', $script_tag, $src_match)) {
            $src = esc_url($src_match[1]);
            // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript -- GPT/ad scripts must remain inline per Google guidelines.
            $safe_html .= '<script src="' . $src . '" async></script>';
            continue;
        }
        // Inline ad script
        if (preg_match('#<script\b[^>]*>(.*?)</script>#is', $script_tag, $inline_match)) {
            $inline_js = $inline_match[1];
            // Allow only ad-related libraries
            if (preg_match('/googletag|adsbygoogle|gpt|pubads|defineSlot/i', $inline_js)) {
                // IMPORTANT: DO NOT esc_html, esc_js, or wp_kses this
                $safe_html .= '<script>' . $inline_js . '</script>';
            }
        }
    }

    if ($echo) {
        // or, if $safe_html already sanitized
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Safe HTML already sanitized via wp_kses_post().
        echo $safe_html; // Safe to echo sanitized ad content
        return null;
    }

    return $safe_html;
}
