<?php
/**
 * Shortcodes Class
 *
 * This class defines all shortcodes used by the plugin.
 *
 * @link       https://mementor.no
 * @since      1.0.0
 *
 * @package    TTSWP
 * @subpackage Mementor_TTS/includes
 */

// If this file is called directly, abort.
if (!defined('ABSPATH')) {
    exit;
}

/**
 * The shortcode functionality of the plugin.
 *
 * Defines the plugin shortcodes and their rendering functions.
 *
 * @package    TTSWP
 * @subpackage Mementor_TTS/includes
 * @author     Mementor <post@mementor.no>
 */
class Mementor_TTS_Shortcodes {

    /**
     * The single instance of the class.
     *
     * @var Mementor_TTS_Shortcodes
     */
    private static $instance = null;

    /**
     * Main Mementor_TTS_Shortcodes Instance.
     *
     * Ensures only one instance of Mementor_TTS_Shortcodes is loaded or can be loaded.
     *
     * @since    1.0.0
     * @param    string    $plugin_name       The name of this plugin.
     * @param    string    $version    The version of this plugin.
     * @return   Mementor_TTS_Shortcodes    Main instance.
     */
    public static function instance($plugin_name = '', $version = '') {
        if (is_null(self::$instance)) {
            self::$instance = new self($plugin_name, $version);
        }
        return self::$instance;
    }

    /**
     * The ID of this plugin.
     *
     * @since    1.0.0
     * @access   private
     * @var      string    $plugin_name    The ID of this plugin.
     */
    private $plugin_name;

    /**
     * The version of this plugin.
     *
     * @since    1.0.0
     * @access   private
     * @var      string    $version    The current version of this plugin.
     */
    private $version;

    /**
     * Track if assets have been enqueued
     *
     * @since    1.0.0
     * @access   private
     * @var      bool    $assets_enqueued    Whether assets have been enqueued
     */
    private static $assets_enqueued = false;

    /**
     * Initialize the class and set its properties.
     *
     * @since    1.0.0
     * @param    string    $plugin_name       The name of this plugin.
     * @param    string    $version    The version of this plugin.
     */
    private function __construct($plugin_name, $version) {
        $this->plugin_name = $plugin_name;
        $this->version = $version;
    }

    /**
     * Register all shortcodes.
     *
     * @since    1.0.0
     */
    public function register_shortcodes() {
        if (!current_theme_supports('mementor-tts')) {
            add_theme_support('mementor-tts');
        }
        
        add_shortcode('mementor-tts', array($this, 'render_tts_shortcode'));
        
        // Debug: Check if shortcode was registered (only log once)
        // static $shortcode_logged = false;
        // if (defined('WP_DEBUG') && WP_DEBUG && !$shortcode_logged) {
        //     error_log('TTS Shortcode: Registered mementor-tts shortcode');
        //     global $shortcode_tags;
        //     if (isset($shortcode_tags['mementor-tts'])) {
        //         error_log('TTS Shortcode: Confirmed registration in shortcode_tags');
        //     }
        //     $shortcode_logged = true;
        // }
        
        // Register assets but don't enqueue yet
        $this->register_shortcode_assets();
    }

    /**
     * Register shortcode assets for later enqueuing.
     *
     * @since    1.0.0
     * @access   private
     */
    private function register_shortcode_assets() {
        // Assets are now registered globally in the main plugin file
        if (!self::$assets_enqueued) {
            // Add script data for mementorTTS (for compatibility)
            wp_localize_script('mementor-tts-player', 'mementorTTS', array(
                'ajaxurl' => admin_url('admin-ajax.php'),
                'nonce' => wp_create_nonce('mementor_tts_nonce'),
                'playerStatsNonce' => wp_create_nonce('mementor_tts_player_stats'),
                'enableStatistics' => get_option('mementor_tts_enable_statistics', 'no'),
                'postId' => get_the_ID(),
                'i18n' => array(
                    'error' => __('Error:', 'text-to-speech-tts'),
                    'generating' => __('Generating audio...', 'text-to-speech-tts'),
                )
            ));
            
            // Add script data
            wp_localize_script('mementor-tts-player', 'mementorTTSPlayer', array(
                'ajaxurl' => admin_url('admin-ajax.php'),
                'nonce' => wp_create_nonce('mementor_tts_nonce'),
                'i18n' => array(
                    'error' => __('Error:', 'text-to-speech-tts'),
                    'generating' => __('Generating audio...', 'text-to-speech-tts'),
                )
            ));
        }
    }

