<?php
namespace QuizPress\Ajax;

use QuizPress\Helper;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

use QuizPress\Classes\Sanitizer;
use QuizPress\Classes\AbstractAjaxHandler;
use QuizPress\API\Query\Attempts as Query;
use QuizPress\API\Query\Quizzes as QuizQuery;
use QuizPress\API\Query\Questions as Questions;
use QuizPress\API\Query\Answers as Answers;

class Admin extends AbstractAjaxHandler {
    protected $namespace = 'quizpress/admin';
    public function __construct()
    {
		$this->actions = array(
			'get_admin_menu_items'  => array(
                'callback' => array( $this, 'get_admin_menu_items' ),
				'capability' => 'manage_options' 
            ),
			'get_quiz_submission_rate' => array(
				'callback' => array( $this, 'get_quiz_submission_rate' ),
                'capability' => 'manage_options'
			),
			'get_quiz_options' => array(
				'callback' => array( $this, 'get_quiz_options' ),
                'capability' => 'manage_options'
			),
            'get_quizpress_users' => array(
                'callback' => array( $this, 'get_users' ),
                'capability' => 'manage_options'
            ),
            'update_quizpress_quiz_status' => array(
                'callback' => array( $this, 'update_quizpress_quiz_status' ),
                'capability' => 'manage_options'
            ),

            'get_quiz_attempt_answers_details' => array(
				'callback' => array( $this, 'get_quiz_attempt_answers_details' ),
				'capability' => 'manage_options',
			),
            'attempt_answer_manually_review' => array(
				'callback' => array( $this, 'attempt_answer_manually_review' ),
				'capability' => 'manage_options',
			),
            'update_quiz_attempt_manual_feedback' => array(
				'callback' => array( $this, 'update_quiz_attempt_manual_feedback' ),
				'capability' => 'manage_options',
			),
            'delete_quiz_attempts' => array(
				'callback' => array( $this, 'delete_quiz_attempts' ),
				'capability' => 'manage_options',
			),
            'update_quiz_question_order' => array(
				'callback' => array( $this, 'update_quiz_question_order' ),
				'capability' => 'manage_options',
			),
			'get_quiz_attempt_feedback' => array(
				'callback' => array( $this, 'get_quiz_attempt_feedback' ),
				'capability' => 'manage_options',
			),
		);
    }

	public function get_admin_menu_items() {
		wp_send_json_success( Helper::get_admin_menu_list() );
	}

    public function get_quiz_submission_rate( $payload_data ) {
        $payload = Sanitizer::sanitize_payload(
            [
                'month' => 'string',
                'days'  => 'integer'
            ],
            $payload_data
        );

        $days = ! empty( $payload['days'] ) ? (int) sanitize_text_field( $payload['days'] ) : 0;
        $from = '';
        $to = '';
        if ( $days > 0 ) {
            $from = gmdate( 'Y-m-d', strtotime( "-{$days} days" ) );
            $to   = gmdate( 'Y-m-d', strtotime( '+1 day' ) );
        }

        $data = Query::get_attempt_info( $from, $to );
        wp_send_json_success( $data );
    }

    public function get_quiz_options( ) {
        $get_results = QuizQuery::get_all_quiz_options();
        foreach( $get_results as $item ) {
            $item->id = (int) $item->id;
        }
        wp_send_json_success( $get_results );
    }

    public function get_users() {
        $users = get_users( array(
            'fields' => array( 'ID', 'display_name', 'user_email' ),
        ) );

        wp_send_json_success( $users );
    }

    public function update_quizpress_quiz_status( $payload_data ) {
        $payload = Sanitizer::sanitize_payload( [ 'quiz_id' => 'integer', 'status' => 'string' ], $payload_data );
        $is_update = wp_update_post(
            [
                'ID' => $payload['quiz_id'],
                'post_status' => $payload['status']
            ]
        );
        wp_send_json_success( $is_update );
    }

    public function get_quiz_attempt_answers_details( $payload_data ) {
		$payload = Sanitizer::sanitize_payload([
			'user_id' => 'integer',
			'attempt_id' => 'integer',
		], $payload_data );

        $user_id = isset( $payload['user_id'] ) ? $payload['user_id'] : 0;
		if ( ! $user_id ) {
			$user_id = get_current_user_id();
		}


		if(! $payload['attempt_id']) {
			wp_send_json_error(__('Required payload missing.'));
		}

		$attempt_id = $payload['attempt_id'];
		
		$prepare_response = [];
		$attempt_details = Query::get_quiz_attempt_details( $attempt_id, $user_id );
		$is_required_manual_review = false;
		foreach ( $attempt_details as $attempt_item ) {
			if ( ! $attempt_item->is_manually_reviewed ) {
				$is_required_manual_review = in_array( $attempt_item->question_type, [ 'short_answer', 'paragraph', 'number', 'date', 'file_upload' ] ) ? true : false;
			}
			$attempt_item->is_required_manual_review = $is_required_manual_review;
			$attempt_item->given_answer = \QuizPress\API\Query\Answers::prepare_given_answer( $attempt_item->question_type, $attempt_item );
			$attempt_item->is_correct = (int) $attempt_item->is_correct;
			$attempt_item->correct_answer = \QuizPress\API\Query\Answers::prepare_correct_answer( $attempt_item->question_type, $attempt_item );
			$attempt_item->question_title = html_entity_decode( $attempt_item->question_title );
			$prepare_response[ $attempt_item->attempt_answer_id ] = $attempt_item;
		}

		wp_send_json_success( array_values( $prepare_response ) );
	}

