<?php

//As this files autoload from composer.
if ( ! defined( 'ABSPATH' ) ) {
	return;
}

/**
 * Pro quiz helper functions.
 *
 * @since 2.5.20
 *
 * @package Masteriyo\Pro
 */

use Masteriyo\Addons\Gradebook\Models\GradeResult;
use Masteriyo\Models\QuizAttempt;
use Masteriyo\Pro\Enums\QuizGradingType;
use Masteriyo\Query\QuizAttemptQuery;
use Masteriyo\Query\QuizQuery;

use function Patchwork\Utils\args;

/**
 * Calculate final grade quiz using attempts.
 *
 * @since 2.5.20
 *
 * @param int|WP_Post|\Masteriyo\Models\Quiz $quiz
 * @param int|WP_user|\Masteriyo\Models\User $user
 * @param string $type Quiz Grading type.
 * @return float
 */
function masteriyo_grade_quiz( $quiz, $user, $type = QuizGradingType::LAST_ATTEMPT ) {
	$final_grade   = 0;
	$quiz_attempts = array();
	$quiz          = masteriyo_get_quiz( $quiz );
	$user          = masteriyo_get_user( $user );

	if ( $quiz && $user && ! is_wp_error( $user ) ) {
		$args = array(
			'quiz'     => $quiz->get_id(),
			'user'     => $user->get_id(),
			'reviewed' => true,
			'limit'    => -1,
			'orderby'  => 'id',
		);

		$args['order'] = QuizGradingType::LAST_ATTEMPT === $type ? 'DESC' : 'ASC';

		$query         = new QuizAttemptQuery( $args );
		$quiz_attempts = $query->get_quiz_attempts();

		if ( QuizGradingType::AVERAGE === $type ) {
			$quiz_attempts = array_filter(
				$quiz_attempts,
				function( $quiz_attempt ) {
					return $quiz_attempt->is_reviewed();
				}
			);
		}
	}

	if ( $quiz_attempts ) {
		$all_earned_marks = array_map(
			function( $quiz_attempt ) {
				return $quiz_attempt->get_earned_marks();
			},
			$quiz_attempts
		);
		arsort( $all_earned_marks, SORT_NUMERIC );

		if ( QuizGradingType::LAST_ATTEMPT === $type || QuizGradingType::FIRST_ATTEMPT === $type ) {
			$final_grade = $quiz_attempts[0]->get_earned_marks();
		} elseif ( QuizGradingType::AVERAGE === $type ) {
			$final_grade = masteriyo_round( array_sum( $all_earned_marks ) / count( $all_earned_marks ), 2 );
		} elseif ( QuizGradingType::HIGHEST === $type ) {
			$final_grade = reset( $all_earned_marks );
		}
	}

	/**
	 * Filters quiz final grade.
	 *
	 * @since 2.5.20
	 *
	 * @param float $final_grade
	 * @param \Masteriyo\Models\Quiz $quiz
	 * @param \Masteriyo\Models\User $user
	 * @param string $type
	 */
	return apply_filters( 'masteriyo_grade_quiz', $final_grade, $quiz, $user, $type );
}

/**
 * Calculate total marks according to quiz grade type.
 *
 * @since 2.5.20
 *
 * @param int|WP_Post|\Masteriyo\Models\Quiz $quiz
 * @param int|WP_user|\Masteriyo\Models\User $user
 * @param string $type Quiz Grading type.
 * @return float
 */
function masteriyo_get_quiz_full_marks( $quiz, $user, $type ) {
	$full_marks = 0;
	$quiz       = masteriyo_get_quiz( $quiz );
	$user       = masteriyo_get_user( $user );

	if ( $quiz && $user && ! is_wp_error( $user ) ) {
		$args = array(
			'quiz'    => $quiz->get_id(),
			'user'    => $user->get_id(),
			'limit'   => -1,
			'orderby' => 'id',
		);

		$query         = new QuizAttemptQuery( $args );
		$quiz_attempts = $query->get_quiz_attempts();

		$full_marks = $quiz->get_full_mark();
		if ( $quiz_attempts && QuizGradingType::AVERAGE === $type ) {
			$full_marks = $quiz->get_full_mark() * count( $quiz_attempts );
		}
	}

	/**
	 * Filters quiz final grade.
	 *
	 * @since 2.5.20
	 *
	 * @param float $final_grade
	 * @param \Masteriyo\Models\Quiz $quiz
	 * @param \Masteriyo\Models\User $user
	 * @param string $type
	 */
	return apply_filters( 'masteriyo_get_quiz_full_marks', $full_marks, $quiz, $user, $type );
}
