<?php
/**
 * Player Position Manager
 *
 * Handles player positioning using WordPress hooks and filters
 * instead of CSS class detection for universal compatibility
 *
 * @package    TTSWP
 * @subpackage Mementor_TTS/includes
 * @since      1.5.0
 */

class Mementor_TTS_Player_Position_Manager {
    
    /**
     * Singleton instance
     * @var Mementor_TTS_Player_Position_Manager
     */
    private static $instance = null;
    
    /**
     * Track if player has been displayed to prevent duplicates
     * @var bool
     */
    private $player_displayed = false;
    
    /**
     * Static tracker for players added per post
     * @var array
     */
    private static $players_added = array();
    
    /**
     * Track if hooks have been initialized
     * @var bool
     */
    private static $hooks_initialized = false;
    
    /**
     * Current position setting
     * @var string
     */
    private $current_position;
    
    /**
     * Reference to public class instance
     * @var Mementor_TTS_Public
     */
    private $public_instance;
    
    /**
     * Current post ID being processed
     * @var int
     */
    private $current_post_id = 0;
    
    /**
     * Initialize the position manager
     * 
     * @param Mementor_TTS_Public $public_instance Reference to public class
     */
    private function __construct($public_instance) {
        $this->public_instance = $public_instance;
    }
    
    /**
     * Get singleton instance
     * 
     * @param Mementor_TTS_Public $public_instance Reference to public class
     * @return Mementor_TTS_Player_Position_Manager
     */
    public static function get_instance($public_instance = null) {
        if (self::$instance === null) {
            if ($public_instance === null) {
                return null;
            }
            self::$instance = new self($public_instance);
        }
        return self::$instance;
    }
    
    /**
     * Initialize hooks based on selected position
     */
    public function init() {
        // Prevent multiple initializations
        if (self::$hooks_initialized) {
            if (defined('WP_DEBUG') && WP_DEBUG) {
                error_log('TTS Player Position Manager: Hooks already initialized, skipping');
            }
            return;
        }
        
        self::$hooks_initialized = true;
        
        $this->current_position = get_option('mementor_tts_player_position', 'after_content');
        
        // Debug log the current position
        // Log only once per request
        // static $position_logged = false;
        // if (defined('WP_DEBUG') && WP_DEBUG && !$position_logged) {
        //     error_log('TTS Player Position Manager: Current position = ' . $this->current_position);
        //     $position_logged = true;
        // }
        
        // Register hooks based on selected position
        switch($this->current_position) {
            case 'before_title':
                // Legacy support - treat as after_title_before_excerpt
                add_filter('the_content', array($this, 'maybe_inject_at_beginning'), 20);
                break;
                
            case 'after_title_before_excerpt':
                // Hook into the_content with standard priority to work with page builders
                add_filter('the_content', array($this, 'maybe_inject_at_beginning'), 20);
                break;
                
            case 'before_excerpt':
            case 'after_excerpt':
                // Hook into both the_excerpt and get_the_excerpt for broad theme compatibility
                if ($this->current_position === 'before_excerpt') {
                    add_filter('the_excerpt', array($this, 'maybe_prepend_before_excerpt'), 20);
                    add_filter('get_the_excerpt', array($this, 'maybe_prepend_before_excerpt'), 20);
                } else {
                    add_filter('the_excerpt', array($this, 'maybe_append_after_excerpt'), 20);
                    add_filter('get_the_excerpt', array($this, 'maybe_append_after_excerpt'), 20);
                }
                // Elementor: hook into widget render to inject around the Post Excerpt widget
                if (defined('ELEMENTOR_VERSION')) {
                    add_filter('elementor/widget/render_content', array($this, 'maybe_inject_excerpt_elementor'), 10, 2);
                }
                break;

            case 'after_title_after_excerpt':
                // Hook into the_content with early priority, but will check for excerpt
                add_filter('the_content', array($this, 'maybe_inject_after_excerpt_check'), 10);
                break;
                
            case 'after_content':
                add_filter('the_content', array($this, 'maybe_append_to_content'), 999);
                break;

            case 'sticky_footer':
                if ( ! ttswp_has_paid_plan() ) {
                    // Downgraded user fallback — inline player at end of content
                    add_filter('the_content', array($this, 'maybe_append_to_content'), 999);
                    break;
                }
                // PRO: sticky footer only, no inline player
                add_action('wp_footer', array($this, 'render_sticky_footer'));
                break;

            default:
                // Default to after content if position is not recognized
                if (defined('WP_DEBUG') && WP_DEBUG) {
                    error_log('TTS Player Position Manager: Unrecognized position "' . $this->current_position . '", defaulting to after_content');
                }
                add_filter('the_content', array($this, 'maybe_append_to_content'), 999);
                break;
        }
        
        // Product-specific player placement (overrides global position for products)
        if (class_exists('WooCommerce')) {
            $product_short_desc = get_option('mementor_tts_product_player_short_desc', 'disabled');
            $product_long_desc = get_option('mementor_tts_product_player_long_desc', 'before');

            if ($product_short_desc !== 'disabled' || $product_long_desc !== 'disabled') {
                // Override or hide player label on product pages
                $hide_label = get_option('mementor_tts_product_hide_label', 0);
                if ($hide_label) {
                    add_filter('pre_option_mementor_tts_show_player_label', array($this, 'hide_product_player_label'));
                } else {
                    $product_label = get_option('mementor_tts_product_player_label', '');
                    if (!empty($product_label)) {
                        add_filter('pre_option_mementor_tts_player_label', array($this, 'override_product_player_label'));
                    }
                }
            }

            if ($product_short_desc !== 'disabled') {
                // Classic themes: woocommerce_short_description filter
                add_filter('woocommerce_short_description', array($this, 'maybe_inject_product_short_desc'), 20);
                // Block themes: inject around the post-excerpt block
                add_filter('render_block', array($this, 'maybe_inject_product_block'), 10, 2);
            }
            if ($product_long_desc !== 'disabled') {
                add_filter('the_content', array($this, 'maybe_inject_product_long_desc'), 15);
            }
        }

        // Always provide manual placement options
        add_shortcode('tts_player', array($this, 'player_shortcode'));
        add_action('mementor_tts_player', array($this, 'display_player_action'));
        
        // Custom hooks for theme developers
        add_action('mementor_tts_before_title', array($this, 'custom_position_before_title'));
        add_action('mementor_tts_after_title', array($this, 'custom_position_after_title'));
        add_action('mementor_tts_after_excerpt', array($this, 'custom_position_after_excerpt'));
        add_action('mementor_tts_after_content', array($this, 'custom_position_after_content'));
        
        // Reset player state on each new post
        add_action('the_post', array($this, 'reset_player_state'));

        // Add filter to clean up p tags around player
        add_filter('the_content', array($this, 'cleanup_player_p_tags'), 9999);

        // Strip player HTML from excerpts as a safety net (but not when player is placed in excerpt)
        if ($this->current_position !== 'before_excerpt' && $this->current_position !== 'after_excerpt') {
            add_filter('get_the_excerpt', array($this, 'strip_player_from_excerpt'), 9999);
            add_filter('the_excerpt', array($this, 'strip_player_from_excerpt'), 9999);
        }
    }
    
