<?php
/** -------------------------------------------------------------------
 * v3.1.0
 * file: utill.php
 * status: pending
 * -------------------------------------------------------------------
 */



/**
 * load quiz
 * v3.1.0
 * status: pending
 */
function load_quiz($params = []) {
    global $wpdb, 
    $table_proqyz_v3_progress_submissions, 
    $table_proqyz_v3_progress_submissions_meta,
    $table_proqyz_v3_progress_meta_submissions,
    $table_proqyz_v3_progress_submissions_user_response,
	$table_proqyz_v3_progress_submissions_session;

    $params     = (object) $params;
    $category   = (string) $params->category;
    $response   = (object) $params->res;
    $session    = (object) $params->session;

    # get latest course 
    if(!class_exists('ST_ProQyz_Oauth')) {
        $proqyz_response = "OAuth failed: class not found";
        require_once ST_PROQYZ_ABSPATH . "/includes/templates/errors/401.php";
        exit;
    }
    
    if(isset($response)) {
        if(isset($response->success)) {
            $success = (object) $response->success;
            if(isset($success->has_json)) {
                if(isset($success->json)) {
                    # valid response
                    $json = (object) $success->json;
                    # configure quiz object
                    if( !isset($json->_q)){
                        $proqyz_response = 'Loaded Data is invalid format';
                        include_once ST_PROQYZ_ABSPATH . '/includes/templates/errors/404.php';
                        exit;
                    }

                    $main_quiz = (object) $json->_q;
                    $quiz_config  = (object) $main_quiz->quiz;
                    $sections     = (array) $main_quiz->sections;
                    $questions    = (array) $main_quiz->questions;
                    $_id          = $main_quiz->_id;
                    $quiz_type    = $quiz_config->_type;

                    $quiz_category_combine  = $quiz_type."-".$quiz_config->_category;
                    if( $category === $quiz_category_combine){
                        # load reading
                        if( $category === "ielts-reading" ) {
                            require_once 'class-reading.php';
                            require_once 'class-progress.php';
                            if( class_exists('Reading') && class_exists('Progress') ) {
            
                                # check for resume details
                                
                                $progress_report = new Progress((object) $session);
                                $session_report  = (object) $progress_report->check_session();
                                $session_details = (object) $progress_report->get_session();
                
                                # logic defined here
                                $resume         = false;
                                $user_data      = null;
                                $result         = false;
                                $seconds        = 0;
                
                                if( $session_report !== null && $session_details !== null ) {
                                    if(isset($session_report->status)) {
                                        $session_type       = isset($session_report->session_type)? $session_report->session_type : null;
                                        $session_category   = isset($session_report->session_category)? $session_report->session_category : null;
                                        $session_logic      = isset($session_report->logic)? $session_report->logic : null;
                                        $session_id         = isset($session_report->resume_id)? $session_report->resume_id : null;
                    
                                        # check session logic , if its for resume or fresh
                                        if( $session_logic == "update" ) {
                                            // apply v3 new logic here
                                            $get_resume_session = $wpdb->get_row("SELECT `response_data` FROM `$table_proqyz_v3_progress_submissions_user_response` WHERE `submission_id` = '$session_id' LIMIT 1");
                                            // $get_resume_session = $wpdb->get_row("SELECT `meta_value` FROM `$table_proqyz_progress_submissions_meta` WHERE `submission_id` = '$session_id' AND `meta_key` = 'json' LIMIT 1");
                                            if( $get_resume_session ) {
                                                $user_response = $get_resume_session->response_data;
                                                $user_response = (object) maybe_unserialize($user_response);
                                                if( $user_response ) {
                                                    $resume = true;
                                                    $user_data = $user_response;
                                                    $seconds = $user_data->quiz->diff;
                                                }
                                                
                                            }
                                        } 
                                    }
                                }
                                
                
                                $reading_obj = new Reading((object) [
                                    "_q"          => (object) $main_quiz,
                                    "sections"    => (array) $sections,
                                    "questions"   => (array) $questions,
                                    "_id"         => (string) $_id,
                                    "category"    => (string) $category,
                                    "quiz"        => (object) $quiz_config,
                                    "seconds"     => $seconds,
                                    "resume"      => $resume,
                                    "result"      => $result,
                                    "solution"    => false,
                                    "user_data"   => $user_data,
                                    "session"     => (object) $session,
                                    "student_id"  => get_current_user_id()    
                                ]);
                
                                return $reading_obj->get_layout();
            
                            }
                        } else if( $category === "ielts-listening" ) {
                            require_once 'class-listening.php';
                            require_once 'class-progress.php';

                            if( class_exists('Listening') && class_exists('Progress') ) {
            
                                # check for resume details
                                $progress_report = new Progress((object) $session);
                                $session_report  = (object) $progress_report->check_session();
                                $session_details = (object) $progress_report->get_session();
                
                                # logic defined here
                                $resume         = false;
                                $user_data      = null;
                                $result         = false;
                                $seconds        = 0;
                
                                if( $session_report !== null && $session_details !== null ) {
                                    if(isset($session_report->status)) {
                                        $session_type       = isset($session_report->session_type)? $session_report->session_type : null;
                                        $session_category   = isset($session_report->session_category)? $session_report->session_category : null;
                                        $session_logic      = isset($session_report->logic)? $session_report->logic : null;
                                        $session_id         = isset($session_report->resume_id)? $session_report->resume_id : null;
                    
                                        # check session logic , if its for resume or fresh
                                        if( $session_logic == "update" ) {
                                            //$get_resume_session = $wpdb->get_row("SELECT `meta_value` FROM `$table_proqyz_progress_submissions_meta` WHERE `submission_id` = '$session_id' AND `meta_key` = 'json' LIMIT 1");
                                            $get_resume_session = $wpdb->get_row("SELECT `response_data` FROM `$table_proqyz_v3_progress_submissions_user_response` WHERE `submission_id` = '$session_id' LIMIT 1");
                                            if( $get_resume_session ) {
                                                $user_response = $get_resume_session->response_data;
                                                $user_response = (object) maybe_unserialize($user_response);
                                                if( $user_response ) {
                                                    $resume = true;
                                                    $user_data = $user_response;
                                                    $seconds = $user_data->quiz->diff;
                                                }
                                            }
                                        }
                                    }
                                }
                                
                                $listening_obj = new Listening((object) [
                                    "_q"          => (object) $main_quiz,
                                    "sections"    => (array) $sections,
                                    "questions"   => (array) $questions,
                                    "_id"         => (string) $_id,
                                    "category"    => (string) $category,
                                    "quiz"        => (object) $quiz_config,
                                    "seconds"     => $seconds,
                                    "resume"      => $resume,
                                    "result"      => $result,
                                    "solution"    => false,
                                    "user_data"   => $user_data,
                                    "session"     => (object) $session,
                                    "student_id"  => get_current_user_id()     
                                ]);
                
                                return $listening_obj->get_layout();
            
                            }
            
                        } else if( $category === "ielts-writing" ) {
                            
                            require_once 'class-writing.php';
                            require_once 'class-progress.php';
                
                            if( class_exists('Writing') && class_exists('Progress') ) {
                
                                # check for resume details
                                $progress_report = new Progress((object) $session);
                                $session_report  = (object) $progress_report->check_session();
                                $session_details = (object) $progress_report->get_session();
                
                                # logic defined here
                                $resume         = false;
                                $user_data      = null;
                                $result         = false;
                                $seconds        = 0;
                
                                if( $session_report !== null && $session_details !== null ) {
                                    if(isset($session_report->status)) {
                                        $session_type       = isset($session_report->session_type)? $session_report->session_type : null;
                                        $session_category   = isset($session_report->session_category)? $session_report->session_category : null;
                                        $session_logic      = isset($session_report->logic)? $session_report->logic : null;
                                        $session_id         = isset($session_report->resume_id)? $session_report->resume_id : null;
                    
                                        # check session logic , if its for resume or fresh
                                        if( $session_logic == "update" ) {
                                            $get_resume_session = $wpdb->get_row("SELECT `response_data` FROM `$table_proqyz_v3_progress_submissions_user_response` WHERE `submission_id` = '$session_id' LIMIT 1");
                                            //$get_resume_session = $wpdb->get_row("SELECT `meta_value` FROM `$table_proqyz_progress_submissions_meta` WHERE `submission_id` = '$session_id' AND `meta_key` = 'json' LIMIT 1");
                                            if( $get_resume_session ) {
                                                $user_response = $get_resume_session->response_data;
                                                $user_response = (object) maybe_unserialize($user_response);
                                                if( $user_response ) {
                                                    $resume = true;
                                                    $user_data = $user_response;
                                                    $seconds = $user_data->quiz->diff;
                                                }
                                            }
                                        }
                                    }
                                }
                                
                
                                $writing_obj = new Writing((object) [
                                    "_q"          => (object) $main_quiz,
                                    "sections"    => (array) $sections,
                                    "_id"         => (string) $_id,
                                    "category"    => (string) $category,
                                    "quiz"        => (object) $quiz_config,
                                    "seconds"     => $seconds,
                                    "resume"      => $resume,
                                    "result"      => $result,
                                    "solution"    => false,
                                    "user_data"   => $user_data,
                                    "session"     => (object) $session,
                                    "student_id"  => get_current_user_id()   
                                ]);
                
                                return $writing_obj->get_layout();
                
                            }
            
                        } else if( $category === "ielts-speaking" ) {

                            require_once 'class-speaking.php';
                            require_once 'class-progress.php';
                
                            if( class_exists('Speaking') && class_exists('Progress') ) {

                                # check for resume details
                                $progress_report = new Progress((object) $session);
                                $session_report  = (object) $progress_report->check_session();
                                $session_details = (object) $progress_report->get_session();
                
                                # logic defined here
                                $resume         = false;
                                $user_data      = null;
                                $result         = false;
                                $seconds        = 0;
                
                                $speaking_obj = new Speaking((object) [
                                    "_q"          => (object) $main_quiz,
                                    "sections"    => (array) $sections,
                                    "questions"   => (array) $questions,
                                    "_id"         => (string) $_id,
                                    "category"    => (string) $category,
                                    "quiz"        => (object) $quiz_config,
                                    "seconds"     => $seconds,
                                    "resume"      => $resume,
                                    "result"      => $result,
                                    "solution"    => false,
                                    "session"     => (object) $session,
                                    "student_id"  => get_current_user_id()     
                                ]);
                
                                return $speaking_obj->get_layout();
                
                            }
                        } else if( $category === "gov-sectional-timing" || $category === "gov-non-sectional-timing" ) {
                            require_once 'class-gov.php';
                            require_once 'class-progress.php';
                            if( class_exists('Gov') && class_exists('Progress') ) {

                                # check for resume details
                                $progress_report = new Progress((object) $session);
                                $session_report  = (object) $progress_report->check_session();
                                $session_details = (object) $progress_report->get_session();
                
                                # logic defined here
                                $resume         = false;
                                $user_data      = null;
                                $result         = false;
                                $seconds        = 0;
                
                                $gov_obj = new Gov((object) [
                                    "_q"          => (object) $main_quiz,
                                    "sections"    => (array) $sections,
                                    "questions"   => (array) $questions,
                                    "_id"         => (string) $_id,
                                    "category"    => (string) $category,
                                    "quiz"        => (object) $quiz_config,
                                    "seconds"     => $seconds,
                                    "resume"      => $resume,
                                    "result"      => $result,
                                    "solution"    => false,
                                    "session"     => (object) $session,
                                    "student_id"  => get_current_user_id()     
                                ]);
                
                                return $gov_obj->get_layout();
                
                            }
                        } else if( $category === "proqyz-pdf-quiz" ){
                            require_once 'class-pdf-quiz.php';
                            require_once 'class-progress.php';
                            if( class_exists('PdfQuiz') && class_exists('Progress') ) {
                                # check for resume details
                                $progress_report = new Progress((object) $session);
                                $session_report  = (object) $progress_report->check_session();
                                $session_details = (object) $progress_report->get_session();

                                # logic defined here
                                $resume         = false;
                                $user_data      = null;
                                $result         = false;
                                $seconds        = 0;

                                if( $session_report !== null && $session_details !== null ) {
                                    if(isset($session_report->status)) {
                                        $session_type       = isset($session_report->session_type)? $session_report->session_type : null;
                                        $session_category   = isset($session_report->session_category)? $session_report->session_category : null;
                                        $session_logic      = isset($session_report->logic)? $session_report->logic : null;
                                        $session_id         = isset($session_report->resume_id)? $session_report->resume_id : null;
                    
                                        # check session logic , if its for resume or fresh
                                        if( $session_logic == "update" ) {
                                            //$get_resume_session = $wpdb->get_row("SELECT `meta_value` FROM `$table_proqyz_progress_submissions_meta` WHERE `submission_id` = '$session_id' AND `meta_key` = 'json' LIMIT 1");
                                            $get_resume_session = $wpdb->get_row("SELECT `response_data` FROM `$table_proqyz_v3_progress_submissions_user_response` WHERE `submission_id` = '$session_id' LIMIT 1");
                                            if( $get_resume_session ) {
                                                $user_response = $get_resume_session->response_data;
                                                $user_response = (object) maybe_unserialize($user_response);
                                                if( $user_response ) {
                                                    $resume = true;
                                                    $user_data = $user_response;
                                                    $seconds = $user_data->quiz->diff;
                                                }
                                            }
                                        } 
                                    }
                                }



                                $pdfQuiz_obj = new PdfQuiz((object) [
                                    "_q"          => (object) $main_quiz,
                                    "_id"         => (string) $_id,
                                    "category"    => (string) $category,
                                    "quiz"        => (object) $quiz_config,
                                    "seconds"     => $seconds,
                                    "resume"      => $resume,
                                    "result"      => $result,
                                    "solution"    => false,
                                    "user_data"   => $user_data,
                                    "session"     => (object) $session,
                                    "student_id"  => get_current_user_id()    
                                ]);
                
                                return $pdfQuiz_obj->get_layout();
                            }
                            ?>
                            <!-- <pre><?php print_r($quiz_config); ?> -->
                            <?php 

                        } else {
                            return "Unknown category quiz";
                        }

                    } else {
                        return "Category not same";
                    }
                }
            } else {
                return "ERROR: has json";
            }
        } else {
            return "ERROR: success";
        }
    } else {
        return "ERROR: response";
    }
}