    /**
     * Enqueue shortcode assets when needed.
     *
     * @since    1.0.0
     * @access   private
     * @param    bool    $should_enqueue    Whether assets should be enqueued.
     */
    private function maybe_enqueue_assets($should_enqueue = true) {
        // If assets are already enqueued or shouldn't be enqueued, return early
        if (self::$assets_enqueued || !$should_enqueue) {
            return;
        }

        // Add filter to indicate assets should be loaded
        add_filter('mementor_tts_should_load_assets', '__return_true');

        // Mark assets as enqueued
        self::$assets_enqueued = true;
        
        // Ensure shortcode JS is enqueued
        wp_enqueue_script('mementor-tts-shortcode');

        // Add script data
        wp_localize_script('mementor-tts-shortcode', 'mementorTtsShortcode', array(
            'ajaxurl' => admin_url('admin-ajax.php'),
            'nonce' => wp_create_nonce('mementor_tts_nonce'),
            'i18n' => array(
                'error' => __('Error:', 'text-to-speech-tts'),
                'generating' => __('Generating audio...', 'text-to-speech-tts'),
            ),
            'debug' => (get_option('mementor_tts_debug_mode', '0') === '1') ? '1' : '0'
        ));
    }

    /**
     * Render the text-to-speech shortcode.
     *
     * @since    1.0.0
     * @param    array     $atts    Shortcode attributes.
     * @param    string    $content The shortcode content.
     * @return   string    HTML output for the text-to-speech player.
     */
    public function render_tts_shortcode($atts, $content = '') {
        // Don't render player markup when extracting content for TTS.
        if (function_exists('ttswp_is_extracting_for_tts') && ttswp_is_extracting_for_tts()) {
            return '';
        }

        // Debug output
        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log('TTS Shortcode: render_tts_shortcode called');
            error_log('TTS Shortcode: Attributes: ' . print_r($atts, true));
        }
        
        // Ensure assets are enqueued
        $this->maybe_enqueue_assets();
        
        // Check if we should render the player
        // For shortcodes, we should always render unless in excerpt
        $is_excerpt = doing_filter('get_the_excerpt') || doing_filter('the_excerpt');
        
        if ($is_excerpt) {
            if (defined('WP_DEBUG') && WP_DEBUG) {
                error_log('TTS Shortcode: Not rendering - is in excerpt');
            }
            return '';
        }
        
        // Get player settings
        $player_settings = get_option('mementor_tts_player_settings', array());
        
        // Parse shortcode attributes
        $atts = shortcode_atts(array(
            'label' => '1', // Default to showing label, will be overridden by player settings
            'voice_id' => '', // Add support for voice_id attribute
            'id' => '', // Support for element ID
            'text' => '', // Support for direct text input
            'audio' => '', // Support for pre-generated audio file
            'time_display' => '', // Support for time display option
            'speed_control' => '', // Support for speed control option
            'volume_control' => '', // Support for volume control option
            'download' => '', // Support for download option
            'autoplay' => '', // Support for autoplay option
            'loop' => '', // Support for loop option
            'information' => '', // Support for information option
        ), $atts, 'mementor-tts');
        
        // Get content from either shortcode content or text attribute
        $text_content = !empty($content) ? $content : (!empty($atts['text']) ? $atts['text'] : '');
        
        // If we have a pre-generated audio file, we don't need text content
        if (!empty($atts['audio'])) {
            // Set a placeholder text for pre-generated audio
            if (empty($text_content)) {
                $text_content = 'Audio player';
            }
        } else {
            // Only require text content if we don't have pre-generated audio
            // Debug - Log the raw content
            if (defined('WP_DEBUG') && WP_DEBUG) {
                error_log('TTS Shortcode Raw Content: ' . substr($text_content, 0, 50) . (strlen($text_content) > 50 ? '...' : ''));
                error_log('TTS Shortcode Content Length: ' . strlen($text_content));
            }
            
            // Sanitize content but preserve line breaks
            $text_content = wp_kses_post($text_content);
            
            // Process line breaks consistently
            $text_content = str_replace('\\n', ' -- ', $text_content); // Convert escaped newlines
            $text_content = str_replace(array("\r\n", "\r", "\n"), ' -- ', $text_content); // Convert actual newlines
            $text_content = preg_replace('/\s*--+\s*/', ' -- ', $text_content); // Normalize dashes with spaces
            $text_content = trim($text_content); // Trim whitespace
            
            if (empty($text_content)) {
                if (defined('WP_DEBUG') && WP_DEBUG) {
                    error_log('TTS Shortcode: Empty content after processing and no audio file provided, not rendering player');
                }
                return '';
            }
        }
        