    /**
     * Clean up p tags around and inside player
     */
    public function cleanup_player_p_tags($content) {
        // First, extract all player containers to protect them
        $pattern = '#(<div class="mementor-tts-player-wrapper">.*?</div><!-- TTS_PLAYER_END -->)#s';
        $players = array();
        
        // Replace players with placeholders and clean them
        if (preg_match_all($pattern, $content, $matches)) {
            foreach ($matches[0] as $index => $player_html) {
                // Remove all p tags from inside the player
                $clean_player = str_replace(array('<p>', '</p>'), '', $player_html);
                
                // Replace the player with a placeholder
                $placeholder = '<!--TTS_PLAYER_PLACEHOLDER_' . $index . '-->';
                $content = str_replace($player_html, $placeholder, $content);
                
                // Store the cleaned player
                $players[$index] = $clean_player;
            }
            
            // Remove p tags around placeholders
            $content = preg_replace('/<p>\s*(<!--TTS_PLAYER_PLACEHOLDER_\d+-->)\s*<\/p>/', '$1', $content);
            
            // Restore the cleaned players
            foreach ($players as $index => $clean_player) {
                $placeholder = '<!--TTS_PLAYER_PLACEHOLDER_' . $index . '-->';
                $content = str_replace($placeholder, $clean_player, $content);
            }
        }
        
        return $content;
    }

    /**
     * Strip player HTML from excerpts
     * This is a safety net to ensure player never appears in excerpts
     *
     * @param string $excerpt The excerpt content
     * @return string Excerpt with player HTML removed
     */
    public function strip_player_from_excerpt($excerpt) {
        if (empty($excerpt)) {
            return $excerpt;
        }

        // Remove all TTS player HTML and related elements
        $patterns = array(
            '#<div[^>]*class="[^"]*mementor-tts-player[^"]*"[^>]*>.*?</div>#si',
            '#<div[^>]*class="[^"]*mementor-tts-player-wrapper[^"]*"[^>]*>.*?</div>#si',
            '#<div[^>]*class="[^"]*mementor-tts-player-container[^"]*"[^>]*>.*?</div>#si',
            '#<audio[^>]*class="[^"]*mementor-tts-audio[^"]*"[^>]*>.*?</audio>#si',
            '#<!--\s*TTS_PLAYER_START.*?-->#si',
            '#<!--\s*TTS_PLAYER_END\s*-->#si',
        );

        foreach ($patterns as $pattern) {
            $excerpt = preg_replace($pattern, '', $excerpt);
        }

        // Clean up any leftover whitespace
        $excerpt = trim($excerpt);

        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log('TTS: Stripped player from excerpt');
        }

