<?php

/** Exit if accessed directly. */
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Main module class for Speaking Test.
 */
class QC_Form_SFF_Learning_Mode_Test
{

    private static $instance;

    private function __construct()
    {
        add_action('wp_ajax_qcld_stt_test_evaluation', [$this, 'qcld_stt_test_evaluation']);
        add_action('wp_ajax_nopriv_qcld_stt_test_evaluation', [$this, 'qcld_stt_test_evaluation']);

        add_action('wp_ajax_vmwpmdp_manual_mark_test', [$this, 'manual_mark_test']);

        add_action('wp_enqueue_scripts', [$this, 'scripts']);

        include_once(plugin_dir_path(__FILE__) . 'form_sff_learning_mode_test-student-results-shortcode.php');
    }

    public static function get_instance()
    {
        if (!isset(self::$instance) && !(self::$instance instanceof QC_Form_SFF_Learning_Mode_Test)) {
            self::$instance = new QC_Form_SFF_Learning_Mode_Test;
        }

        return self::$instance;
    }

    public function scripts()
    {

        wp_enqueue_style('qcld_stt_learning_mode_test_css', plugin_dir_url(__FILE__) . 'assets/css/form_sff_learning_mode_test.css' );

        wp_enqueue_script('qcld_stt_learning_mode_test_js', plugin_dir_url(__FILE__) . 'assets/js/form_sff_learning_mode_test.js', ['jquery'], '1.1.0', true);
        wp_localize_script('qcld_stt_learning_mode_test_js', 'qcld_stt_test_obj', [
            'ajax_url' => admin_url('admin-ajax.php'),
            'nonce' => wp_create_nonce('qcld_stt_test_nonce'),
            'stop_text' => esc_html__('Stop Speaking', 'voice-widgets'),
            'start_text' => esc_html__('Start Speaking', 'voice-widgets'),
            'recording_text' => esc_html__('Recording...', 'voice-widgets'),
            'processing_text' => esc_html__('Processing...', 'voice-widgets'),
            'stt_type' => get_option('qc_voice_to_speech_stt_type') ? get_option('qc_voice_to_speech_stt_type') : 'google',
            'lang_code' => get_option('qc_voice_to_speech_stt_lang_code') ? get_option('qc_voice_to_speech_stt_lang_code') : 'en-US',
        ]);
    }

