<?php
if ( ! defined( 'ABSPATH' ) ) exit;

/**
 * VMO OpenAI TTS HD Streaming Integration
 * Replaces ElevenLabs with OpenAI's Text-to-Speech HD streaming
 */

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

class VMO_OpenAI_TTS {
    
    private $api_key;
    private $default_voice = 'ash'; // ash, marin, cedar, alloy, echo, fable, onyx, nova, shimmer
    private $default_model = 'tts-1-hd'; // High-quality streaming model
    
    /**
     * Available OpenAI HD voices with descriptions
     */
    private $available_voices = [
        'ash' => [
            'name' => 'Ash',
            'description' => 'Balanced, confident voice tuned for consultations',
            'gender' => 'neutral'
        ],
        'marin' => [
            'name' => 'Marin',
            'description' => 'Polished concierge-style voice for premium receptionist calls',
            'gender' => 'neutral',
            'api_voice' => 'marin'
        ],
        'cedar' => [
            'name' => 'Cedar',
            'description' => 'Deeper, grounded voice suited for formal business reception',
            'gender' => 'male',
            'api_voice' => 'cedar'
        ],
        'alloy' => [
            'name' => 'Alloy',
            'description' => 'Neutral and balanced, great for professional contexts',
            'gender' => 'neutral'
        ],
        'echo' => [
            'name' => 'Echo',
            'description' => 'Male voice with a warm, approachable tone',
            'gender' => 'male'
        ],
        'fable' => [
            'name' => 'Fable',
            'description' => 'British accent, expressive and engaging',
            'gender' => 'male'
        ],
        'onyx' => [
            'name' => 'Onyx',
            'description' => 'Deep and authoritative male voice',
            'gender' => 'male'
        ],
        'nova' => [
            'name' => 'Nova',
            'description' => 'Female voice that is energetic and friendly',
            'gender' => 'female'
        ],
        'shimmer' => [
            'name' => 'Shimmer',
            'description' => 'Female voice with a soft, gentle quality',
            'gender' => 'female'
        ]
    ];
    
    public function __construct() {
        $this->api_key = get_option('vmo_openai_api_key');
        $this->setup_ajax_handlers();
    }
    
    /**
     * Setup AJAX handlers for TTS streaming
     */
    private function setup_ajax_handlers() {
        add_action('wp_ajax_vmo_openai_synthesize_speech', array($this, 'handle_ajax_synthesize_speech'));
        // nopriv removed — TTS requires authenticated user to prevent anonymous API abuse
        
        add_action('wp_ajax_vmo_openai_get_voices', array($this, 'handle_ajax_get_voices'));
        // nopriv removed — voice listing requires authentication
        
        add_action('wp_ajax_vmo_openai_preview_voice', array($this, 'handle_ajax_preview_voice'));
        // nopriv removed — voice preview calls OpenAI TTS HD and must be billed
        
        add_action('wp_ajax_vmo_save_voice_preference', array($this, 'handle_ajax_save_voice_preference'));
        // nopriv removed — preference save requires user context
    }
    