/**
 * v3.1.0
 * single page with start, resume button, if not then load quiz
 * status: pending
 */
function handle_quiz_page($proqyz_attempt_url = '',$proqyz_category = ''){ 
    $proqyz_action  = get_query_var('action');
    $proqyz_quiz_id = get_query_var('quiz_id');

    if ($proqyz_action === "start") {
        if( class_exists('ST_ProQyz_Oauth') ) {
            
            $where_params = [
                "where" => (object) [],
                "grant_type" => "request",
                "permission" => "quiz"
            ];
            $main_params = array_merge($where_params,[
                "request_id" => date("U")
            ]);
    
            // backend endpoint external
            $response = (object) ST_ProQyz_Oauth::rest_post_request("/quizzes/quiz/".$proqyz_quiz_id, $main_params);
            if (!isset($response->error)) {
                /**
                 * sections [html]
                * styles   [html]
                */
                $html_response = load_quiz((object) [
                    'category'          => $proqyz_category,
                    'res'               => $response,
                    'session'           => (object) [
                        "course_title"      => '',
                        "course"            => '',
                        "session_category"  => "single",
                        "course_id"         => null,
                        "lesson_id"         => null,
                        'course_category'   => null,
                        "quiz_category"     => $proqyz_category,
                        "api_id"            => $proqyz_quiz_id
                    ]
                ]);
            
                echo $html_response;
            } else {
                $error = (object) $response->error;
                if(isset($error->message)){
                    
                    $proqyz_response = $error->message;
                    include_once ST_PROQYZ_ABSPATH . '/includes/templates/errors/404.php';
                    exit;
                } else {
                    $proqyz_response = "Unknown Error";
                    include_once ST_PROQYZ_ABSPATH . '/includes/templates/errors/500.php';
                    exit;
                }
            }
        } else {
            $proqyz_response = 'It looks like there is an error with RestApi functionalities';
            include_once ST_PROQYZ_ABSPATH . '/includes/templates/errors/500.php';
            exit;
        }
    } else { ?>
        <!DOCTYPE html>
        <html <?php language_attributes(); ?>>
        <head>
            <meta charset="<?php bloginfo('charset'); ?>" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <title><?php wp_title(); ?></title>
        </head>
        <body class="">
            
            <a class="btn btn-primary" href="<?php echo esc_html($proqyz_attempt_url); ?>" target="_blank">Start</a>
            
            <!--BEGIN::SCRIPTS HERE-->
            <script type="application/json"></script>
            <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
            <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
            <!--END::SCRIPTS HERE-->
        </body>
        </html>
    <?php }
} 


