<?php 
/**
 * Writing_AI_Evaluation
 *
 * @package Spacetree/lib/proqyz/writing
 * @since   2.0.3.1
 * v2.1.0 - updated (testing - copy of vscode php)
 */

defined( 'ABSPATH' ) || exit;

class Writing_AI_Evaluation {

    /**
     * Writing_AI_Evaluation version.
     *
     * @var string
     */
    public $version = '2.1.0';
    public $review_id = null;

    protected static $_instance = null;

    /**
     * Table names.
     *
     * @var string
     */
    public $table_progress_submissions;
    public $table_submissions_review;
    public $table_submissions_review_meta;

    /**
     * v2.1.0
     * Main Writing_AI_Evaluation Instance.
     *
     * Ensures only one instance of Writing_AI_Evaluation is loaded or can be loaded.
     *
     * @since 1.0
     * @static
     * @return Writing_AI_Evaluation - Main instance.
     */
    public static function instance() {
        if ( is_null( self::$_instance ) ) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }

    /**
     * v2.1.0
     * Constructor method to initialize the plugin.
     */
    public function __construct() {
        global 
            $table_proqyz_v3_progress_submissions,
            $table_proqyz_v3_submissions_review,
            $table_proqyz_v3_submissions_review_meta;

        // Initialize table names
        $this->table_progress_submissions = $table_proqyz_v3_progress_submissions;
        $this->table_submissions_review = $table_proqyz_v3_submissions_review;
        $this->table_submissions_review_meta = $table_proqyz_v3_submissions_review_meta;

        $this->includes();
        $this->register_rest_api_routes();
    }

    /**
     * v2.1.0
     * Include necessary files (if any).
     */
    public function includes() {
        // Include other necessary files if needed.
    }

    /**
     * v2.1.0
     * Register REST API routes.
     */
    public function register_rest_api_routes() {
        add_action('rest_api_init', [$this, 'register_writing_evaluation_route']);
    }

    /**
     * Register the REST API route for AI evaluation.
     */
    public function register_writing_evaluation_route() {
        register_rest_route('spacetree/proqyz', '/writing/ai/evaluation', [
            'methods'  => 'POST',
            'callback' => [$this, 'handle_ai_evaluation_request'],
            'permission_callback' => '__return_true', // Handle permissions here as necessary
        ]);
        register_rest_route('spacetree/proqyz', '/writing/ai/evaluation/run', [
            'methods'  => 'POST',
            'callback' => [$this, 'handle_ai_evaluation_run'],
            'permission_callback' => '__return_true',
        ]);
    }