        return $excerpt;
    }

    /**
     * Reset player state for each post
     */
    public function reset_player_state($post) {
        if ($post && isset($post->ID)) {
            // Only reset if we're moving to a different post
            if ($this->current_post_id !== $post->ID) {
                $this->player_displayed = false;
                $this->current_post_id = $post->ID;
            }
        }
    }
    
    /**
     * Check if this is an Elementor page
     * 
     * @return bool
     */
    private function is_elementor_page() {
        if (!defined('ELEMENTOR_VERSION')) {
            return false;
        }
        
        $post_id = get_the_ID();
        if (!$post_id) {
            return false;
        }
        
        // Check if built with Elementor
        return get_post_meta($post_id, '_elementor_edit_mode', true) === 'builder';
    }
    
    /**
     * Check if player should be displayed
     * 
     * @param string $context Current filter context
     * @return bool
     */
    private function should_display_player($context = '') {
        // Don't fold player markup (and its attribution popup) into the
        // rendered content while ttswp_render_content_full() is applying
        // the_content for TTS extraction; the audio would read the popup.
        if (function_exists('ttswp_is_extracting_for_tts') && ttswp_is_extracting_for_tts()) {
            return false;
        }

        // Prevent duplicates
        if ($this->player_displayed) {
            return false;
        }
        
        // For title context, add extra checks to prevent multiple calls
        if ($context === 'title') {
            // Check if this is being called from a widget or menu
            if (did_action('dynamic_sidebar') || doing_filter('wp_nav_menu_items')) {
                return false;
            }
            
            // Check for specific filter depth to avoid nested calls
            global $wp_current_filter;
            $title_filter_count = 0;
            foreach ($wp_current_filter as $filter) {
                if ($filter === 'the_title') {
                    $title_filter_count++;
                }
            }
            // Only process the first the_title call
            if ($title_filter_count > 1) {
                return false;
            }
        }
        
        // Check if we're in the right context
        // For excerpt context, relax the loop checks since Elementor and page builders
        // use their own loops but still display on singular pages
        if ($context === 'product') {
            if (!is_singular('product')) {
                return false;
            }
        } elseif ($context === 'excerpt') {
            if (!is_singular()) {
                return false;
            }
        } elseif (!is_singular() || !is_main_query() || !in_the_loop()) {
            return false;
        }
        
        // Get post ID
        $post_id = get_the_ID();
        if (!$post_id) {
            return false;
        }
        
        // Check static tracker to prevent multiple players per post
        if (isset(self::$players_added[$post_id])) {
            return false;
        }
        
        // Check if this post type is enabled
        $enabled_post_types = get_option('mementor_tts_post_types', array('post', 'page'));
        if (!in_array(get_post_type($post_id), $enabled_post_types)) {
            return false;
        }
        
        // Check if player is disabled for this specific post
        $player_disabled = get_post_meta($post_id, '_mementor_tts_disable_player', true);
        if ($player_disabled === '1' || $player_disabled === 'yes') {
            return false;
        }
        
        // Check if the post content has the tts_player shortcode
        $post = get_post($post_id);
        if ($post && has_shortcode($post->post_content, 'tts_player')) {
            if (defined('WP_DEBUG') && WP_DEBUG) {
                error_log('TTS: Shortcode [tts_player] found in content - skipping auto player');
            }
            return false;
        }
        
        // Check if audio exists
        $audio_url = '';
        if ($this->public_instance && method_exists($this->public_instance, 'get_audio_url')) {
            $audio_url = $this->public_instance->get_audio_url($post_id);
        }
        
        // Check if auto-add player is enabled (PRO feature check)
        // Note: Using the correct option name for auto-generation
        $auto_add = get_option('mementor_tts_automatically_add_audio', '0') === '1';
        $is_pro = ttswp_has_paid_plan();
        
        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log('TTS: Post ID ' . $post_id . ' - Audio URL: ' . ($audio_url ? 'EXISTS' : 'NOT FOUND'));
            error_log('TTS: Auto-add player setting: ' . ($auto_add ? 'ENABLED' : 'DISABLED'));
            error_log('TTS: Is PRO version: ' . ($is_pro ? 'YES' : 'NO'));
        }
        
        // Don't show player if no audio exists
        if (!$audio_url) {
            // Only allow auto-add if this is the PRO version
            if (!$auto_add || !$is_pro) {
                if (defined('WP_DEBUG') && WP_DEBUG) {
                    error_log('TTS: No audio found and auto-add disabled or not PRO - not showing player');
                }
                return false;
            }
        }
        
        return true;
    }
    
    /**
     * Get player HTML
     * 
     * @param int $post_id Post ID
     * @return string Player HTML
     */
    private function get_player_html($post_id = null) {
        if (!$post_id) {
            $post_id = get_the_ID();
        }
        
        // Generate player using public instance method
        $player_html = $this->public_instance->get_player_html($post_id, $this->current_position);
        
        if ($player_html) {
            $this->player_displayed = true;
            // Mark this post as having a player
            if ($post_id) {
                self::$players_added[$post_id] = true;
            }
        }
        
        return $player_html;
    }

    /**
     * Inject player into WooCommerce short description.
     *
     * @param string $description The short description HTML.
     * @return string Modified description with player.
     */
    public function maybe_inject_product_short_desc($description) {
        if (!is_product() || !is_singular('product')) {
            return $description;
        }

        if (!$this->should_display_player('product')) {
            return $description;
        }

        $player = $this->get_player_html();
        if (!$player) {
            return $description;
        }

        $position = get_option('mementor_tts_product_player_short_desc', 'disabled');
        $wrapped = '<div class="mementor-tts-player-wrapper mementor-tts-product-player">' . $player . '</div>';

        if ($position === 'before') {
            return $wrapped . $description;
        } else {
            return $description . $wrapped;
        }
    }

    /**
     * Block theme fallback: inject player around the post-excerpt block
     * on WooCommerce product pages. This fires for each rendered block,
     * and only acts on core/post-excerpt when on a singular product page
     * and the classic woocommerce_short_description hook hasn't already
     * placed the player.
     *
     * @param string $block_content The rendered block HTML.
     * @param array  $block         The parsed block data.
     * @return string Modified block HTML with player.
     */
    public function maybe_inject_product_block($block_content, $block) {
        // Only target the post-excerpt block (short description)
        if ($block['blockName'] !== 'core/post-excerpt') {
            return $block_content;
        }

        // Only on product pages
        if (!is_singular('product')) {
            return $block_content;
        }

        // If the classic short_desc hook already placed the player, skip
        if ($this->player_displayed) {
            return $block_content;
        }

        $post_id = get_the_ID();
        if (!$post_id || isset(self::$players_added[$post_id])) {
            return $block_content;
        }

        if (!$this->should_display_player('product')) {
            return $block_content;
        }

        $player = $this->get_player_html();
        if (!$player) {
            return $block_content;
        }

        $position = get_option('mementor_tts_product_player_short_desc', 'disabled');
        $wrapped = '<div class="mementor-tts-player-wrapper mementor-tts-product-player">' . $player . '</div>';

        if ($position === 'before') {
            return $wrapped . $block_content;
        } else {
            return $block_content . $wrapped;
        }
    }

    /**
     * Inject player into WooCommerce product long description (the_content on product pages).
     *
     * @param string $content The content HTML.
     * @return string Modified content with player.
     */
    public function maybe_inject_product_long_desc($content) {
        if (!is_singular('product')) {
            return $content;
        }

        if (!$this->should_display_player('product')) {
            return $content;
        }

        $player = $this->get_player_html();
        if (!$player) {
            return $content;
        }

        $position = get_option('mementor_tts_product_player_long_desc', 'before');
        $wrapped = '<div class="mementor-tts-player-wrapper mementor-tts-product-player">' . $player . '</div>';

        if ($position === 'before') {
            return $wrapped . $content;
        } else {
            return $content . $wrapped;
        }
    }

    /**
     * Override the player label text on product pages.
     *
     * @param string $label The current label text.
     * @return string The product-specific label or the original.
     */
    public function override_product_player_label($value) {
        if (!is_singular('product')) {
            return false; // Return false to let get_option proceed normally
        }

        $product_label = get_option('mementor_tts_product_player_label', '');
        return !empty($product_label) ? $product_label : false;
    }

    /**
     * Hide the player label on product pages.
     *
     * @param mixed $value The current show_player_label option value.
     * @return string '0' on product pages to hide the label.
     */
    public function hide_product_player_label($value) {
        if (!is_singular('product')) {
            return false; // Return false to let get_option proceed normally
        }
        return '0';
    }

    /**
     * Prepend player before excerpt
     *
     * @param string $excerpt The excerpt content.
     * @return string Excerpt with player prepended.
     */
    public function maybe_prepend_before_excerpt($excerpt) {
        if ($this->should_display_player('excerpt')) {
            $player_html = $this->get_player_html();
            if ($player_html) {
                $protected_player = '<div class="mementor-tts-player-wrapper">' . $player_html . '</div><!-- TTS_PLAYER_END -->';
                return $protected_player . $excerpt;
            }
        }

        return $excerpt;
    }

    /**
     * Append player after excerpt
     *
     * @param string $excerpt The excerpt content.
     * @return string Excerpt with player appended.
     */
    public function maybe_append_after_excerpt($excerpt) {
        if ($this->should_display_player('excerpt')) {
            $player_html = $this->get_player_html();
            if ($player_html) {
                $protected_player = '<div class="mementor-tts-player-wrapper">' . $player_html . '</div><!-- TTS_PLAYER_END -->';
                return $excerpt . $protected_player;
            }
        }

        return $excerpt;
    }
    
    /**
     * Inject player before/after Elementor Post Excerpt widget
     *
     * @param string $content Widget rendered content.
     * @param \Elementor\Widget_Base $widget Widget instance.
     * @return string Modified content.
     */
    public function maybe_inject_excerpt_elementor($content, $widget) {
        // Only target the Post Excerpt widget
        if ($widget->get_name() !== 'theme-post-excerpt') {
            return $content;
        }

        // Skip in Elementor editor
        if (class_exists('\Elementor\Plugin') && \Elementor\Plugin::$instance->editor->is_edit_mode()) {
            return $content;
        }

        if ($this->should_display_player('excerpt')) {
            $player_html = $this->get_player_html();
            if ($player_html) {
                $protected_player = '<div class="mementor-tts-player-wrapper">' . $player_html . '</div><!-- TTS_PLAYER_END -->';

                if ($this->current_position === 'before_excerpt') {
                    return $protected_player . $content;
                } else {
                    return $content . $protected_player;
                }
            }
        }

        return $content;
    }

    /**
     * Prepend to content when position is after excerpt
     */
    public function maybe_prepend_to_content_after_excerpt($content) {
        // Only use this if excerpt is not displayed
        if (!has_excerpt() && $this->should_display_player('content')) {
            $player_html = $this->get_player_html();
            if ($player_html) {
                return $player_html . $content;
            }
        }
        
        return $content;
    }
    
    /**
     * Append player to content
     */
    public function maybe_append_to_content($content) {
        // Skip product pages when product-specific placement is configured
        if (is_singular('product') && class_exists('WooCommerce')) {
            $product_short = get_option('mementor_tts_product_player_short_desc', 'disabled');
            $product_long = get_option('mementor_tts_product_player_long_desc', 'before');
            if ($product_short !== 'disabled' || $product_long !== 'disabled') {
                return $content;
            }
        }

        // Don't inject player during excerpt generation
        if (doing_filter('get_the_excerpt') || doing_filter('the_excerpt')) {
            return $content;
        }

        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log('TTS: maybe_append_to_content called - THIS SHOULD NOT HAPPEN FOR before_title!');
            error_log('TTS: Current position in append: ' . $this->current_position);
        }

        if ($this->should_display_player('content')) {
            $player_html = $this->get_player_html();
            if ($player_html) {
                // Wrap in HTML comment to prevent wpautop from adding p tags
                $protected_player = '<!-- wp:html -->' . $player_html . '<!-- /wp:html -->';
                return $content . $protected_player;
            }
        }
        
        return $content;
    }
    
    
    /**
     * Inject player at the beginning of content (after_title_before_excerpt)
     */
    public function maybe_inject_at_beginning($content) {
        // Skip product pages when product-specific placement is configured
        if (is_singular('product') && class_exists('WooCommerce')) {
            $product_short = get_option('mementor_tts_product_player_short_desc', 'disabled');
            $product_long = get_option('mementor_tts_product_player_long_desc', 'before');
            if ($product_short !== 'disabled' || $product_long !== 'disabled') {
                return $content;
            }
        }

        // Allow developers to explicitly prevent player injection
        // Usage: add_filter('mementor_tts_allow_player_injection', '__return_false');
        if (!apply_filters('mementor_tts_allow_player_injection', true, $content, get_the_ID())) {
            if (defined('WP_DEBUG') && WP_DEBUG) {
                error_log('TTS: Skipping player injection - disabled by filter');
            }
            return $content;
        }

        // IMPORTANT: Don't inject player during excerpt generation
        // This prevents the player from appearing in post excerpts on archive pages, etc.
        if (doing_filter('get_the_excerpt') || doing_filter('the_excerpt') || doing_filter('wp_trim_excerpt')) {
            if (defined('WP_DEBUG') && WP_DEBUG) {
                error_log('TTS: Skipping player injection - in excerpt context');
            }
            return $content;
        }

        // Additional check: Look at the call stack to detect if we're being called from excerpt functions
        // This catches cases where get_the_excerpt() is called directly in templates
        $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 15);
        foreach ($backtrace as $trace) {
            if (isset($trace['function']) &&
                (strpos($trace['function'], 'excerpt') !== false ||
                 strpos($trace['function'], 'get_the_excerpt') !== false ||
                 $trace['function'] === 'wp_trim_words')) {
                if (defined('WP_DEBUG') && WP_DEBUG) {
                    error_log('TTS: Skipping player injection - detected excerpt in call stack: ' . $trace['function']);
                }
                return $content;
            }
        }

        // Check if content is suspiciously short (likely an excerpt)
        // Most excerpts are under 200 characters, full content is typically much longer
        $content_length = strlen(strip_tags($content));
        if ($content_length > 0 && $content_length < 300 && !is_admin()) {
            if (defined('WP_DEBUG') && WP_DEBUG) {
                error_log('TTS: Skipping player injection - content too short (' . $content_length . ' chars), likely an excerpt');
            }
            return $content;
        }

        // Check if player is already in content
        if (strpos($content, 'mementor-tts-player-container') !== false) {
            if (defined('WP_DEBUG') && WP_DEBUG) {
                error_log('TTS: Player already in content, skipping injection');
            }
            return $content;
        }

        // Debug log
        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log('TTS: maybe_inject_at_beginning called for position: ' . $this->current_position);
            error_log('TTS: Content length: ' . strlen($content));
            error_log('TTS: is_singular: ' . (is_singular() ? 'yes' : 'no'));
            error_log('TTS: is_main_query: ' . (is_main_query() ? 'yes' : 'no'));
            error_log('TTS: in_the_loop: ' . (in_the_loop() ? 'yes' : 'no'));
        }

        // Extra check to ensure we're in the right context
        if (!is_singular() || !is_main_query() || !in_the_loop()) {
            if (defined('WP_DEBUG') && WP_DEBUG) {
                error_log('TTS: Skipping - context check failed');
            }
            return $content;
        }
        
        if ($this->should_display_player('content')) {
            $player_html = $this->get_player_html();
            if (defined('WP_DEBUG') && WP_DEBUG) {
                error_log('TTS: should_display_player returned true');
                error_log('TTS: Player HTML length: ' . strlen($player_html));
            }
            if ($player_html) {
                if (defined('WP_DEBUG') && WP_DEBUG) {
                    error_log('TTS: Adding player at beginning of content');
                    error_log('TTS: Post ID: ' . get_the_ID());
                }
                // Add a unique marker to track if our content is being preserved
                $marker = '<!-- TTS_PLAYER_START_' . uniqid() . ' -->';
                
                // Use a div wrapper to prevent wpautop from adding p tags
                $protected_player = $marker . '<div class="mementor-tts-player-wrapper">' . $player_html . '</div><!-- TTS_PLAYER_END -->';
                $new_content = $protected_player . $content;
                
                if (defined('WP_DEBUG') && WP_DEBUG) {
                    error_log('TTS: Content before: ' . substr($content, 0, 50) . '...');
                    error_log('TTS: Content after: ' . substr($new_content, 0, 200) . '...');
                    error_log('TTS: Marker added: ' . $marker);
                    
                    // Add a check to see if content is being filtered multiple times
                    add_action('shutdown', function() use ($marker) {
                        $final_content = ob_get_contents();
                        if (strpos($final_content, $marker) !== false) {
                            error_log('TTS: Marker FOUND in final output');
                        } else {
                            error_log('TTS: Marker NOT FOUND in final output - content was replaced!');
                        }
                    });
                }
                
                return $new_content;
            } else {
                if (defined('WP_DEBUG') && WP_DEBUG) {
                    error_log('TTS: No player HTML generated');
                }
            }
        } else {
            if (defined('WP_DEBUG') && WP_DEBUG) {
                error_log('TTS: should_display_player returned false');
            }
        }
        
        return $content;
    }
    
    /**
     * Inject player after excerpt check (after_title_after_excerpt)
     */
    public function maybe_inject_after_excerpt_check($content) {
        // Skip product pages when product-specific placement is configured
        if (is_singular('product') && class_exists('WooCommerce')) {
            $product_short = get_option('mementor_tts_product_player_short_desc', 'disabled');
            $product_long = get_option('mementor_tts_product_player_long_desc', 'before');
            if ($product_short !== 'disabled' || $product_long !== 'disabled') {
                return $content;
            }
        }

        // Don't inject player during excerpt generation
        if (doing_filter('get_the_excerpt') || doing_filter('the_excerpt')) {
            return $content;
        }

        if ($this->should_display_player('content')) {
            $player_html = $this->get_player_html();
            if ($player_html) {
                // For Elementor pages, find the first complete text-editor widget
                if (strpos($content, 'elementor-widget-text-editor') !== false) {
                    // Match the first complete Elementor text-editor widget
                    // This pattern captures from the opening div to the closing div of the widget
                    $pattern = '/<div[^>]*elementor-widget-text-editor[^>]*>.*?<\/div>/s';

                    if (preg_match($pattern, $content, $matches, PREG_OFFSET_CAPTURE)) {
                        // Get the position where the first widget ends
                        $widget_end = $matches[0][1] + strlen($matches[0][0]);

                        // Split content at that position
                        $before = substr($content, 0, $widget_end);
                        $after = substr($content, $widget_end);

                        // Wrap in div to prevent wpautop issues
                        $protected_player = '<div class="mementor-tts-player-wrapper">' . $player_html . '</div><!-- TTS_PLAYER_END -->';
                        return $before . $protected_player . $after;
                    }
                }

                // For non-Elementor pages or fallback, inject after first paragraph
                $first_p_close = strpos($content, '</p>');
                if ($first_p_close !== false) {
                    $before = substr($content, 0, $first_p_close + 4);
                    $after = substr($content, $first_p_close + 4);
                    // Wrap in div to prevent wpautop issues
                    $protected_player = '<div class="mementor-tts-player-wrapper">' . $player_html . '</div><!-- TTS_PLAYER_END -->';
                    return $before . $protected_player . $after;
                }

                // Default to beginning if no paragraph found
                $protected_player = '<div class="mementor-tts-player-wrapper">' . $player_html . '</div><!-- TTS_PLAYER_END -->';
                return $protected_player . $content;
            }
        }

        return $content;
    }
    
    /**
     * Shortcode handler
     */
    public function player_shortcode($atts) {
        // Don't render player markup when extracting content for TTS.
        if (function_exists('ttswp_is_extracting_for_tts') && ttswp_is_extracting_for_tts()) {
            return '';
        }

        $atts = shortcode_atts(array(
            'post_id' => get_the_ID(),
            'class' => '',
            'autoplay' => 'false'
        ), $atts, 'tts_player');

        $post_id = absint($atts['post_id']);
        if (!$post_id) {
            return '';
        }
        
        // Check if audio exists
        $audio_url = '';
        if ($this->public_instance && method_exists($this->public_instance, 'get_audio_url')) {
            $audio_url = $this->public_instance->get_audio_url($post_id);
        }

        // Don't show player if no audio exists for this post
        if (!$audio_url) {
            $auto_add = get_option('mementor_tts_automatically_add_audio', '0') === '1';
            $is_pro = ttswp_has_paid_plan();
            if (!$auto_add || !$is_pro) {
                return '';
            }
        }
        
        // Use get_player_html to ensure all settings are applied
        $player_html = $this->public_instance->get_player_html($post_id, 'shortcode');
        
        if (!$player_html) {
            return '';
        }
        
        // Wrap the player in a shortcode-specific container
        $wrapper_html = '<div class="mementor-tts-shortcode-wrapper';
        if ($atts['class']) {
            $wrapper_html .= ' ' . esc_attr($atts['class']);
        }
        $wrapper_html .= '">';
        
        // Update the player container to mark it as shortcode type
        $player_html = str_replace(
            'data-player-type="auto-inserted"',
            'data-player-type="shortcode"',
            $player_html
        );
        
        // Add shortcode class to the container
        $player_html = str_replace(
            'class="mementor-tts-player-container',
            'class="mementor-tts-player-container mementor-tts-shortcode',
            $player_html
        );
        
        $wrapper_html .= $player_html;
        $wrapper_html .= '</div>';
        
        return $wrapper_html;
    }
    
    /**
     * Action hook for manual placement
     */
    public function display_player_action($post_id = null) {
        if (!$post_id) {
            $post_id = get_the_ID();
        }
        
        $audio_url = $this->public_instance->get_audio_url($post_id);
        if ($audio_url) {
            echo '<div class="mementor-tts-player-container mementor-tts-action" data-player-type="action">';
            echo wp_kses_post($this->public_instance->render_player($audio_url, $post_id));
            echo '</div>';
        }
    }
    
    /**
     * Output player for action hooks
     */
    public function output_player_for_action() {
        if ($this->should_display_player('action')) {
            $player_html = $this->get_player_html();
            if ($player_html) {
                echo '<!-- wp:html -->' . $player_html . '<!-- /wp:html -->';
            }
        }
    }
    
    /**
     * Output player before title using loop_start
     */
    public function maybe_output_before_title($wp_query) {
        // Only on main query and singular posts
        if (!$wp_query->is_main_query() || !is_singular()) {
            return;
        }
        
        // Check if we're in the loop
        if (!in_the_loop()) {
            return;
        }
        
        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log('TTS: maybe_output_before_title called');
        }
        
        if ($this->should_display_player('before_title')) {
            $player_html = $this->get_player_html();
            if ($player_html) {
                if (defined('WP_DEBUG') && WP_DEBUG) {
                    error_log('TTS: Outputting player before title');
                }
                // Output the player directly
                echo '<!-- wp:html -->' . $player_html . '<!-- /wp:html -->';
            }
        }
    }
    
    /**
     * Custom position handlers for theme developers
     */
    public function custom_position_before_title() {
        if ($this->current_position === 'before_title' && $this->should_display_player('custom')) {
            echo wp_kses_post($this->get_player_html());
        }
    }
    
    public function custom_position_after_title() {
        if ($this->current_position === 'after_title_before_excerpt' && $this->should_display_player('custom')) {
            echo wp_kses_post($this->get_player_html());
        }
    }
    
    public function custom_position_after_excerpt() {
        if ($this->current_position === 'after_title_after_excerpt' && $this->should_display_player('custom')) {
            echo wp_kses_post($this->get_player_html());
        }
    }
    
    public function custom_position_after_content() {
        if ($this->current_position === 'after_content' && $this->should_display_player('custom')) {
            echo wp_kses_post($this->get_player_html());
        }
    }

    /**
     * Render the sticky footer player via wp_footer.
     * Visible on page load. Close removes it for this page load only.
     */
    public function render_sticky_footer() {
        static $rendered = false;
        if ( $rendered ) {
            return;
        }
        $rendered = true;

        if ( ! is_singular() ) {
            return;
        }

        global $post;
        if ( ! $post ) {
            return;
        }

        $audio_url = $this->public_instance->get_audio_url( $post->ID );
        if ( empty( $audio_url ) ) {
            return;
        }

        $post_title   = get_the_title( $post->ID );
        $show_time    = get_option( 'mementor_tts_show_time', true );
        $show_volume  = get_option( 'mementor_tts_show_volume', true );
        $show_speed   = get_option( 'mementor_tts_speed_control', false );
        $show_download = get_option( 'mementor_tts_show_download', false );
        $show_info    = get_option( 'mementor_tts_show_info', false );
        $autoplay     = get_option( 'mementor_tts_autoplay', false );
        $loop         = get_option( 'mementor_tts_loop', false );
        ?>
        <div id="mementor-tts-sticky-footer" class="mementor-tts-sticky-footer" role="region" aria-label="<?php esc_attr_e('Audio Player', 'text-to-speech-tts'); ?>">
            <div class="mementor-tts-sticky-inner">
                <button class="mementor-tts-sticky-play" aria-label="<?php esc_attr_e('Play', 'text-to-speech-tts'); ?>">
                    <svg class="mementor-tts-sticky-icon-play" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
                        <path d="M8 5v14l11-7z"/>
                    </svg>
                    <svg class="mementor-tts-sticky-icon-pause" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg" style="display:none;">
                        <path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/>
                    </svg>
                </button>
                <div class="mementor-tts-sticky-info">
                    <span class="mementor-tts-sticky-title"><?php echo esc_html( $post_title ); ?></span>
                </div>
                <div class="mementor-tts-sticky-progress-wrap">
                    <?php if ( $show_time ) : ?>
                        <span class="mementor-tts-sticky-time">0:00</span>
                    <?php endif; ?>
                    <?php
                    $progress_type = get_option('mementor_tts_progress_type', 'linear');
                    if ( $progress_type === 'waveform_progress' && ttswp_has_paid_plan() ) : ?>
                        <div class="mementor-tts-sticky-progress-container mementor-tts-waveform" data-progress-type="waveform_progress" data-post-id="<?php echo esc_attr( $post->ID ); ?>"></div>
                    <?php else : ?>
                        <div class="mementor-tts-sticky-progress-container">
                            <div class="mementor-tts-sticky-progress-bar"></div>
                        </div>
                    <?php endif; ?>
                    <?php if ( $show_time ) : ?>
                        <span class="mementor-tts-sticky-duration">0:00</span>
                    <?php endif; ?>
                </div>
                <?php if ( $show_volume ) : ?>
                <button class="mementor-tts-sticky-volume" aria-label="<?php esc_attr_e('Mute', 'text-to-speech-tts'); ?>">
                    <svg class="mementor-tts-sticky-icon-volume-on" width="18" height="18" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
                        <path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/>
                    </svg>
                    <svg class="mementor-tts-sticky-icon-volume-off" width="18" height="18" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg" style="display:none;">
                        <path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"/>
                    </svg>
                </button>
                <?php endif; ?>
                <?php if ( $show_speed ) : ?>
                <button class="mementor-tts-sticky-speed" aria-label="<?php esc_attr_e('Playback speed', 'text-to-speech-tts'); ?>">1x</button>
                <?php endif; ?>
                <?php if ( $show_download ) : ?>
                <a class="mementor-tts-sticky-download" href="<?php echo esc_url( $audio_url ); ?>" download aria-label="<?php esc_attr_e('Download', 'text-to-speech-tts'); ?>">
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
                        <path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/>
                    </svg>
                </a>
                <?php endif; ?>
                <?php if ( $show_info ) : ?>
                <button type="button" class="mementor-tts-info-button" aria-label="<?php esc_attr_e('Information', 'text-to-speech-tts'); ?>" style="padding:0!important;margin:0!important;"><span class="dashicons dashicons-info mementor-dashicons mementor-dashicons-info"></span></button>
                <?php endif; ?>
                <button class="mementor-tts-sticky-close" aria-label="<?php esc_attr_e('Close', 'text-to-speech-tts'); ?>">
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
                        <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
                    </svg>
                </button>
            </div>
            <audio preload="metadata"<?php echo $loop ? ' loop' : ''; ?>>
                <source src="<?php echo esc_url( $audio_url ); ?>" type="audio/mpeg">
            </audio>
            <?php if ( $show_info ) : ?>
                <div class="mementor-tts-info-popup" style="display: none;">
                    <button type="button" class="mementor-tts-info-close" aria-label="<?php esc_attr_e( 'Close', 'text-to-speech-tts' ); ?>" style="padding:0!important;margin:0!important;">&times;</button>
                    <p><?php echo mementor_tts_info_popup_html(); ?></p>
                </div>
            <?php endif; ?>
        </div>
        <?php
    }
}