<?php
/**
 * Shortcode context tracker.
 * Prevents badges from being injected inside blocked shortcodes.
 */

defined( 'ABSPATH' ) || exit;

/**
 * List of shortcodes that should never receive product badges.
 *
 * Example — add more shortcodes to block:
 *
 *   add_filter( 'cpbw_blocked_shortcodes', function( $shortcodes ) {
 *       $shortcodes[] = 'my_custom_slider';
 *       $shortcodes[] = 'another_plugin_widget';
 *       return $shortcodes;
 *   } );
 *
 * @return array
 */
function cpbw_get_blocked_shortcodes() {
    return (array) apply_filters( 'cpbw_blocked_shortcodes', [
        'cusrev_reviews_slider',
        'cusrev_reviews_grid'
    ] );
}

/**
 * List of shortcodes that are explicitly allowed to show badges.
 * Overrides cpbw_blocked_shortcodes for specific tags.
 * By default empty — nothing is allowed unless opted-in.
 *
 * Example — allow badges in specific shortcodes:
 *
 *   add_filter( 'cpbw_allowed_badge_shortcodes', function( $shortcodes ) {
 *       $shortcodes[] = 'cusrev_reviews_slider';
 *       $shortcodes[] = 'my_custom_slider';
 *       return $shortcodes;
 *   } );
 *
 * @return array
 */
function cpbw_get_allowed_badge_shortcodes() {
    return (array) apply_filters( 'cpbw_allowed_badge_shortcodes', [] );
}

/**
 * Simple on/off flag to track if we're inside a blocked shortcode.
 * Uses a static variable — no globals needed.
 *
 * @param bool|null $set  true to enter, false to exit, null to read
 * @return bool
 */
function cpbw_shortcode_context( $set = null ) {
    static $inside = false;
    if ( $set !== null ) {
        $inside = $set;
    }
    return $inside;
}

/**
 * Check if badges are allowed inside a specific shortcode tag.
 * A shortcode is allowed if it appears in cpbw_allowed_badge_shortcodes,
 * regardless of whether it is also in cpbw_blocked_shortcodes.
 *
 * @param string $tag Shortcode tag being rendered
 * @return bool
 */
function cpbw_is_badge_allowed_in_shortcode( $tag ) {
    return in_array( $tag, cpbw_get_allowed_badge_shortcodes(), true );
}

/**
 * Set flag ON just before a blocked shortcode renders.
 * Skipped if the tag is explicitly allowed via cpbw_allowed_badge_shortcodes.
 */
add_filter( 'pre_do_shortcode_tag', function( $return, $tag ) {
    if (
        in_array( $tag, cpbw_get_blocked_shortcodes(), true ) &&
        ! cpbw_is_badge_allowed_in_shortcode( $tag )
    ) {
        cpbw_shortcode_context( true );
    }
    return $return;
}, 10, 2 );

/**
 * Set flag OFF after a blocked shortcode finishes rendering.
 * Always resets regardless of allowed/blocked state.
 */
add_filter( 'do_shortcode_tag', function( $output, $tag ) {
    if ( in_array( $tag, cpbw_get_blocked_shortcodes(), true ) ) {
        cpbw_shortcode_context( false );
    }
    return $output;
}, 10, 2 );