    /**
     * v2.1.0
     * Handle the AI evaluation request.
     *
     * @param WP_REST_Request $request
     * @return WP_REST_Response
     */
    public function handle_ai_evaluation_request($request) {
        // Ensure the script continues processing even if the user disconnects
        ignore_user_abort(true);

        // Get the parameters from the request
        $result_id      = sanitize_text_field($request['result_id']);
        $section_id     = sanitize_text_field($request['section_id']);
        $section_data   = (object) $request['section'];
        $user_answer    = $request['user_answer'];
        $reviewer_id    = "-1";

        if (empty($result_id) || empty($section_id)) {
            return new WP_REST_Response([
                'error'  => (object) [
                    "message" => 'Missing required parameters'
                ]
            ], 200);
        }

        // Perform AI evaluation processing here (e.g., saving to database or calling external APIs)
        global $wpdb;

        global $ST_OPTION_st_proqyz__open_ai_endpoint, $ST_OPTION_st_proqyz__open_ai_modal, $ST_OPTION_st_proqyz__open_ai_enable, $ST_OPTION_st_proqyz__open_ai_apikey; 
        $ST_OPTION_st_proqyz__open_ai_endpoint__option_value    = get_option($ST_OPTION_st_proqyz__open_ai_endpoint, 'https://api.openai.com/v1/completions');
        $ST_OPTION_st_proqyz__open_ai_modal__option_value       = get_option($ST_OPTION_st_proqyz__open_ai_modal, 'gpt-4o-mini');
        $ST_OPTION_st_proqyz__open_ai_enable__option_value      = get_option($ST_OPTION_st_proqyz__open_ai_enable, 0);
        $ST_OPTION_st_proqyz__open_ai_apikey_option_value       = get_option($ST_OPTION_st_proqyz__open_ai_apikey, '');

        if(empty($ST_OPTION_st_proqyz__open_ai_endpoint__option_value) || $ST_OPTION_st_proqyz__open_ai_endpoint__option_value == '') {
            return (object) [
                'error' => (object) [
                    'message' => 'API Endpoint is not set',
                    'code'    => 'PROQYZ_OPEN_AI::api_endpoint_missing',
                    'status'  => 500,
                ]
            ];
        }
    
        if(empty($ST_OPTION_st_proqyz__open_ai_modal__option_value) || $ST_OPTION_st_proqyz__open_ai_modal__option_value == '') {
            return new WP_REST_Response((object) (object) [
                'error' => (object) [
                    'message' => 'OpenAI Modal is not set',
                    'code'    => 'PROQYZ_OPEN_AI::openai_modal_missing',
                    'status'  => 500,
                ]
            ], 200);
        }
    
        if( (int) $ST_OPTION_st_proqyz__open_ai_enable__option_value == 0 ) {
            return new WP_REST_Response([
                'error' => (object) [
                    'message' => 'OpenAI is not enabled',
                    'code'    => 'PROQYZ_OPEN_AI::openai_disabled',
                    'status'  => 200,
                ]
            ], 200);
        }

        if( $ST_OPTION_st_proqyz__open_ai_apikey_option_value == ''){
            return new WP_REST_Response([
                'error'  => (object) [
                    "message" => 'AI Apikey is not set',
                    'code'    => 'PROQYZ_OPEN_AI::apikey_not_set',
                    'status'  => 200,
                ]
            ], 200);
        }

        # phase checked -------------------------- working
        

        # match it with student_id - to ensure if student is making that request
        $get_result = $wpdb->get_row("SELECT `user_id`,`api_id` FROM {$this->table_progress_submissions} WHERE `ID` = '$result_id' LIMIT 1");
        if( !$get_result ) {
            return new WP_REST_Response([
                'error'  => (object) [
                    "message" => 'Result id with given request not found'
                ]
            ], 200);
        }

        $student_id = $get_result->user_id;
        $quiz_id    = $get_result->api_id;
        # after result found check if review is already given or processing
        $get_review = $wpdb->get_row("SELECT `ID` FROM {$this->table_submissions_review} WHERE `result_id` = '$result_id' AND `user_id` = '$student_id' AND `section_id` = '$section_id' AND `status` = 1 ");
        if( !$get_review ) {
            # initiate the result
            $is_review_request_added = $wpdb->insert($this->table_submissions_review, [
                "status"        => 1,
                "user_id"       => $student_id,
                "section_id"    => $section_id,
                "result_id"     => $result_id
            ]);

            if( $is_review_request_added ) {
                $this->review_id = $wpdb->insert_id;
            } else {
                return new WP_REST_Response([
                    'error'  => (object) [
                        'message' => 'AI evaluation Failed due to review initiate problem',
                        'data'    => [
                            'result_id'  => $result_id,
                            'section_id' => $section_id,
                        ],
                    ]
                ], 200);
            }
        } else {
            $this->review_id = $get_review->ID;
        }

        # phase checked 2 -------------------------- working
        if( $this->review_id ) {
            $rv_id = $this->review_id;
            # create status
            $process = false;

            # 0.) update the reviewer
            $this->update_review_meta($this->review_id, "reviewer", $reviewer_id);

            # 1.) check review status
            $review_status_id = null;
            $review_status_key = $wpdb->get_row("SELECT `meta_value`, `ID` FROM {$this->table_submissions_review_meta} WHERE `meta_key` = 'review-status' AND `review_id` = '$rv_id' AND `meta_status` = 1 LIMIT 1");
            if( $review_status_key ) { 
                $review_status = $review_status_key->meta_value;
                $review_status_id = $review_status_key->ID;
                if( $review_status == "started" || $review_status == "processing" ) {
                    $process = false;
                    $this->update_review_meta($this->review_id, "review-log", serialize([
                        "type"      => "info",
                        "message"   => "AI evaluation is still processing please wait",
                        "date"      => date("U")
                    ]));
            
                    return new WP_REST_Response([
                        'success'  => (object) [
                            'message' => 'AI evaluation is still processing please wait',
                            'error_code' => 400
                        ]
                    ], 200);
                } else {
                    # process the queue
                    $process = true;
                }
            } else {
                # if review is not yet found , which means its not yet started
                $review_status_id = $this->update_review_meta($this->review_id, "review-status", "started");
                $process = true;
            }

            if( $process ) {
                # get the prompt from external api
                if( !class_exists('ST_ProQyz_Oauth') ) {
                    if( $review_status_id ) {

                        $wpdb->update($this->table_submissions_review_meta, [
                            "meta_value" => 'failed'
                        ], [
                            "ID" => $review_status_id
                        ]);

                        $this->update_review_meta($this->review_id, "review-log", serialize([
                            "type"      => "error",
                            "message"   => "AI evaluation Failed, [reason]: ST_ProQyz_Oauth::not-found",
                            "date"      => date("U")
                        ]));
                    }

                    return new WP_REST_Response([
                        'error'  => (object) [
                            'message' => 'RestApi class no found'
                        ]
                    ], 200);
                }

                $section_order = $section_data->order;
                /**
                 * external api endpoint
                 */
                $REST_response = (object) ST_ProQyz_Oauth::rest_post_request("/ai/writing/evaluation/".$quiz_id."/".$section_id."/".$section_order, []);
                # phase checked 3 -------------------------- working
                if (!isset($REST_response->error)) {
                    if( $review_status_id ) {
                        $wpdb->update($this->table_submissions_review_meta, [
                            "meta_value" => 'processing'
                        ], [
                            "ID" => $review_status_id
                        ]);
                        # reset error log
                        $this->update_review_meta($this->review_id, "review-log", serialize([
                            "date"      => date("U"),
                            "type"      => "info",
                            "message"   => "AI evaluation Processing"
                        ]));
                    }    
                    
                    if( $REST_response->success ) {
                        $rest_success = (object) $REST_response->success;
                        $default_output_format = 'You **must** return the evaluation in the following JSON format: {
                            "success": {
                                "format": "json",
                                "response": {
                                    "task-achievement": {
                                        "feedback": **feedback for task achievement here**,
                                        "band": "**feedback band score between 2-9**"
                                    },
                                    "coherence-and-cohesion": {
                                        "feedback": **feedback for coherence and cohesion here**,
                                        "band": "**feedback band score between 2-9**"
                                    },
                                    "lexical-resource": {
                                        "feedback": **feedback for lexical resource here**,
                                        "band": "**feedback band score between 2-9**"
                                    },
                                    "grammatical-range-and-accuracy": {
                                        "feedback": **feedback for grammatical range and accuracy here**,
                                        "band": "**feedback band score between 2-9**"
                                    },
                                    "overall": {
                                        "feedback": **Overall feedback here**,
                                        "band": "**Overall feedback band score between 2-9 using formula (score1 + score2 + score3 + score4)/4 **"
                                    },
                                    "highlights: **hightlights array here**,
                                    "user-response": **complete user response with highlights index  here**


                                }
                            }
                        }
                        \n\nOnly output the JSON object in the exact format provided. Do not include any plain text responses outside the JSON object.';
                        $prompt         = isset($rest_success->prompt)? $rest_success->prompt : null;
                        $output_format  = isset($rest_success->output_format)? $rest_success->output_format : $default_output_format;

                    

                        if( $prompt ) {
                            $task   = $section_data->content;
                            $answer = $user_answer;

                            # valdate user answer and task
                            if( empty($answer) || empty($task) ) {
                                $this->update_review_meta($this->review_id, "review-log", serialize([
                                    "date"      => date("U"),
                                    "type"      => "info",
                                    "message"   => "AI evaluation Failed, [reason]: Answer or task is empty",
                                    "data"      => [
                                        'answer' => $answer,
                                        'task'   => $task,
                                    ],
                                ]));
                                $wpdb->update($this->table_submissions_review_meta, [
                                    "meta_value" => 'failed'
                                ], [
                                    "ID" => $review_status_id
                                ]);

                                return new WP_REST_Response([
                                    'error'  => (object) [
                                        'message' => 'Answer or task is empty',
                                        'data'    => [
                                            'answer' => $answer,
                                            'task'   => $task,
                                        ],
                                    ]
                                ], 200);
                            }

                            # also need spend time on that section
                            # fetch the image or graph if its task 1
                            $data_payload = $this->parse_task_html_to_prompt($task, $section_order, $answer, $timespend = '');

                            // Define the prompt array
                            $prompt_payload = (array) [];
                            $prompt_payload[]   = (object) ['role' => 'system', 'content' => $prompt. "\n\n\n\n". $output_format];
                            $prompt_payload[]  = (object) ['role' => 'user', 'content' => $data_payload];

                            // Store prompt for background worker, then trigger worker and return "started" (no wait for OpenAI).
                            $this->update_review_meta($this->review_id, "prompt", serialize($prompt_payload));

                            $run_url = rest_url('spacetree/proqyz/writing/ai/evaluation/run');
                            $run_key = hash_hmac('sha256', (string) $this->review_id, wp_salt('auth'));
                            wp_remote_post($run_url, [
                                'timeout'  => 2,
                                'blocking' => false,
                                'body'     => [
                                    'review_id' => $this->review_id,
                                    'run_key'   => $run_key,
                                ],
                            ]);

                            return new WP_REST_Response([
                                'success' => (object) [
                                    'message' => 'Evaluation started. You can leave this tab; we will notify you when complete.',
                                    'started' => true,
                                ],
                            ], 200);
                        } else {
                            # phase checked 4 -------------------------- working
                            $wpdb->update($this->table_submissions_review_meta, [
                                "meta_value" => 'failed'
                            ], [
                                "ID" => $review_status_id
                            ]);
    
                            $this->update_review_meta($this->review_id, "review-log", serialize([
                                "date"      => date("U"),
                                "type"      => "error",
                                "message"   => "AI evaluation Failed, [reason]: Prompt for AI Evaluation failed",
                                "error"     => $REST_response
                            ]));


                            return new WP_REST_Response([
                                'success'  => (object) [
                                    "message" => "we are inside 4",
                                    "res"      =>   $prompt
                                ]
                            ], 200);
                        }
                    }   

                    
                    
                } else {
                    $rest_error = (object) $REST_response->error;
                    // Example of returning a successful response
                    if( $review_status_id ) {
                        $wpdb->update($this->table_submissions_review_meta, [
                            "meta_value" => 'failed'
                        ], [
                            "ID" => $review_status_id
                        ]);

                        $this->update_review_meta($this->review_id, "review-log", serialize([
                            "date"      => date("U"),
                            "type"      => "error",
                            "message"   => "AI evaluation Failed, [reason]: Request to AI REST API Failed with error response",
                            "error"     => $rest_error
                        ]));
                    }
                    return new WP_REST_Response([
                        'error'  => $rest_error
                    ], 200);    
                }

            } else {
                # unknown response
                // Example of returning a successful response
                # update log for review
                $this->update_review_meta($this->review_id, "review-log", serialize([
                    "type"      => "error",
                    "message"   => "Request failed due to process status",
                    "date"      => date("U")
                ]));
                return new WP_REST_Response([
                    'error'  => (object) [
                        'message' => 'AI evaluation failed reason unknown'
                    ]
                ], 200);
            }  
        } else {
            return new WP_REST_Response([
                'error'  => (object) [
                    'message' => 'AI evaluation Failed due to could not found review request inititator',
                    'data'    => [
                        'result_id'  => $result_id,
                        'section_id' => $section_id,
                    ],
                ]
            ], 200);
        }

    }

    /**
     * Background worker: run OpenAI request and save response. Called internally (fire-and-forget).
     *
     * @param WP_REST_Request $request Must contain review_id and run_key (HMAC for verification).
     * @return WP_REST_Response
     */
    public function handle_ai_evaluation_run($request) {
        ignore_user_abort(true);

        $review_id = isset($request['review_id']) ? absint($request['review_id']) : 0;
        $run_key   = isset($request['run_key']) ? $request['run_key'] : '';

        if (!$review_id || !$run_key) {
            return new WP_REST_Response(['error' => (object) ['message' => 'Missing review_id or run_key']], 200);
        }

        $expected_key = hash_hmac('sha256', (string) $review_id, wp_salt('auth'));
        if (!hash_equals($expected_key, $run_key)) {
            return new WP_REST_Response(['error' => (object) ['message' => 'Invalid run_key']], 200);
        }

        global $wpdb, $table_proqyz_v3_progress_submissions, $table_proqyz_v3_submissions_review;
        global $ST_OPTION_st_proqyz__open_ai_endpoint, $ST_OPTION_st_proqyz__open_ai_modal, $ST_OPTION_st_proqyz__open_ai_apikey;

        $this->review_id = $review_id;
        # get review first
        $review_row = $wpdb->get_row("SELECT user_id, result_id FROM {$table_proqyz_v3_submissions_review} WHERE ID = $review_id LIMIT 1");
        if( !$review_row ) {
            $this->update_review_meta($this->review_id, 'review-status', 'failed');
            $this->update_review_meta($this->review_id, 'review-log', serialize([
                'type' => 'error',
                'message' => 'Review not found by given review_id: '.$review_id,
                'date' => date('U'),
            ]));
            return new WP_REST_Response(['error' => (object) ['message' => 'Review not found by given review_id: '.$review_id]], 200);
        }

        $prompt_meta = $wpdb->get_row($wpdb->prepare(
            "SELECT meta_value FROM {$this->table_submissions_review_meta} WHERE review_id = %d AND meta_key = 'prompt' AND meta_status = 1 LIMIT 1",
            $review_id
        ));
        if (!$prompt_meta) {
            $this->update_review_meta($this->review_id, 'review-status', 'failed');
            $this->update_review_meta($this->review_id, 'review-log', serialize([
                'type' => 'error',
                'message' => 'Background worker: prompt not found',
                'date' => date('U'),
            ]));
            return new WP_REST_Response(['error' => (object) ['message' => 'Prompt not found']], 200);
        }

        $prompt_payload = maybe_unserialize($prompt_meta->meta_value);
        if (!is_array($prompt_payload)) {
            $this->update_review_meta($this->review_id, 'review-status', 'failed');
            return new WP_REST_Response(['error' => (object) ['message' => 'Invalid prompt payload']], 200);
        }

        $endpoint = get_option($ST_OPTION_st_proqyz__open_ai_endpoint, 'https://api.openai.com/v1/chat/completions');
        $apikey   = get_option($ST_OPTION_st_proqyz__open_ai_apikey, '');
        $endpoints = (object) [
            'endpoint' => $endpoint,
            'modal'    => get_option($ST_OPTION_st_proqyz__open_ai_modal, 'gpt-4o-mini'),
            'apikey'   => $apikey,
        ];

        $response_AI = $this->openai_conversation_request($endpoints, $prompt_payload);

        if (isset($response_AI->error)) {
            $this->update_review_meta($this->review_id, 'review-status', 'failed');
            $this->update_review_meta($this->review_id, 'review-log', serialize($response_AI));
            return new WP_REST_Response(['error' => $response_AI->error], 200);
        }

        if (isset($response_AI->success)) {
            $response_ai = $response_AI->success->body;
            $this->update_review_meta($this->review_id, 'ai-review-content', $response_ai);
            $this->update_review_meta($this->review_id, 'review-status', 'completed');
            # logic here ========================================================================
            $ai_review_content_json = (object) json_decode($response_ai, true);
            $need_update_scoring = false;
            if( isset($ai_review_content_json->success) ) {
                $ai_response = (object) $ai_review_content_json->success;
                if( isset($ai_response->format) && isset($ai_response->response) ) {
                    # template 1
                    if( $ai_response->format == "json" ) {
                        $evaluation_report = (array) $ai_response->response;
                        $ta = [];
                        $cc = [];
                        $lr = [];
                        $ga = [];
                        $overall = [];

                        if (!empty($evaluation_report)) {
                            // Extract each section from the report
                            if (isset($evaluation_report['task-achievement'])) {
                                $ta['band'] = $evaluation_report['task-achievement']['band'];
                            }
                            
                            if (isset($evaluation_report['coherence-and-cohesion'])) {
                                $cc['band'] = $evaluation_report['coherence-and-cohesion']['band'];
                            }
                        
                            if (isset($evaluation_report['lexical-resource'])) {
                                $lr['band'] = $evaluation_report['lexical-resource']['band'];
                            }
                        
                            if (isset($evaluation_report['grammatical-range-and-accuracy'])) {
                                $ga['band'] = $evaluation_report['grammatical-range-and-accuracy']['band'];
                            }
                        }

                        if( count($ta) > 0 && count($cc) > 0 && count($lr) > 0 && count($ga) > 0) {
                            $scoring_overall = [(int) $ta['band'], (int) $cc['band'], (int) $lr['band'], (int) $ga['band']];
                            // store the scoring array in review-scores meta
                            $this->update_review_meta($this->review_id, "review-scores", json_encode($scoring_overall));
                            $need_update_scoring = true;
                        }
                    }
                }
            }

            # debug: option update for dubugging report
            apply_filters('proqyz_quiz__on_evaluation_writing', [
                'user_id'     => $review_row->user_id,
                'reviewer_id' => '-1',
                'result_id'   => $review_row->result_id,
            ]);

            if( $need_update_scoring) {
                $user_id = $review_row->user_id;
                $result_id = $review_row->result_id;
                if( $result_id ) {
                    # finally mark the progress submission as completed by making review = 1
                    $wpdb->update($table_proqyz_v3_progress_submissions, [
                        'review' => 1,
                        'date_modified' => date("U"),
                    ], [
                        'ID' => $result_id
                    ]);
                }

            }

            return new WP_REST_Response(['success' => (object) ['message' => 'Evaluation completed in background']], 200);
        }

        $this->update_review_meta($this->review_id, 'review-status', 'failed');
        $this->update_review_meta($this->review_id, 'review-log', serialize([
            'type'    => 'error',
            'message' => 'AI evaluation response invalid',
            'date'    => date('U'),
            'error'   => $response_AI,
        ]));
        return new WP_REST_Response(['error' => (object) ['message' => 'AI invalid response']], 200);
    }
    /**
     * v2.1.0
     * @param WP_REST_Request
     * @return WP_REST_Response
     */
    public function openai_conversation_request( $endpoints, $prompt = [] ) {
        if( count($prompt) === 0 ) {
            return (object) [
                'error' => (object) [
                    'message' => 'Prompt is missing',
                    'code'    => 'PROQYZ_OPEN_AI::openai_prompt_missing',
                    'status'  => 500,
                ]
            ];
        }
    
    
        // Set up the OpenAI API endpoint and headers
        $url = $endpoints->endpoint;
        $headers = array(
            'Authorization' => 'Bearer ' . $endpoints->apikey,
            'Content-Type'  => 'application/json',
        );
    
        // Structure the conversation with 'user' and 'assistant' roles
        $data = array(
            'model' => $endpoints->modal,
            'messages' => $prompt,
            'max_tokens' => 4096,
            'temperature' => 0.7,
        );

        # given prompt to proqyz_ai
        $this->update_review_meta($this->review_id, "prompt", serialize($prompt));
    
        // Send a POST request to the OpenAI API
        $response = wp_remote_post( $url, array(
            'headers' => $headers,
            'body'    => wp_json_encode( $data ),
            'timeout' => 360
        ) );
    
        
        
        // Handle potential errors with the API request
        if ( is_wp_error( $response ) ) {
            # given prompt to proqyz_ai
            $this->update_review_meta($this->review_id, "response", $response->get_error_message());
            return (object) [
                'error' => (object) [
                    'message' => $response->get_error_message(),
                    'code'    => 'request_failed',
                    'status'  => 500,
                ]
            ];
        }
    
        // Retrieve response code and body
        $response_code  = wp_remote_retrieve_response_code( $response );
        $body           = wp_remote_retrieve_body( $response );
        $result         = json_decode( $body, true );
    
        # given prompt to proqyz_ai
        $this->update_review_meta($this->review_id, "response", serialize($result) );
        // If the response code is not successful (200), return an error
        if ( $response_code !== 200 ) {
            return (object) [
                'error' => (object) [
                    'message' => isset( $result['error']['message'] ) ? $result['error']['message'] : 'Unknown error',
                    'code'    => isset( $result['error']['type'] ) ? $result['error']['type'] : 'unknown_error',
                    'status'  => $response_code,
                ]
            ];
        }
    
        // Check if a valid AI response is received
        if ( isset( $result['choices'][0]['message']['content'] ) ) {
            return (object) [
                'success' => (object) [
                    'message' => 'Response from AI',
                    'body' => $result['choices'][0]['message']['content'],
                ]
            ];
        }
    
        // Return error if no valid response is found
        return (object) [
            'error' => (object) [
                'message' => 'No valid response from OpenAI.',
                'code'    => 'invalid_response',
                'status'  => 500,
            ]
        ];
    }

    /**
     * v2.1.0
     * Handle the AI Payload data
     */
    public function parse_task_html_to_prompt($html, $task_order, $answer, $timespend = '') {
        // Load the HTML into a DOMDocument
        $dom = new DOMDocument();
        @$dom->loadHTML($html);
    
        // Initialize the prompt
        $prompt = "";
    
        // Find the task title (Writing Task 1 or 2)
        $h1_elements = $dom->getElementsByTagName('h1');
        $task_type = "Task ".$task_order;

        /* foreach ($h1_elements as $h1) {
            if (strpos(strtolower($h1->textContent), 'writing task 1') !== false) {
                $task_type = 'Task 1';
            } elseif (strpos(strtolower($h1->textContent), 'writing task 2') !== false) {
                $task_type = 'Task 2';
            }
        } */
    
        // Add the task type to the prompt
        
        $prompt .= "Below is given input payload.\n\n";

    
        // Extract question text (from <p> tags)
        $paragraphs = $dom->getElementsByTagName('p');
        $question_text = "";
        foreach ($paragraphs as $p) {
            $question_text .= $p->textContent;
        }
        $prompt .= "Task:\n". trim($question_text)."\n\n";
        if($task_type !== ""){
            $prompt .= "Task Type:".$task_type."\n\n";
        }
    
        // Find any image tags (if task is Task 1 and contains an image)
        $image_description = "";
        $img_tags = $dom->getElementsByTagName('img');
        foreach ($img_tags as $img) {
            $image_url = $img->getAttribute('src');
            $alt_text = $img->getAttribute('alt'); // Fetch the alt text (image description)
            if ($image_url) {
                $prompt .= "Image URL: $image_url \n\n";
            }

            if ($image_url && $alt_text) {
                $image_description = $alt_text;
                $prompt .= "Task Image Description:\n ".$image_description."\n\n";
            }
        }
    
        // Add the user response and time spent
        $prompt .= "User Response:\n".$answer."\n\n";
        
        // $prompt .= "[Time Spent]: $timespend\n";
    
        return $prompt;
    }

    /**
     * v2.1.0
     */
    public function update_review_meta( $review_id, $review_meta_key, $review_meta_value ) {
        global $wpdb;
        $check_meta = $wpdb->get_row("SELECT `ID` FROM {$this->table_submissions_review_meta} WHERE `review_id` = '$review_id' AND `meta_key` = '$review_meta_key' AND `meta_status` = 1 ");
        if( !$check_meta ) {
            $wpdb->insert($this->table_submissions_review_meta, [
                "review_id"     => $review_id,
                "meta_key"      => $review_meta_key,
                "meta_value"    => $review_meta_value,
                "meta_status"   => 1
            ]);

            return $wpdb->insert_id;

        }

        $wpdb->update($this->table_submissions_review_meta, [
            "meta_value"    => $review_meta_value
        ], [
            "ID" => $check_meta->ID,
        ]);

        return $check_meta->ID;
    }

}

// Instantiate the plugin class
return Writing_AI_Evaluation::instance();