    /**
     * Stream speech from OpenAI TTS HD API
     * 
     * @param string $text Text to convert to speech
    * @param string $voice Voice to use (ash, alloy, echo, fable, onyx, nova, shimmer)
     * @param string $model Model to use (tts-1 or tts-1-hd)
     * @return array Response with audio data or error
     */
    public function stream_speech($text, $voice = null, $model = null) {
        if (empty($this->api_key)) {
            return [
                'success' => false,
                'error' => 'AI API key not configured'
            ];
        }
        
        if (empty($text)) {
            return [
                'success' => false,
                'error' => 'No text provided for speech synthesis'
            ];
        }
        
        // Use defaults if not specified
        $voice = strtolower((string) ($voice ?? $this->get_user_voice_preference()));
        $model = $model ?? $this->default_model;
        
        // Validate voice
        if (!array_key_exists($voice, $this->available_voices)) {
            $voice = $this->default_voice;
        }

        $api_voice = $this->available_voices[$voice]['api_voice'] ?? $voice;
        
        // Prepare request body
        $body = [
            'model' => $model,
            'input' => $text,
            'voice' => $api_voice,
            'response_format' => 'mp3', // mp3, opus, aac, flac
            'speed' => 1.0 // 0.25 to 4.0
        ];
        
        // Make streaming request to OpenAI
        $response = wp_remote_post('https://api.openai.com/v1/audio/speech', [
            'timeout' => 30,
            'headers' => [
                'Authorization' => 'Bearer ' . $this->api_key,
                'Content-Type' => 'application/json'
            ],
            'body' => json_encode($body),
            'stream' => false // WordPress doesn't support true streaming, we'll get full response
        ]);
        
        if (is_wp_error($response)) {
            error_log('VMO OpenAI TTS Error: ' . $response->get_error_message());
            return [
                'success' => false,
                'error' => 'Failed to connect to TTS service: ' . $response->get_error_message()
            ];
        }
        
        $status_code = wp_remote_retrieve_response_code($response);
        
        if ($status_code !== 200) {
            $error_body = wp_remote_retrieve_body($response);
            error_log('VMO OpenAI TTS Error (Status ' . $status_code . '): ' . $error_body);
            
            return [
                'success' => false,
                'error' => 'TTS API error: HTTP ' . $status_code,
                'details' => $error_body
            ];
        }
        
        // Get audio data
        $audio_data = wp_remote_retrieve_body($response);
        
        if (empty($audio_data)) {
            return [
                'success' => false,
                'error' => 'Empty response from TTS service'
            ];
        }
        
        // Return base64-encoded audio for frontend
        $audio_base64 = base64_encode($audio_data); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- data encoding
        
        return [
            'success' => true,
            'audio' => $audio_base64,
            'format' => 'mp3',
            'voice' => $voice,
            'api_voice' => $api_voice,
            'model' => $model,
            'text_length' => strlen($text)
        ];
    }
    
    /**
     * AJAX handler for speech synthesis
     */
    public function handle_ajax_synthesize_speech() {
        // Verify nonce for security
        check_ajax_referer('vmo_ajax_nonce', 'nonce');
        
        // ✅ TOKEN DEDUCTION v8.1.0: Charge for TTS voice synthesis
        $user_id = get_current_user_id();
        if (function_exists('vmo_deduct_tokens_for_operation')) {
            if (!vmo_deduct_tokens_for_operation($user_id, 'tts')) {
                wp_send_json_error([
                    'message' => 'Insufficient tokens for voice synthesis. Please top up your balance.',
                    'status' => 'insufficient_tokens'
                ]);
                return;
            }
        }
        
        $text = isset($_POST['text']) ? sanitize_textarea_field($_POST['text']) : '';
        $voice = isset($_POST['voice']) ? sanitize_text_field(wp_unslash($_POST['voice'])) : null;
        $model = isset($_POST['model']) ? sanitize_text_field(wp_unslash($_POST['model'])) : null;
        
        if (empty($text)) {
            wp_send_json_error([
                'message' => 'No text provided'
            ]);
            return;
        }
        
        // Synthesize speech
        $result = $this->stream_speech($text, $voice, $model);
        
        if ($result['success']) {
            wp_send_json_success($result);
        } else {
            wp_send_json_error([
                'message' => $result['error'],
                'details' => isset($result['details']) ? $result['details'] : null
            ]);
        }
    }
    
    /**
     * AJAX handler to get available voices
     */
    public function handle_ajax_get_voices() {
        check_ajax_referer('vmo_ajax_nonce', 'nonce');
        
        $current_preference = $this->get_user_voice_preference();
        
        wp_send_json_success([
            'voices' => $this->available_voices,
            'current' => $current_preference,
            'default' => $this->default_voice
        ]);
    }
    