    public function qcld_stt_test_evaluation()
    {

        if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'qcld_stt_test_nonce')) {
            wp_send_json_error('Invalid nonce');
        }

        $post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0;
        $level_index = isset($_POST['level_index']) ? intval($_POST['level_index']) : 0;
        $audio_id = isset($_POST['audio_id']) ? intval($_POST['audio_id']) : 0;

        if (!$post_id || !$audio_id) {
            wp_send_json_error('Missing data');
        }

        // Get the audio path
        $audio_file_path = get_post_meta($audio_id, 'qcld_wpvm_vmwpmdp_voicemssg_audio', true);
        if (!$audio_file_path) {
            wp_send_json_error('Audio not found');
        }

        // Perform STT
        $transcription = $this->perform_stt($audio_file_path);
        if (is_wp_error($transcription)) {
            wp_send_json_error($transcription->get_error_message());
        }

        // Get the target words based on level index
        $levels = get_post_meta($post_id, 'vmwpmdp_test_levels', true);
        $target_words = isset($levels[$level_index]['text']) ? $levels[$level_index]['text'] : '';
        $level_label = isset($levels[$level_index]['label']) ? $levels[$level_index]['label'] : 'Level ' . ($level_index + 1);

        // Evaluation logic (Basic string matching for now)
        $evaluation = 'fail';
        $clean_transcription = strtolower(trim(preg_replace('/[[:punct:]]/', '', $transcription)));
        $clean_target = strtolower(trim(preg_replace('/[[:punct:]]/', '', $target_words)));

        if ($clean_transcription == $clean_target) {
            $evaluation = 'pass';
        }
        else {
            if (!empty($clean_target) && strpos($clean_transcription, $clean_target) !== false) {
                $evaluation = 'pass';
            }
        }

        // Save evaluation result to the record
        update_post_meta($audio_id, 'vmwpmdp_test_evaluation', $evaluation);
        update_post_meta($audio_id, 'vmwpmdp_transcription_txt', $transcription);
        update_post_meta($audio_id, 'vmwpmdp_test_level_index', $level_index);
        update_post_meta($audio_id, 'vmwpmdp_test_level_label', $level_label);

        wp_send_json_success([
            'evaluation' => $evaluation,
            'transcription' => $transcription,
            'target' => $target_words,
        ]);

    }

    public function manual_mark_test()
    {
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Unauthorized');
        }

        $record_id = isset($_POST['record_id']) ? intval($_POST['record_id']) : 0;
        $score = isset($_POST['score']) ? intval($_POST['score']) : -1;
        $status = isset($_POST['status']) ? sanitize_text_field($_POST['status']) : '';

        if (!$record_id) {
            wp_send_json_error('Invalid record ID');
        }

        if ($score !== -1) {
            update_post_meta($record_id, 'vmwpmdp_test_score', $score);
        }

        if (!empty($status)) {
            update_post_meta($record_id, 'vmwpmdp_test_evaluation', $status);
        }

        update_post_meta($record_id, 'vmwpmdp_manual_marked', 'yes');

        // Calculate new total score for the session
        $session_id = get_post_meta($record_id, 'vmwpmdp_exam_session_id', true);
        $total_score = 0;

        if ($session_id) {
            $args = [
                'post_type' => 'qcvoicemsg_record',
                'meta_query' => [
                    [
                        'key' => 'vmwpmdp_exam_session_id',
                        'value' => $session_id,
                    ]
                ],
                'fields' => 'ids',
                'posts_per_page' => -1,
            ];
            $session_posts = get_posts($args);
            foreach ($session_posts as $p_id) {
                $total_score += (int)get_post_meta($p_id, 'vmwpmdp_test_score', true);
            }
        }
        else {
            // Legacy record fallback
            $test_id = get_post_meta($record_id, 'vmwpmdp_cform_id', true);
            $post = get_post($record_id);
            $author_id = $post->post_author;
            $student_meta = get_post_meta($record_id, 'vmwpmdp_additional_fields', true);

            $args = [
                'post_type' => 'qcvoicemsg_record',
                'meta_key' => 'vmwpmdp_cform_id',
                'meta_value' => $test_id,
                'author' => $author_id,
                'fields' => 'ids',
                'posts_per_page' => -1,
            ];
            $all_records = get_posts($args);
            if ($author_id == 0) {
                $current_meta = json_decode($student_meta, true);
                foreach ($all_records as $p_id) {
                    $r_meta = json_decode(get_post_meta($p_id, 'vmwpmdp_additional_fields', true), true);
                    if ($r_meta === $current_meta) {
                        $total_score += (int)get_post_meta($p_id, 'vmwpmdp_test_score', true);
                    }
                }
            }
            else {
                foreach ($all_records as $p_id) {
                    $total_score += (int)get_post_meta($p_id, 'vmwpmdp_test_score', true);
                }
            }
        }

        wp_send_json_success(['total_score' => $total_score]);
    }

    private function perform_stt($audio_path)
    {

        $stt_type = get_option('qc_voice_to_speech_stt_type');

        if ($stt_type === 'google') {
            return $this->google_stt($audio_path);
        }
        elseif ($stt_type === 'openai') {
            return $this->openai_stt($audio_path);
        }
        elseif ($stt_type === 'speechrecognition') {
            return $this->speechrecognition_stt($audio_path);
        }

        return new WP_Error('stt_config', 'STT is not configured.');
    }

    private function speechrecognition_stt($audio_path)
    {
        // For 'speechrecognition', the transcription typically happens on the frontend via Web Speech API.
        // It should be passed via AJAX and either read from $_POST or retrieved from post meta here.
        $transcription = isset($_POST['transcription']) ? sanitize_text_field($_POST['transcription']) : '';

        if (!empty($transcription)) {
            return $transcription;
        }

        return 'Failed to transcribe with speechrecognition';
    }

    private function google_stt($audio_path)
    {
        if (!function_exists('qc_voice_stt_transcribe_audio')) {
            return new WP_Error('google_stt_error', 'Google STT function not available.');
        }

        $lang_code = get_option('qc_voice_to_speech_stt_lang_code') ? get_option('qc_voice_to_speech_stt_lang_code') : 'en-US';

        $file = [
            'name' => basename($audio_path),
            'tmp_name' => $audio_path,
        ];

        $transcription = qc_voice_stt_transcribe_audio($file, $lang_code);

        if (!empty($transcription)) {
            return $transcription;
        }

        return new WP_Error('google_stt_error', 'Failed to transcribe with Google STT.');
    }

    private function openai_stt($audio_path)
    {
        $api_key = get_option('qc_voice_to_speech_stt_openai_api_key');
        if (!$api_key) {
            return new WP_Error('openai_error', 'OpenAI API key missing.');
        }

        $url = 'https://api.openai.com/v1/audio/transcriptions';

        $body = [
            'file' => curl_file_create($audio_path),
            'model' => 'whisper-1',
        ];

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $api_key,
            'Content-Type: multipart/form-data',
        ]);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        $response = curl_exec($ch);
        curl_close($ch);

        $result = json_decode($response, true);
        if (isset($result['text'])) {
            return $result['text'];
        }

        return new WP_Error('openai_error', 'Failed to transcribe with OpenAI.');
    }

}

QC_Form_SFF_Learning_Mode_Test::get_instance();