/**
 * 3.1.0
 * status: pending
 * handle result analyze page
 */
function handle_result_analyze_page($proqyz_attempt_url = '') {
    global $wpdb, $table_proqyz_v3_progress_submissions, $table_proqyz_v3_progress_submissions_meta, $table_proqyz_v3_submissions_versioning;

    $ilms_action                = get_query_var('action');
    $ilms_quiz_category         = get_query_var('quiz_category');
    $ilms_quiz_slug             = get_query_var('quiz_slug');
    $ilms_quiz_id               = get_query_var('quiz_id');
    $ilms_result_id             = get_query_var('result_id');

    // get if this result is not already submitted
    $get_result_session = $wpdb->get_row("SELECT `ID` FROM `$table_proqyz_v3_progress_submissions` WHERE `ID` = '$ilms_result_id' AND `status` = 1 AND `session_status` = 1 LIMIT 1");
    if( $get_result_session ) {
        // redirect to result page
        $result_url = st_proqyz_get_result_url( $ilms_quiz_category, $ilms_quiz_slug, $ilms_quiz_id, $ilms_result_id );
        wp_safe_redirect($result_url);
        exit;
    } else {
        // submit the result
        $update_result = $wpdb->update($table_proqyz_v3_progress_submissions, ['session_status' => 1], ['ID' => $ilms_result_id]);
        if( $update_result ) {
            # using given result id, get session details using submission core table
            $get_result_submission = $wpdb->get_row("SELECT `user_id`, `quiz_category`, `session_type`, `session_category`, `course_category`, `course_id`, `topic_id`, `lesson_id`, `api_id` FROM `$table_proqyz_v3_progress_submissions` WHERE `ID` = '$ilms_result_id' LIMIT 1");
            if( $get_result_submission ) {
                $student_id = $get_result_submission->user_id;
                $quiz_category = $get_result_submission->quiz_category;
                $session_type = $get_result_submission->session_type;
                $session_category = $get_result_submission->session_category;
                $course_category = $get_result_submission->course_category;
                $course_id = $get_result_submission->course_id;
                $lesson_id = $get_result_submission->lesson_id;
                $topic_id = $get_result_submission->topic_id;
                $api_id = $get_result_submission->api_id;
                $quiz_json = null;
                $result_url = st_proqyz_get_result_url( $ilms_quiz_category, $ilms_quiz_slug, $ilms_quiz_id, $ilms_result_id );
                # get the quiz_version_id from submission meta table
                $get_quiz_version_id = $wpdb->get_row("SELECT `meta_value` FROM `$table_proqyz_v3_progress_submissions_meta` WHERE `submission_id` = '$ilms_result_id' AND `meta_key` = 'quiz_version_id' LIMIT 1");
                if( $get_quiz_version_id ) {
                    $quiz_version_id = $get_quiz_version_id->meta_value;
                    # get the quiz from quiz versioning table
                    $get_quiz_versioning = $wpdb->get_row("SELECT `meta_value` FROM `$table_proqyz_v3_submissions_versioning` WHERE `version_id` = '$quiz_version_id' AND `meta_key` = 'quiz' LIMIT 1");
                    if( $get_quiz_versioning ) {
                        $quiz_json = (object) maybe_unserialize($get_quiz_versioning->meta_value);
                    }
                }

                # calling hooks:
                # email notification: 
                apply_filters('proqyz_quiz__on_finish', [
                    "user_id"               => $student_id,
                    "quiz_category"         => $quiz_category,
                    "session_type"          => $session_type,
                    "session_category"      => $session_category,
                    "course_category"       => $course_category,
                    "course_id"             => $course_id,
                    "topic_id"              => $topic_id,
                    "lesson_id"             => $lesson_id,
                    "api_id"                => $api_id,
                    "result_url"            => $result_url,
                    "quiz"                  => $quiz_json
                ]);    

                # learndash hooks:  
                if( $course_category == "sfwd-course" ) {
                    /**
                     * moved to addon - proqyz-learndash 
                     */
                    apply_filters( 'proqyz_sfwd_complete_quiz', '', [
                        "user_id"               => $student_id,
                        "quiz_category"         => $quiz_category,
                        "session_type"          => $session_type,
                        "session_category"      => $session_category,
                        "course_category"       => $course_category,
                        "course_id"             => $course_id,
                        "topic_id"              => $topic_id,
                        "lesson_id"             => $lesson_id,
                        "api_id"                => $api_id
                    ]);
                }
            }

            
            // redirect to result page
            wp_safe_redirect($result_url);
            exit;
        } else {
            // error page
            include_once ST_PROQYZ_ABSPATH . "/includes/templates/errors/500.php";
            exit;
        }
    }
}