    /**
     * AJAX handler to preview a voice
     */
    public function handle_ajax_preview_voice() {
        check_ajax_referer('vmo_ajax_nonce', 'nonce');
        
        // ✅ TOKEN DEDUCTION: Voice preview calls OpenAI TTS HD — charge tokens
        $user_id = get_current_user_id();
        if (function_exists('vmo_deduct_tokens')) {
            $preview_cost = defined('VMO_TOKENS_TTS_RESPONSE') ? VMO_TOKENS_TTS_RESPONSE : 81;
            if (!vmo_deduct_tokens($user_id, $preview_cost, 'tts_preview', 'Voice preview synthesis')) {
                wp_send_json_error([
                    'message' => 'Insufficient tokens for voice preview. Please top up your balance.',
                    'status' => 'insufficient_tokens'
                ]);
                return;
            }
        }
        
        $voice = isset($_POST['voice']) ? sanitize_text_field(wp_unslash($_POST['voice'])) : $this->default_voice;
        
        // Validate voice
        if (!array_key_exists($voice, $this->available_voices)) {
            wp_send_json_error([
                'message' => 'Invalid voice selected'
            ]);
            return;
        }
        
        // Preview text tailored to the voice
        $preview_text = "Hi! I'm " . $this->available_voices[$voice]['name'] . ". " . 
                       $this->available_voices[$voice]['description'] . 
                       " I'm here to help you build your business website with intelligent conversation.";
        
        // Generate preview audio
        $result = $this->stream_speech($preview_text, $voice, $this->default_model);
        
        if ($result['success']) {
            wp_send_json_success($result);
        } else {
            wp_send_json_error([
                'message' => $result['error']
            ]);
        }
    }
    
    /**
     * AJAX handler to save voice preference
     */
    public function handle_ajax_save_voice_preference() {
        check_ajax_referer('vmo_ajax_nonce', 'nonce');
        
        $voice = isset($_POST['voice']) ? sanitize_text_field(wp_unslash($_POST['voice'])) : '';
        
        if (empty($voice) || !array_key_exists($voice, $this->available_voices)) {
            wp_send_json_error([
                'message' => 'Invalid voice selection'
            ]);
            return;
        }
        
        // Save to user meta if logged in, otherwise session
        if (is_user_logged_in()) {
            $user_id = get_current_user_id();
            update_user_meta($user_id, 'vmo_preferred_voice', $voice);
            update_user_meta($user_id, 'vmo_selected_reception_voice', ucfirst($voice));
        } else {
            // Use session for non-logged-in users
            if (!session_id()) {
                session_start();
            }
            $_SESSION['vmo_preferred_voice'] = $voice;
        }
        
        wp_send_json_success([
            'message' => 'Voice preference saved',
            'voice' => $voice
        ]);
    }
    
    /**
     * Get user's voice preference
     * 
     * @return string Voice preference or default
     */
    private function get_user_voice_preference() {
        // Check user meta if logged in
        if (is_user_logged_in()) {
            $user_id = get_current_user_id();
            $preference = get_user_meta($user_id, 'vmo_preferred_voice', true);
            
            if (!empty($preference) && array_key_exists($preference, $this->available_voices)) {
                return $preference;
            }

            $reception_voice = strtolower((string) get_user_meta($user_id, 'vmo_selected_reception_voice', true));
            if (!empty($reception_voice) && array_key_exists($reception_voice, $this->available_voices)) {
                return $reception_voice;
            }
        }
        
        // Check session for non-logged-in users
        if (session_id() && isset($_SESSION['vmo_preferred_voice'])) {
            $preference = $_SESSION['vmo_preferred_voice'];
            
            if (array_key_exists($preference, $this->available_voices)) {
                return $preference;
            }
        }
        
        // Return default
        return $this->default_voice;
    }
    
    /**
     * Get available voices list
     * 
     * @return array Available voices
     */
    public function get_available_voices() {
        return $this->available_voices;
    }
    
    /**
     * Validate if voice is available
     * 
     * @param string $voice Voice to validate
     * @return bool True if valid
     */
    public function is_valid_voice($voice) {
        return array_key_exists($voice, $this->available_voices);
    }
}

// Initialize TTS class
if (!function_exists('vmo_openai_tts')) {
    function vmo_openai_tts() {
        return new VMO_OpenAI_TTS();
    }
}

// Initialize on WordPress init
add_action('init', 'vmo_openai_tts');