    public function attempt_answer_manually_review( $payload_data ) {
		$payload = Sanitizer::sanitize_payload([
			'attempt_answer_id' => 'integer',
			'attempt_id' => 'integer',
			'question_id' => 'integer',
			'quiz_id' => 'integer',
			'mark_as' => 'string',
		], $payload_data );
    

		$attempt_answer_id = ( isset( $payload['attempt_answer_id'] ) ? $payload['attempt_answer_id'] : 0 );
		$attempt_id = ( isset( $payload['attempt_id'] ) ? $payload['attempt_id'] : 0 );
		$question_id = ( isset( $payload['question_id'] ) ? $payload['question_id'] : 0 );
		$mark_as = ( isset( $payload['mark_as'] ) ? $payload['mark_as'] : '' );
		// get question
		$question = Questions::get_quiz_question( $question_id );
		$attempt_answer = Answers::get_quiz_attempt_answer( $attempt_answer_id );
		$attempt_answer->attempt_id = $attempt_id;
		$attempt_answer->question_mark = $question->question_score;
		$achieved_mark = 'correct' === $mark_as ? $question->question_score : ( - $question->question_negative_score ?? '' );
		$attempt_answer->achieved_mark = $achieved_mark;
		$attempt_answer->is_correct = 'correct' === $mark_as ? 1 : 0;
		// update attempt answer
		$attempt_answer_id = Query::quiz_attempt_answer_insert( (array) $attempt_answer );
		// prepare attempt data
		$attempt_data = Query::calculate_attempt_data( $attempt_answer->quiz_id, $attempt_id, $attempt_answer->user_id );
		unset( $attempt_data['percentage'] );
		unset( $attempt_data['skip_questions'] );
		$prepared_attempt = array_merge( (array) Query::get_quiz_attempt( $attempt_id ), $attempt_data );
		$attempt_info = array_merge( $attempt_data['attempt_info'], array(
			'total_correct_answers' => Answers::get_total_quiz_attempt_correct_answers( $attempt_id )
		));
		$prepared_attempt['attempt_info'] = wp_json_encode( wp_unslash( $attempt_info ) );
		$prepared_attempt['manually_reviewed_at'] = current_time( 'mysql' );
		$prepared_attempt['is_manually_reviewed'] = true;
		$attempt_id = Query::quiz_attempt_insert( wp_unslash( (array) $prepared_attempt ) );
		wp_send_json_success( $attempt_answer_id );
	}

    public function update_quiz_attempt_manual_feedback( $payload_data ) {
		$payload = Sanitizer::sanitize_payload([
			'attempt_id' => 'integer',
			'feedback' => 'string',
		], $payload_data );

		$attempt_id = ( isset( $payload['attempt_id'] ) ? $payload['attempt_id'] : 0 );
		$feedback = ( isset( $payload['feedback'] ) ? $payload['feedback'] : '' );
		// get exising attempt
		$attempt = (array) Query::get_quiz_attempt( $attempt_id );
		$attempt_info = json_decode( $attempt['attempt_info'], true );
		// prepare
		$attempt_info['feedback'] = $feedback;
		$attempt['attempt_info'] = wp_json_encode( $attempt_info );

		do_action( 'quizpress/quiz_attempt_status_' . $attempt['attempt_status'], $attempt );
		// update attempt
		$update = Query::quiz_attempt_insert( $attempt );
		if ( $update ) {
			wp_send_json_success( __( 'Successfully updated feedback.', 'quizpress' ) );
		}
		wp_send_json_error( __( 'Sorry, Failed to update feedback.', 'quizpress' ) );
	}

	public function get_quiz_attempt_feedback( $payload_data ) {
		$payload = Sanitizer::sanitize_payload([
			'attempt_id' => 'integer',
		], $payload_data );

		$attempt_id = ( isset( $payload['attempt_id'] ) ? $payload['attempt_id'] : 0 );
		// get exising attempt
		$attempt = (array) Query::get_quiz_attempt( $attempt_id );
		$attempt_info = json_decode( $attempt['attempt_info'], true );

		do_action( 'quizpress/get_quiz_attempt_feedback', $attempt_info, $attempt_id );

		wp_send_json_success( $attempt_info );
	}

    public function delete_quiz_attempts($payload_data){
        $payload = Sanitizer::sanitize_payload([
			'quiz_id' => 'integer',
		], $payload_data );


        if(empty($payload['quiz_id'])){
	        wp_send_json_error( __( 'Sorry, Quiz ID is missing', 'quizpress' ) );
        }

        $is_delete = Query::delete_attempts_by_quiz_id($payload['quiz_id']);
        wp_send_json_success($is_delete);
    }

    public function update_quiz_question_order($payload_data){
        $result = Questions::update_questions_order_by_quiz_id(json_decode($payload_data['questions'], true));
        wp_send_json_success($result);
    }
}