/**
* v3.1.0
* handle result page 
* status: pending
*/
function handle_result_page($proqyz_attempt_url = '') {
    global $wpdb, 
    $table_proqyz_v3_progress_submissions, 
    $table_proqyz_v3_progress_submissions_meta,
    $table_proqyz_v3_progress_meta_submissions,
    $table_proqyz_v3_submissions_review, 
    $table_proqyz_v3_submissions_review_meta,
    $table_proqyz_v3_submissions_versioning,
    $table_proqyz_v3_progress_submissions_user_response,
    $table_proqyz_v3_progress_submissions_session;

    // verify post

    $ilms_action                = get_query_var('action');
    $ilms_quiz_category         = get_query_var('quiz_category');
    $ilms_quiz_slug             = get_query_var('quiz_slug');
    $ilms_quiz_id               = get_query_var('quiz_id');
    $ilms_result_id             = get_query_var('result_id');

    /**
      * sections [html]
      * styles   [html]
    */
    
    $category   = (string) $ilms_quiz_category;
    $result_id  = (int) $ilms_result_id;
    $session    = (object) [];
    $main_quiz  = null;
    $session_details = null;
    $get_result_session = null;
    $student_id = null;
    $json = null;
    $remote_course = null;

    # get latest course 
    if(!class_exists('ST_ProQyz_Oauth')) {
        $proqyz_response = "OAuth failed: class not found";
        require_once ST_PROQYZ_ABSPATH . "/includes/templates/errors/401.php";
        exit;
    }

    if( 
        $category === "ielts-reading" || 
        $category === "ielts-listening" || 
        $category === "ielts-writing" || 
        $category === "ielts-speaking" || 
        $category === "gov-sectional-timing" || 
        $category === "gov-non-sectional-timing" || 
        $category === "proqyz-pdf-quiz" 
    ) {

        $course_subcategory = 'academic';
        $get_result_session = $wpdb->get_row("SELECT `user_id`, `course_id` FROM `$table_proqyz_v3_progress_submissions` WHERE `ID` = '$result_id' AND `status` = 1 AND `session_status` = 1 LIMIT 1");
        if( $get_result_session ) {
            $student_id = $get_result_session->user_id;
        }
        /**
         * v3.1.0  
         * status: pending
         * logic: get the quiz version id from submission meta table and then get the quiz from quiz versioning table
         */
        $get_quiz_meta = $wpdb->get_row("SELECT `meta_value` FROM `$table_proqyz_v3_progress_submissions_meta` WHERE `submission_id` = '$result_id' AND `meta_key` = 'quiz_version_id' LIMIT 1");
        if( $get_quiz_meta ) {
            $quiz_version_id = $get_quiz_meta->meta_value;
            # we need to get the quiz from quiz versioning table 
            $get_quiz_versioning = $wpdb->get_row("SELECT `meta_value` FROM `$table_proqyz_v3_submissions_versioning` WHERE `version_id` = '$quiz_version_id' AND `meta_key` = 'quiz' LIMIT 1");
            if( $get_quiz_versioning ) {
                $main_quiz = (object) maybe_unserialize($get_quiz_versioning->meta_value);
            }
        }

        /**
         * v3.1.0  
         * status: pending
         * logic: get the session details from submission meta table
         */
        $get_session_details = $wpdb->get_row("SELECT `session_data` FROM `$table_proqyz_v3_progress_submissions_session` WHERE `submission_id` = '$result_id' LIMIT 1");
        if( $get_session_details ) {
            $session_details = (object) maybe_unserialize($get_session_details->session_data);
        }

        /**
         * v3.1.0  
         * status: pending
         * logic: get the json from user response table
         */
        $get_user_response = $wpdb->get_row("SELECT `response_data` FROM `$table_proqyz_v3_progress_submissions_user_response` WHERE `submission_id` = '$result_id' LIMIT 1");
        if( $get_user_response ) {
            $json = (object) maybe_unserialize($get_user_response->response_data);
        }

        /**
         * v3.0.0.1  
         * status: pending
         * logic: get the course subcategory from submission meta table
         */
        $get_course_subcategory = $wpdb->get_row("SELECT `meta_value` FROM `$table_proqyz_v3_progress_submissions_meta` WHERE `submission_id` = '$result_id' AND `meta_key` = 'course_subcategory' LIMIT 1");
        if( $get_course_subcategory ) {
            $course_subcategory = $get_course_subcategory->meta_value;
        }
        if( $course_subcategory === null ) {
            $course_subcategory = 'academic';
        }



        /* -------------------------------------------- end:: v3.1.0 -------------------------------------------- */
    } else {
        return "Unknown category result";
    }

    // if result session not found then 404 page template with message
    if( $get_result_session === null ) {
        status_header(404);
        // Include the WordPress 404 template
        include get_404_template();
        // Optionally, you can exit the script here to prevent further execution
        exit;
        echo "[result] Result not found";
    }

    // if quiz not found then 404 page template with message
    if( $main_quiz === null ) {
        status_header(404);
        // Include the WordPress 404 template
        include get_404_template();
        // Optionally, you can exit the script here to prevent further execution
        exit;
        echo "Result not found";
    }

    // if session details not found then 404 page template with message
    if( $session_details === null ) {
        status_header(404);
        // Include the WordPress 404 template
        include get_404_template();
        // Optionally, you can exit the script here to prevent further execution
        exit;
        echo "[session details] Result not found";
    }

    // users permission check
    $user = get_userdata(get_current_user_id());
    if (!$user) { return null; }
    $user_roles = $user->roles;
    if (in_array("administrator", $user_roles)) {} elseif (in_array("teacher", $user_roles)) {} else {
        if($student_id != get_current_user_id()){
            $proqyz_response = "Access denied";
            require_once ST_PROQYZ_ABSPATH . "/includes/templates/errors/401.php";
            exit;
        }
    }

    // if category is ielts-writing/ielts-speaking then get the course details
    if( $category === "ielts-writing" || $category === "ielts-speaking" ) {
        $where_params_course = [
            "where" => (object) [],
            "grant_type" => "request",
            "permission" => "course"
        ];
        $main_params_course = array_merge($where_params_course,[
            "request_id" => date("U")
        ]);

        $rest_course = (object) ST_ProQyz_Oauth::rest_post_request("/courses/course/".($get_result_session->course_id), $main_params_course);
        if( isset($rest_course->success) ) {
            $remote_c_res  = (object) $rest_course->success;
            $remote_c_json = isset($remote_c_res->json)? (object) $remote_c_res->json : null;
            if( $remote_c_json ){
                $c = isset($remote_c_json->_c)? (object) $remote_c_json->_c : null;
                if( $c ){
                    $remote_course  = isset($c->course)? (object) $c->course : null;
                }
            }
        }

    }


    
    # load reading
    if( $category === "ielts-reading" ) {
        require_once 'class-reading.php';

        /**
         * table: $table_proqyz_progress_submissions
         * column: all columns
         */
            // $main_quiz is global variable above defined
            $quiz_config    = (object) $main_quiz->quiz;
            $sections       = (array) $main_quiz->sections;
            $questions      = (array) $main_quiz->questions;
            $_id            = $main_quiz->_id;
            $session        = (object) $session_details;

            if( class_exists('Reading') ) {
            
                # logic defined here
                $resume         = false;
                $user_data      = $json;
                $seconds        = 0;
                $result         = true;
    
                if( $user_data ) {
                    $seconds = $user_data->quiz->diff;
                }
        
                $reading_obj = new Reading((object) [
                    "sections"    => (array) $sections,
                    "questions"   => (array) $questions,
                    "_id"         => (string) $_id,
                    "category"    => (string) $category,
                    "quiz"        => (object) $quiz_config,
                    "seconds"     => $seconds,
                    "resume"      => $resume,
                    "result"      => $result,
                    "solution"    => false,
                    "user_data"   => $user_data,
                    "result_id"   => $result_id,
                    "session"     => (object) $session,
                    "_q"          => $main_quiz,
                    "student_id"  => $student_id,
                    "attempt_url"  => $proqyz_attempt_url,
                    "course_subcategory" => $course_subcategory
                ]);
        
                echo $reading_obj->get_result_layout();
            }
        

    } else if( $category === "ielts-listening" ) {

        require_once 'class-listening.php';

            // $main_quiz is global variable above defined
            $quiz_config    = (object) $main_quiz->quiz;
            $sections       = (array) $main_quiz->sections;
            $questions      = (array) $main_quiz->questions;
            $_id            = $main_quiz->_id;
            $session        = (object) $session_details;

            if( class_exists('Listening') ) {
            
                # logic defined here
                $resume         = false;
                $user_data      = $json;
                $seconds        = 0;
                $result         = true;
    
                if( $user_data ) {
                    $seconds = $user_data->quiz->diff;
                }
        
                $listening_obj = new Listening((object) [
                    "sections"    => (array) $sections,
                    "questions"   => (array) $questions,
                    "_id"         => (string) $_id,
                    "category"    => (string) $category,
                    "quiz"        => (object) $quiz_config,
                    "seconds"     => $seconds,
                    "resume"      => $resume,
                    "result"      => $result,
                    "solution"    => false,
                    "user_data"   => $user_data,
                    "result_id"   => $result_id,
                    "session"     => (object) $session,
                    "_q"          => $main_quiz,
                    "student_id"  => $student_id,  
                    "attempt_url"  => $proqyz_attempt_url,
                    "course_subcategory" => $course_subcategory
                ]);
        
                echo $listening_obj->get_result_layout();
            }
    } else if( $category === "ielts-writing" ) {

        require_once 'class-writing.php';

            $main_course    = (object) $session_details;
            $session        = (object) $session_details;
            $quiz_config    = (object) $main_quiz->quiz;
            $sections       = (array) $main_quiz->sections;
            $_id            = $main_quiz->_id;
            $user_data      = $json;
            $session_version = isset($main_course->session_version)? $main_course->session_version : null;
            if( $session_version == null ) {
                # modify the result as requirements
                
                # fetch answers for writing tasks
                $user_answers = (array) $user_data->answers;
                if( count($user_answers) > 0 ) {
                    if(count($sections) > 0 ) {
                        foreach( $sections as $skey => $section ) {
                            $key = $skey + 1;
                            $section = (object) $section;
                            if( isset($user_answers[$key]) ) {
                                $user_answers[$key]->id = $section->_id;
                                $user_answers[$key]->order = $section->order;
                            }
                        }
                        $user_data->answers = $user_answers;
                    }
                    
                }

                # modify the enrollment arrray as requirements
                // NEW: Use v3 evaluation metadata table
                $check_payment_for_tasksv2 = st_proqyz_get_submission_evaluation_meta($result_id, "enrolled_for", $student_id, true);
                // OLD: $check_payment_for_tasksv2 = get_user_meta($student_id, "st_proqyz__evaluation-" . ($result_id), true);
                
                if (!$check_payment_for_tasksv2) {
                    // Check legacy v1 format (still in usermeta for migration compatibility)
                    $check_payment_for_tasks_v1 = get_user_meta($student_id, "st_proqyz_ielts-lms_evaluation-" . ($result_id), true);
                    if ($check_payment_for_tasks_v1) {
                        $enroll_for = []; // Define as an array instead of an object
                        $enrollment = (array) json_decode($check_payment_for_tasks_v1);
                        
                        if (in_array("task-1", $enrollment)) {
                            $is_found_1 = reset(array_filter((array)$user_data->answers, function ($answer) {
                                return $answer->order == 1;
                            }));

                            if ($is_found_1) {
                                $section_1 = (object)$is_found_1;
                                $enroll_for[$section_1->id] = [
                                    "task_id"       => $section_1->id,
                                    "task_key"      => "writing-task-1",
                                    "payment_for"   => "instructor"
                                ];
                            }
                        }

                        if (in_array("task-2", $enrollment)) {
                            $is_found_2 = reset(array_filter((array)$user_data->answers, function ($answer) {
                                return $answer->order == 2;
                            }));

                            if ($is_found_2) {
                                $section_2 = (object)$is_found_2;
                                $enroll_for[$section_2->id] = [
                                    "task_id"       => $section_2->id,
                                    "task_key"      => "writing-task-2",
                                    "payment_for"   => "instructor"
                                ];
                            }
                        }

                        // NEW: Use v3 evaluation metadata table
                        st_proqyz_update_submission_evaluation_meta($result_id, "enrolled_for", json_encode($enroll_for), $student_id);
                        // OLD: update_user_meta($student_id, "st_proqyz__evaluation-" . ($result_id), json_encode($enroll_for));
                    }
                }
            }

            if($remote_course !== null){
                $main_course->course = $remote_course;
            }

            
            if( class_exists('Writing') ) {
            
                # logic defined here
                $resume         = false;
                
                $seconds        = 0;
                $result         = true;

                $writing_obj = new Writing((object) [
                    "sections"    => (array) $sections,
                    "questions"   => (array) [],
                    "_id"         => (string) $_id,
                    "category"    => (string) $category,
                    "course"      => (object) $main_course,  
                    "quiz"        => (object) $quiz_config,
                    "seconds"     => $seconds,
                    "resume"      => $resume,
                    "result"      => $result,
                    "solution"    => false,
                    "user_data"   => $user_data,
                    "result_id"   => $result_id,
                    "session"     => (object) $session,
                    "_q"          => $main_quiz,
                    "student_id"  => $student_id,
                    "attempt_url"  => $proqyz_attempt_url        
                ]);
        
                echo $writing_obj->get_result_layout();
            }
    
    } else if( $category === "ielts-speaking" ) {

        require_once 'class-speaking.php';

            // $main_quiz is global variable above defined
            $main_course    = (object) $session_details;
            $session        = (object) $session_details;
            $quiz_config    = (object) $main_quiz->quiz;
            $sections       = (array) $main_quiz->sections;
            $questions      = (array) $main_quiz->questions;
            $_id            = $main_quiz->_id;
            $user_data      = $json;

            if($remote_course !== null){
                $main_course->course = $remote_course;
            }

            
            if( class_exists('Speaking') ) {
            
                # logic defined here
                $resume         = false;
                $seconds        = 0;
                $result         = true;
    
            
                $speaking_obj = new Speaking((object) [
                    "sections"    => (array) $sections,
                    "questions"   => (array) $questions,
                    "_id"         => (string) $_id,
                    "category"    => (string) $category,
                    "quiz"        => (object) $quiz_config,
                    "course"      => (object) $main_course, 
                    "seconds"     => $seconds,
                    "resume"      => $resume,
                    "result"      => $result,
                    "solution"    => false,
                    "user_data"   => $user_data,
                    "result_id"   => $result_id,
                    "session"     => (object) $session,
                    "_q"          => $main_quiz,
                    "student_id"  => $student_id,
                    "attempt_url"  => $proqyz_attempt_url      
                ]);
        
                echo $speaking_obj->get_result_layout();
            }
        
    } else if( $category === "gov-sectional-timing" || $category === "gov-non-sectional-timing" ) {
        require_once 'class-gov.php';
            
            // $main_quiz is global variable above defined
            $quiz_config    = (object) $main_quiz->quiz;
            $sections       = (array) $main_quiz->sections;
            $questions      = (array) $main_quiz->questions;
            $_id            = $main_quiz->_id;
            $session        = (object) $session_details;

            if( class_exists('Gov') ) {
            
                # logic defined here
                $resume         = false;
                $user_data      = $json;
                $seconds        = 0;
                $result         = true;
    
                if( $user_data ) {
                    $seconds = $user_data->quiz->diff;
                }
        
                $gov_obj = new Gov((object) [
                    "sections"    => (array) $sections,
                    "questions"   => (array) $questions,
                    "_id"         => (string) $_id,
                    "category"    => (string) $category,
                    "quiz"        => (object) $quiz_config,
                    "seconds"     => $seconds,
                    "resume"      => $resume,
                    "result"      => $result,
                    "solution"    => false,
                    "user_data"   => $user_data,
                    "result_id"   => $result_id,
                    "session"     => (object) $session,
                    "_q"          => $main_quiz,
                    "student_id"  => $student_id      
                ]);

                
        
                echo $gov_obj->get_result_layout();
            }
        
    } else if( $category === "proqyz-pdf-quiz" ){
        require_once 'class-pdf-quiz.php';

            // $main_quiz is global variable above defined
            $quiz_config    = (object) $main_quiz->quiz;
            $_id            = $main_quiz->_id;
            $session        = (object) $session_details;

            if( class_exists('PdfQuiz') ) {
            
                # logic defined here
                $resume         = false;
                $user_data      = $json;
                $seconds        = 0;
                $result         = true;
    
                if( $user_data ) {
                    $seconds = $user_data->quiz->diff;
                }

                $pdfQuiz_obj = new PdfQuiz((object) [
                    "_q"          => (object) $main_quiz,
                    "_id"         => (string) $_id,
                    "category"    => (string) $category,
                    "quiz"        => (object) $quiz_config,
                    "seconds"     => $seconds,
                    "resume"      => $resume,
                    "result"      => $result,
                    "solution"    => false,
                    "user_data"   => $user_data,
                    "result_id"   => $result_id,
                    "session"     => (object) $session,
                    "student_id"  => $student_id,
                    "attempt_url"  => $proqyz_attempt_url    
                ]);
        
                echo $pdfQuiz_obj->get_result_layout();
            }

    }

}