        // Debug - Log the processed content
        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log('TTS Shortcode Processed Content: ' . substr($text_content, 0, 50) . (strlen($text_content) > 50 ? '...' : ''));
        }
        
        // Generate a consistent ID based on content hash
        $content_hash = md5($text_content . $atts['voice_id']);
        $element_uid = !empty($atts['id']) ? sanitize_key($atts['id']) : 'shortcode_' . substr($content_hash, 0, 8);
        $player_id = 'mementor-tts-player-' . $element_uid;
        
        // Get current language code
        $language_code = 'en'; // Default to English
        if (defined('ICL_LANGUAGE_CODE')) {
            $language_code = ICL_LANGUAGE_CODE;
        } else {
            $language_code = get_option('mementor_tts_language', 'en');
        }
        
        // Debug log to help troubleshoot
        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log('TTS Shortcode: Processing shortcode with attributes: ' . print_r($atts, true));
        }
        
        // Check for pre-generated audio file
        $audio_exists = false;
        $file_url = '';
        $upload_dir = wp_upload_dir();
        
        // If audio attribute is provided, use that file
        if (!empty($atts['audio'])) {
            $audio_value = $atts['audio'];

            // Check if it's a full URL (external like CloudFront/S3)
            if (filter_var($audio_value, FILTER_VALIDATE_URL)) {
                $file_url = esc_url($audio_value);
                $audio_exists = true;

                if (defined('WP_DEBUG') && WP_DEBUG) {
                    error_log('TTS Shortcode: Using external audio URL: ' . $file_url);
                }
            } else {
                // Local filename — check uploads directory first
                $audio_filename = sanitize_file_name($audio_value);
                $file_path = $upload_dir['basedir'] . '/text-to-speech-tts/' . $audio_filename;
                $file_url = $upload_dir['baseurl'] . '/text-to-speech-tts/' . $audio_filename;
                $audio_exists = file_exists($file_path);

                // If not found locally, check the shortcode audio map (paid plans store on CDN)
                if (!$audio_exists) {
                    $audio_map = get_option('mementor_tts_shortcode_audio_map', array());
                    if (isset($audio_map[$audio_filename])) {
                        $file_url = $audio_map[$audio_filename];
                        $audio_exists = true;

                        if (defined('WP_DEBUG') && WP_DEBUG) {
                            error_log('TTS Shortcode: Found audio in shortcode map: ' . $file_url);
                        }
                    }
                }

                if (defined('WP_DEBUG') && WP_DEBUG) {
                    error_log('TTS Shortcode: Using audio attribute file: ' . $audio_filename);
                    error_log('TTS Shortcode: Audio ' . ($audio_exists ? 'resolved to: ' . $file_url : 'not found'));
                }
            }

            // If we have an audio file, we don't need text content for generation
            if ($audio_exists && empty($text_content)) {
                $text_content = 'Pre-generated audio'; // Placeholder text
            }
        } else {
            // Check if audio file already exists with language code
            $file_path = $upload_dir['basedir'] . '/text-to-speech-tts/' . $element_uid . '-' . $language_code . '.mp3';
            $file_url = $upload_dir['baseurl'] . '/text-to-speech-tts/' . $element_uid . '-' . $language_code . '.mp3';
            $audio_exists = file_exists($file_path);
            
            if (defined('WP_DEBUG') && WP_DEBUG) {
                error_log('TTS Shortcode: Audio file ' . ($audio_exists ? 'exists at: ' . $file_url : 'does not exist yet'));
            }
        }
        
        // Get current post ID
        $current_post_id = get_the_ID();

        // If no audio exists, don't render the player at all
        if (!$audio_exists) {
            return '';
        }

        // Build the player HTML with data attribute to identify as shortcode
        $output = sprintf(
            '<div class="mementor-tts-player-container%s" id="%s" data-player-type="shortcode" data-post-id="%s">',
            $audio_exists ? ' mementor-tts-audio-ready' : '',
            esc_attr($player_id),
            esc_attr($current_post_id)
        );
        
        // Debug the HTML structure being built
        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log('TTS Shortcode: Building player with ID: ' . $player_id);
            error_log('TTS Shortcode: Audio exists: ' . ($audio_exists ? 'yes' : 'no'));
            if ($audio_exists) {
                error_log('TTS Shortcode: Audio URL: ' . $file_url);
            }
        }
        
        // Get player label - standardized approach for consistency
        $show_label = get_option('mementor_tts_show_player_label', '1');
        // Override with shortcode attribute if specified
        if (!empty($atts['label']) && $atts['label'] === 'yes') {
            $show_label = '1';
        } elseif (!empty($atts['label']) && ($atts['label'] === 'no' || $atts['label'] === '0')) {
            $show_label = '0';
        }
        $label_text = get_option('mementor_tts_player_label', __('Listen to this text:', 'text-to-speech-tts'));
        
        // Get autoplay and loop settings
        $autoplay = get_option('mementor_tts_autoplay', false);
        // Check shortcode override for autoplay
        if (!empty($atts['autoplay']) && $atts['autoplay'] === 'yes') {
            $autoplay = true;
        }
        
        $loop = get_option('mementor_tts_loop', false);
        // Check shortcode override for loop
        if (!empty($atts['loop']) && $atts['loop'] === 'yes') {
            $loop = true;
        }
        
        // Add data attributes for the player
        $data_attrs = array(
            'id' => $player_id,
            'class' => 'mementor-tts-player',
            'data-text' => $text_content,
            'data-element-uid' => $element_uid,
            'data-status' => $audio_exists ? 'ready' : 'pending'
        );
        
        // Add voice ID if provided
        if (!empty($atts['voice_id'])) {
            $data_attrs['data-voice-id'] = sanitize_key($atts['voice_id']);
        }
        
        // Add audio URL if file exists
        if ($audio_exists) {
            $data_attrs['data-audio-url'] = esc_url($file_url);
        }
        
        // Add autoplay and loop data attributes if enabled
        if ($autoplay) {
            $data_attrs['data-autoplay'] = 'true';
        }
        if ($loop) {
            $data_attrs['data-loop'] = 'true';
        }
        
        // Add customizer options as data attributes
        $customizer_options = array('time_display', 'speed_control', 'volume_control', 'download', 'autoplay', 'loop', 'information');
        foreach ($customizer_options as $option) {
            if (!empty($atts[$option]) && $atts[$option] === 'yes') {
                $data_attrs['data-' . str_replace('_', '-', $option)] = 'yes';
            }
        }
        
        // Build the data attributes string
        $data_attrs_str = '';
        foreach ($data_attrs as $key => $value) {
            if ($key === 'data-text') {
                // Special handling for text content to avoid HTML attribute issues
                $data_attrs_str .= sprintf(' %s="%s"', esc_attr($key), esc_attr($value));
            } else {
                $data_attrs_str .= sprintf(' %s="%s"', esc_attr($key), esc_attr($value));
            }
        }
        
        $output .= sprintf('<div%s>', $data_attrs_str);
        
        // Standardized check for consistency with other methods
        if ($show_label === '1' || $show_label === 1 || $show_label === true) {
            // Get label settings
            $label_position = get_option('mementor_tts_player_label_position', 'left');
            $label_size = get_option('mementor_tts_player_label_size', '14');
            $label_weight = get_option('mementor_tts_player_label_weight', '400');
            $label_color = get_option('mementor_tts_player_label_color', '#1d2327');
            
            // Build label classes
            $label_classes = array('mementor-tts-player-label');
            $label_classes[] = 'text-' . $label_position;
            
            // Add size class
            if ($label_size <= 12) {
                $label_classes[] = 'label-size-small';
            } elseif ($label_size >= 16) {
                $label_classes[] = 'label-size-large';
            } else {
                $label_classes[] = 'label-size-default';
            }
            
            // Add weight class
            if ($label_weight >= 700) {
                $label_classes[] = 'label-weight-bold';
            } elseif ($label_weight >= 500) {
                $label_classes[] = 'label-weight-medium';
            } else {
                $label_classes[] = 'label-weight-normal';
            }
            
            // Add color class or inline style
            if ($label_color === '#ffffff' || strtolower($label_color) === 'white') {
                $label_classes[] = 'label-color-white';
            } elseif ($label_color === '#1d2327' || strtolower($label_color) === 'dark') {
                $label_classes[] = 'label-color-dark';
            } else {
                $label_classes[] = 'label-color-custom';
            }
            
            // Build label HTML
            $label_html = sprintf(
                '<div class="%s"',
                esc_attr(implode(' ', $label_classes))
            );
            
            // Add inline style for custom color
            if (!in_array($label_color, array('#ffffff', 'white', '#1d2327', 'dark'))) {
                $label_html .= sprintf(' style="--mementor-tts-custom-label-color: %s"', esc_attr($label_color));
            }
            
            $label_html .= '>' . esc_html($label_text) . '</div>';
            
            $output .= $label_html;
        }
        
        // Add audio element if we have a pre-generated file
        if ($audio_exists) {
            $audio_attrs = 'preload="metadata" src="' . esc_url($file_url) . '"';
            if ($autoplay) {
                $audio_attrs .= ' autoplay';
            }
            if ($loop) {
                $audio_attrs .= ' loop';
            }
            $output .= sprintf('<audio %s></audio>', $audio_attrs);
        }
        
        // Get button background setting
        $show_play_bg = get_option('mementor_tts_show_play_bg', true);
        
        $output .= '<div class="mementor-tts-custom-controls"' . ($show_play_bg ? '' : ' data-show-play-bg="false"') . '>';
        
        // Play button
        $play_icon_class = $audio_exists ? 'dashicons-controls-play mementor-dashicons-controls-play' : 'dashicons-update mementor-dashicons-update';
        $play_aria_label = $audio_exists ? __('Play', 'text-to-speech-tts') : __('Generate Audio', 'text-to-speech-tts');
        
        $output .= sprintf(
            '<button class="mementor-tts-play-button" aria-label="%s" style="padding:0!important;margin:0!important;">',
            esc_attr($play_aria_label)
        );
        $output .= sprintf('<span class="dashicons %s"></span>', esc_attr($play_icon_class));
        $output .= '</button>';
        
        // Time display
        $show_time = get_option('mementor_tts_show_time', true);
        // Check shortcode override
        if (!empty($atts['time_display']) && $atts['time_display'] === 'yes') {
            $show_time = true;
        }
        
        if ($show_time) {
            $output .= '<span class="mementor-tts-time-display">0:00</span>';
        }
        
        // Progress bar
        $output .= '<div class="mementor-tts-progress-container">';
        $output .= '<div class="mementor-tts-progress-bar"></div>';
        $output .= '</div>';
        
        // Duration display
        if ($show_time) {
            $output .= '<span class="mementor-tts-duration-display">0:00</span>';
        }
        
        // Volume button
        $show_volume = get_option('mementor_tts_show_volume', true);
        // Check shortcode override
        if (!empty($atts['volume_control']) && $atts['volume_control'] === 'yes') {
            $show_volume = true;
        }
        
        if ($show_volume) {
            $output .= '<button class="mementor-tts-volume-button" aria-label="' . esc_attr__('Volume', 'text-to-speech-tts') . '" style="padding:0!important;margin:0!important;">';
            $output .= '<span class="dashicons dashicons-controls-volumeon mementor-dashicons mementor-dashicons-controls-volumeon"></span>';
            $output .= '</button>';
        }
        
        // Speed control
        $show_speed = get_option('mementor_tts_speed_control', false);
        // Check shortcode override
        if (!empty($atts['speed_control']) && $atts['speed_control'] === 'yes') {
            $show_speed = true;
        }
        
        if ($show_speed) {
            $output .= '<button class="mementor-tts-speed-button" style="padding:0!important;margin:0!important;">1.0x</button>';
        }
        
        // Download button
        $show_download = get_option('mementor_tts_show_download', false);
        // Check shortcode override
        if (!empty($atts['download']) && $atts['download'] === 'yes') {
            $show_download = true;
        }
        
        if ($show_download) {
            $output .= '<button class="mementor-tts-download-button" aria-label="' . esc_attr__('Download', 'text-to-speech-tts') . '" style="padding:0!important;margin:0!important;">';
            $output .= '<span class="dashicons dashicons-download"></span>';
            $output .= '</button>';
        }
        
        // Info button
        $show_info = get_option('mementor_tts_show_info', false);
        // Check shortcode override
        if (!empty($atts['information']) && $atts['information'] === 'yes') {
            $show_info = true;
        }
        
        if ($show_info) {
            $output .= '<button type="button" class="mementor-tts-info-button" aria-label="' . esc_attr__('Information', 'text-to-speech-tts') . '" style="padding:0!important;margin:0!important;">';
            $output .= '<span class="dashicons dashicons-info mementor-dashicons mementor-dashicons-info"></span>';
            $output .= '</button>';
        }
        
        $output .= '</div>'; // End controls
        $output .= '</div>'; // End player
        $output .= '</div>'; // End container
        
        // Debug output
        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log('TTS Shortcode: Final output length: ' . strlen($output));
        }
        
        return $output;
    }
} 