/**
 * v3.1.0
 * handle review page
 * status: pending
 */
function handle_review_page($proqyz_attempt_url = '') {
    
    global $wpdb, 
    $table_proqyz_v3_progress_submissions, 
    $table_proqyz_v3_progress_submissions_meta,
    $table_proqyz_v3_progress_meta_submissions,
    $table_proqyz_v3_submissions_review, 
    $table_proqyz_v3_submissions_review_meta,
    $table_proqyz_v3_submissions_versioning,
    $table_proqyz_v3_progress_submissions_user_response,
    $table_proqyz_v3_progress_submissions_session;
    // verify post

    $ilms_action                = get_query_var('action');
    $ilms_quiz_category         = get_query_var('quiz_category');
    $ilms_quiz_slug             = get_query_var('quiz_slug');
    $ilms_quiz_id               = get_query_var('quiz_id');
    $ilms_result_id             = get_query_var('result_id');

    /**
      * sections [html]
      * styles   [html]
    */
    
    $category   = (string) $ilms_quiz_category;
    $result_id  = (int) $ilms_result_id;


    $get_result_session = null;
    $remote_course = null;
    $main_quiz = null;
    $session_details = null;
    $student_id = null;
    $json = null;
    # get latest course 
    if(!class_exists('ST_ProQyz_Oauth')) {
        $proqyz_response = "OAuth failed: class not found";
        require_once ST_PROQYZ_ABSPATH . "/includes/templates/errors/401.php";
        exit;
    }

    if( $category === "ielts-writing" || $category === "ielts-speaking" ) {
        $get_result_session = $wpdb->get_row("SELECT `user_id`, `course_id` FROM `$table_proqyz_v3_progress_submissions` WHERE `ID` = '$result_id' AND `status` = 1 AND `session_status` = 1 LIMIT 1");
        if( $get_result_session ) {
            $student_id = $get_result_session->user_id;

            /**
             * v3.1.0  
             * status: pending
             * logic: get the quiz version id from submission meta table and then get the quiz from quiz versioning table
             */
            $get_quiz_meta = $wpdb->get_row("SELECT `meta_value` FROM `$table_proqyz_v3_progress_submissions_meta` WHERE `submission_id` = '$result_id' AND `meta_key` = 'quiz_version_id' LIMIT 1");
            if( $get_quiz_meta ) {
                $quiz_version_id = $get_quiz_meta->meta_value;
                # we need to get the quiz from quiz versioning table 
                $get_quiz_versioning = $wpdb->get_row("SELECT `meta_value` FROM `$table_proqyz_v3_submissions_versioning` WHERE `version_id` = '$quiz_version_id' AND `meta_key` = 'quiz' LIMIT 1");
                if( $get_quiz_versioning ) {
                    $main_quiz = (object) maybe_unserialize($get_quiz_versioning->meta_value);
                }
            }

            /**
             * v3.1.0  
             * status: pending
             * logic: get the session details from submission meta table
             */
            $get_session_details = $wpdb->get_row("SELECT `session_data` FROM `$table_proqyz_v3_progress_submissions_session` WHERE `submission_id` = '$result_id' LIMIT 1");
            if( $get_session_details ) {
                $session_details = (object) maybe_unserialize($get_session_details->session_data);
            }

            /**
             * v3.1.0  
             * status: pending
             * logic: get the json from user response table
             */
            $get_user_response = $wpdb->get_row("SELECT `response_data` FROM `$table_proqyz_v3_progress_submissions_user_response` WHERE `submission_id` = '$result_id' LIMIT 1");
            if( $get_user_response ) {
                $json = (object) maybe_unserialize($get_user_response->response_data);
            }
        }
    } else {
        return "Review is not available for this category: $category";
    }

    // if quiz not found then 404 page template with message
    if( $main_quiz === null ) {
        status_header(404);
        // Include the WordPress 404 template
        include get_404_template();
        // Optionally, you can exit the script here to prevent further execution
        exit;
        echo "Result not found";
    }

    // if session details not found then 404 page template with message
    if( $session_details === null ) {
        status_header(404);
        // Include the WordPress 404 template
        include get_404_template();
        // Optionally, you can exit the script here to prevent further execution
        exit;
        echo "[session details] Result not found";
    }

    $user = get_userdata(get_current_user_id());
    if (!$user) { return null; }
    $user_roles = $user->roles;
    if (in_array("administrator", $user_roles)) {} elseif (in_array("teacher", $user_roles)) {} else {
        if($student_id != get_current_user_id()){
            $proqyz_response = "Access denied";
            require_once ST_PROQYZ_ABSPATH . "/includes/templates/errors/401.php";
            exit;
        }
    }

    # permission config
    $where_params_course = [
        "where" => (object) [],
        "grant_type" => "request",
        "permission" => "course"
    ];

    $main_params_course = array_merge($where_params_course,[
        "request_id" => date("U")
    ]);

    $rest_course = (object) ST_ProQyz_Oauth::rest_post_request("/courses/course/".($get_result_session->course_id), $main_params_course);
    if( isset($rest_course->success) ) {
        $remote_c_res  = (object) $rest_course->success;
        $remote_c_json = isset($remote_c_res->json)? (object) $remote_c_res->json : null;
        if( $remote_c_json ){
            $c = isset($remote_c_json->_c)? (object) $remote_c_json->_c : null;
            if( $c ){
                $remote_course  = isset($c->course)? (object) $c->course : null;
                
            }
        }
    }


    if( $category === "ielts-writing" ) {
        require_once 'class-writing.php';

            // $main_quiz is global variable above defined
            $main_course    = (object) $session_details;
            $quiz_config    = (object) $main_quiz->quiz;
            $sections       = (array) $main_quiz->sections;
            $_id            = $main_quiz->_id;

            # helper function for converting
            $user_data = $json;
            $session_version = isset($main_course->session_version)? $main_course->session_version : null;
            if( $session_version == null ) {
                # modify the result as requirements
                
                # fetch answers for writing tasks
                $user_answers = (array) $user_data->answers;
                if( count($user_answers) > 0 ) {
                    if(count($sections) > 0 ) {
                        foreach( $sections as $skey => $section ) {
                            $key = $skey + 1;
                            $section = (object) $section;
                            if( isset($user_answers[$key]) ) {
                                $user_answers[$key]->id = $section->_id;
                                $user_answers[$key]->order = $section->order;
                            }
                        }
                        $user_data->answers = $user_answers;
                    }
                    
                }
                # modify the enrollment arrray as requirements
                
                // NEW: Use v3 evaluation metadata table
                $check_payment_for_tasksv2 = st_proqyz_get_submission_evaluation_meta($result_id, "enrolled_for", $student_id, true);
                // OLD: $check_payment_for_tasksv2 = get_user_meta($student_id, "st_proqyz__evaluation-" . ($result_id), true);
                
                if (!$check_payment_for_tasksv2) {
                    // Check legacy v1 format (still in usermeta for migration compatibility)
                    $check_payment_for_tasks_v1 = get_user_meta($student_id, "st_proqyz_ielts-lms_evaluation-" . ($result_id), true);
                    if ($check_payment_for_tasks_v1) {
                        $enroll_for = []; // Define as an array instead of an object
                        $enrollment = (array) json_decode($check_payment_for_tasks_v1);
                        
                        if (in_array("task-1", $enrollment)) {
                            $is_found_1 = reset(array_filter((array)$user_data->answers, function ($answer) {
                                return $answer->order == 1;
                            }));

                            if ($is_found_1) {
                                $section_1 = (object)$is_found_1;
                                $enroll_for[$section_1->id] = [
                                    "task_id"       => $section_1->id,
                                    "task_key"      => "writing-task-1",
                                    "payment_for"   => "instructor"
                                ];
                            }
                        }

                        if (in_array("task-2", $enrollment)) {
                            $is_found_2 = reset(array_filter((array)$user_data->answers, function ($answer) {
                                return $answer->order == 2;
                            }));

                            if ($is_found_2) {
                                $section_2 = (object)$is_found_2;
                                $enroll_for[$section_2->id] = [
                                    "task_id"       => $section_2->id,
                                    "task_key"      => "writing-task-2",
                                    "payment_for"   => "instructor"
                                ];
                            }
                        }

                        // NEW: Use v3 evaluation metadata table
                        st_proqyz_update_submission_evaluation_meta($result_id, "enrolled_for", json_encode($enroll_for), $student_id);
                        // OLD: update_user_meta($student_id, "st_proqyz__evaluation-" . ($result_id), json_encode($enroll_for));
                    }
                }

                
            }

            if($remote_course !== null){
                $main_course->course = $remote_course;
            }

            if( class_exists('Writing') ) {
                # logic defined here
                $resume         = false;
                $seconds        = 0;
                $result         = true;
                $review         = true;

                $writing_obj = new Writing((object) [
                    "sections"    => (array) $sections,
                    "questions"   => (array) [],
                    "_id"         => (string) $_id,
                    "category"    => (string) $category,
                    "quiz"        => (object) $quiz_config,
                    "course"      => (object) $main_course,  
                    "seconds"     => $seconds,
                    "resume"      => $resume,
                    "result"      => $result,
                    "review"      => $review,  
                    "solution"    => false,
                    "user_data"   => $user_data,
                    "result_id"   => $result_id,
                    "session"     => (object) $session,
                    "_q"          => $main_quiz,
                    "student_id"  => $student_id,
                ]);
        
                echo $writing_obj->get_result_layout();
            }
        
    } else if( $category === "ielts-speaking" ) {
        
        require_once 'class-speaking.php';

            // $main_quiz is global variable above defined
            $main_course    = (object) $session_details;
            $quiz_config    = (object) $main_quiz->quiz;
            $sections       = (array) $main_quiz->sections;
            $questions      = (array) $main_quiz->questions;
            $_id            = $main_quiz->_id;

            if($remote_course !== null){
                $main_course->course = $remote_course;
            }

            
            if( class_exists('Speaking') ) {
            
                # logic defined here
                $resume         = false;
                $user_data      = $json;
                $seconds        = 0;
                $result         = true;
                $review         = true;
    
                $speaking_obj = new Speaking((object) [
                    "sections"    => (array) $sections,
                    "questions"   => (array) $questions,
                    "_id"         => (string) $_id,
                    "category"    => (string) $category,
                    "quiz"        => (object) $quiz_config,
                    "course"      => (object) $main_course,  
                    "seconds"     => $seconds,
                    "resume"      => $resume,
                    "result"      => $result,
                    "review"      => $review,  
                    "solution"    => false,
                    "user_data"   => $user_data,
                    "result_id"   => $result_id,
                    "session"     => (object) $session,
                    "_q"          => $main_quiz,
                    "student_id"  => $student_id,
                ]);
        
                echo $speaking_obj->get_result_layout();
            }
    }

}
