<?php
namespace AcademyProAssignments;

use Academy;

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

class Ajax {
	public static function init() {
		$self = new self();
		add_action( 'wp_ajax_academy_pro_assignments/get_submitted_assignments', array( $self, 'get_submitted_assignments' ) );
		add_action( 'wp_ajax_academy_pro_assignments/evaluate_submitted_assignment', array( $self, 'evaluate_submitted_assignment' ) );
		add_action( 'wp_ajax_academy_pro_assignments/frontend/render_assignment', array( $self, 'render_assignment' ) );
		add_action( 'wp_ajax_academy_pro_assignments/frontend/start_assignment', array( $self, 'start_assignment' ) );
		add_action( 'wp_ajax_academy_pro_assignments/frontend/submit_assignment', array( $self, 'submit_assignment' ) );
		add_action( 'wp_ajax_academy_pro_assignments/delete_submitted_assignment', array( $self, 'delete_submitted_assignment' ) );
		// Mark as complete
		add_action( 'academy/frontend/before_mark_topic_complete', array( $self, 'mark_assignment_complete' ), 11, 4 );
	}
	public function get_submitted_assignments() {
		check_ajax_referer( 'academy_nonce', 'security' );

		if ( ! current_user_can( 'manage_academy_instructor' ) ) {
			wp_die();
		}

		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 
		$user_id = ( isset( $_POST['user_id'] ) ? sanitize_text_field( $_POST['user_id'] ) : 0 );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 
		$page = ( isset( $_POST['page'] ) ? sanitize_text_field( $_POST['page'] ) : 1 );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 
		$per_page = ( isset( $_POST['per_page'] ) && 'null' !== $_POST['per_page'] ? sanitize_text_field( $_POST['per_page'] ) : 10 );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 
		$search = ( isset( $_POST['search'] ) ? sanitize_text_field( $_POST['search'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 
		$status = ( isset( $_POST['status'] ) ? sanitize_text_field( $_POST['status'] ) : 'all' );
		$offset = ( $page - 1 ) * $per_page;
		$course_ids = \Academy\Helper::get_course_ids_by_instructor_id( $user_id );
		$author_in = array();
		if ( is_array( $course_ids ) && count( $course_ids ) ) {
			foreach ( $course_ids as $course_id ) {
				$instructors = \Academy\Helper::get_course_instructor( $course_id );

				foreach ( $instructors as $instructor ) {
					$author_in[] = $instructor->user_id;
				}
			}
		}

		$args = array(
			'comment_type' => 'academy_assignments',
			'status'       => 'any' === $status ? array( 'submitted', 'pass', 'failed' ) : $status,
		);
		if ( ! \Academy\Helper::get_addon_active_status( 'multi_instructor' ) && $user_id ) {
				$args['post_author'] = $user_id;
		} else {
			if ( count( $author_in ) === 1 ) {
				$args['post_author'] = $user_id;
			} else {
				$args['parent__in'] = $course_ids;
				$args['post_author__in'] = $author_in;
			}
		}

		$total_comments = count( get_comments( $args ) );

		// Set the x-wp-total header
		header( 'x-wp-total: ' . $total_comments );

		if ( ! empty( $search ) ) {
			$args['search'] = $search;
		}
		// pagination
		$args['offset'] = $offset;
		$args['number'] = $per_page;

		$submitted_assignments = get_comments( $args );
		$submitted_assignments = Helper::prepare_submitted_assignment_items( $submitted_assignments );
		$submitted_assignments = apply_filters( 'academy_pro_assignments/admin/submitted_assignments', $submitted_assignments );
		wp_send_json_success( $submitted_assignments );
	}
	public function evaluate_submitted_assignment() {
		check_ajax_referer( 'academy_nonce', 'security' );
		if ( ! current_user_can( 'manage_academy_instructor' ) ) {
			wp_die();
		}

		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$comment_id = (int) sanitize_text_field( $_POST['comment_id'] );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized , WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$evaluate_point = (int) sanitize_text_field( $_POST['evaluate_point'] );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$minimum_passing_points = (int) sanitize_text_field( $_POST['minimum_passing_points'] );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$evaluate_feedback = sanitize_textarea_field( $_POST['evaluate_feedback'] );

		update_comment_meta( $comment_id, 'academy_pro_assignment_evaluate_point', $evaluate_point );
		update_comment_meta( $comment_id, 'academy_pro_assignment_evaluate_feedback', $evaluate_feedback );

		// Update Assignment Status
		$comment_approved = $evaluate_point < $minimum_passing_points ? 'failed' : 'pass';

		$args = array(
			'comment_ID'         => $comment_id,
			'comment_approved'   => $comment_approved,
		);

		wp_update_comment( $args );

		$response = get_comment( $comment_id );
		$response = Helper::prepare_submitted_assignment_item( $response );
		do_action( 'academy_pro/frontend/evaluate_submitted_assignment', $response );

		// for gradebook integration
		$total_marks   = get_post_meta( $response->comment_post_ID, 'academy_assignment_settings', true )['total_points'];
		if ( $evaluate_point < 0 ) {
			$evaluate_point = 0;
		} elseif ( $evaluate_point > $total_marks ) {
			$evaluate_point = $total_marks;
		}
		$earned_percentage = ( $evaluate_point / $total_marks ) * 100;
		$passing_percentage = ( $minimum_passing_points / $total_marks ) * 100;
		$percentage = ( $evaluate_point / $total_marks ) * 100;
		$evaluate_info = (object) array(
			'user_id'           => $response->user_id,
			'course_id'         => $response->comment_parent,
			'quiz_id'           => null,
			'assignment_id'     => get_comment( $comment_id )->comment_post_ID,
			'result_for'        => 'assignment',
			'earned_percentage' => $earned_percentage,
		);
		do_action( 'academy_pro/frontend/after_evaluate_assignment', $evaluate_info );

		// hooks for GamiPress integration
		if ( $earned_percentage >= $passing_percentage ) {
			do_action( 'academy_pro_assignment/after_evaluate_status_pass', get_comment( $comment_id )->comment_post_ID, $response->user_id, $response->comment_parent );
		} else {
			do_action( 'academy_pro_assignment/after_evaluate_status_fail', get_comment( $comment_id )->comment_post_ID, $response->user_id, $response->comment_parent );
		}

		$response = apply_filters( 'academy_pro_assignments/admin/before_evaluate_assignment', $response );

		wp_send_json_success( $response );
	}
	public function render_assignment() {
		check_ajax_referer( 'academy_nonce', 'security' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$course_id = (int) sanitize_text_field( $_POST['course_id'] );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$assignment_id = (int) sanitize_text_field( $_POST['assignment_id'] );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$time_zone = sanitize_text_field( $_POST['time_zone'] );
		$user_id   = (int) get_current_user_id();

		$has_permission = \Academy\Helper::has_permission_to_access_curriculum( $course_id, $user_id, $assignment_id, 'assignment' );

		if ( $has_permission ) {
			do_action( 'academy_pro_assignments/frontend/before_render_assignment', $course_id, $assignment_id );
			$assignment = get_post( $assignment_id );
			if ( ! $assignment ) {
				wp_send_json_error( esc_html__( 'Sorry, something went wrong!', 'academy-pro' ) );
			}
			$assignment->post_content_rendered = \Academy\Helper::get_content_html( stripslashes( $assignment->post_content ) );
			$attachment_id = (int) get_post_meta( $assignment_id, 'academy_assignment_attachment', true );
			$assignment->attachment = [
				'ID' => $attachment_id ? $attachment_id : (int) get_post_meta( $assignment_id, '_thumbnail_id', true ),
				'url' => get_the_post_thumbnail_url( $assignment_id ),
			];
			$assignment->settings = get_post_meta( $assignment_id, 'academy_assignment_settings', true );
			$submitted_assignments = get_comments(array(
				'post_id' => $assignment->ID,
				'comment_type' => 'academy_assignments',
				'parent'    => $course_id,
				'user_id'   => $user_id,
				'status' => array( 'submitted', 'submitting', 'pass', 'failed' )
			));
			if ( $submitted_assignments ) {
				$submitted_assignments = Helper::prepare_submitted_assignment_items( $submitted_assignments );
				$assignment->submitted_assignment = current( $submitted_assignments );
				$assignment->resubmit_attempt = get_option( 'academy_pro_assignment_' . $submitted_assignments[0]->comment_ID . '_submission_attempt' );
			}
			$assignment->submission_status = 'active';
			if ( Helper::is_assignment_submission_expired( $assignment, $time_zone ) ) {
				$assignment->submission_status = 'expired';
			}
			$assignment = apply_filters( 'academy_pro_assignments/frontend/evaluate_submitted_assignment', $assignment, $course_id, $user_id, $assignment_id );
			wp_send_json_success( $assignment );
		}//end if
		wp_send_json_error( __( 'Access Denied', 'academy-pro' ) );
	}

	public function start_assignment() {
		check_ajax_referer( 'academy_nonce', 'security' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$course_id              = (int) sanitize_text_field( $_POST['course_id'] );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$assignment_id          = (int) sanitize_text_field( $_POST['assignment_id'] );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$submitting_time        = sanitize_text_field( $_POST['submitting_time'] );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$time_zone              = sanitize_text_field( $_POST['time_zone'] );
		$current_user           = wp_get_current_user();
		$is_administrator       = current_user_can( 'administrator' );
		$is_instructor          = \Academy\Helper::is_instructor_of_this_course( $current_user->ID, $course_id );
		$is_enrolled               = \Academy\Helper::is_enrolled( $course_id, $current_user->ID );
		$is_public_course = \Academy\Helper::is_public_course( $course_id );

		$submitting_assignments = get_comments(array(
			'post_id'           => $assignment_id,
			'parent'    => $course_id,
			'user_id'   => $current_user->ID,
			'comment_type' => 'academy_assignments',
			'status' => array( 'submitted', 'submitting' )
		));

		if ( count( $submitting_assignments ) ) {
			wp_send_json_error( __( 'Already Submitted', 'academy-pro' ) );
		}

		if ( $is_administrator || $is_instructor || $is_enrolled || $is_public_course ) {
			$data = array(
				'comment_post_ID'      => $assignment_id,
				'comment_parent'       => $course_id,
				'user_id'              => $current_user->ID,
				'comment_author'       => $current_user->user_login,
				'comment_author_email' => $current_user->user_email,
				'comment_author_url'   => $current_user->user_url,
				'comment_approved'     => 'submitting',
				'comment_agent'        => 'academy',
				'comment_type'         => 'academy_assignments',
				'comment_meta'         => array(
					'academy_pro_assignment_start_time' => $submitting_time,
				)
			);
			$assignment_answer_id = wp_insert_comment( $data );
			$response = get_comment( $assignment_answer_id );
			$response = Helper::prepare_submitted_assignment_item( $response );
			wp_send_json_success( $response );
		}
		wp_send_json_error( __( 'Access Denied', 'academy-pro' ) );
	}
	public function submit_assignment() {
		check_ajax_referer( 'academy_nonce', 'security' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$course_id              = (int) sanitize_text_field( $_POST['course_id'] );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$assignment_id          = (int) sanitize_text_field( $_POST['assignment_id'] );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$assignment_comment_id  = (int) sanitize_text_field( $_POST['assignment_comment_id'] );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$submitted_time         = sanitize_text_field( $_POST['submitted_time'] );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$time_zone              = sanitize_text_field( $_POST['time_zone'] );
		$current_user           = wp_get_current_user();
		$is_administrator       = current_user_can( 'administrator' );
		$is_instructor          = \Academy\Helper::is_instructor_of_this_course( $current_user->ID, $course_id );
		$is_enrolled               = \Academy\Helper::is_enrolled( $course_id, $current_user->ID );
		$is_public_course = \Academy\Helper::is_public_course( $course_id );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 
		$assignment_answer      = ( isset( $_POST['assignment_answer'] ) ? wp_kses_post( $_POST['assignment_answer'] ) : '' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 
		$assignment_attachment  = ( isset( $_POST['assignment_attachment'] ) ? sanitize_text_field( $_POST['assignment_attachment'] ) : '' );

		$started_assignment = get_comment( $assignment_comment_id );

		if ( ! $started_assignment ) {
			wp_send_json_error( __( 'Assignment Haven\'t started yet.', 'academy-pro' ) );
		}

		if ( $is_administrator || $is_instructor || $is_enrolled || $is_public_course ) {
			// first check submission is expired or not
			$assignment = get_post( $assignment_id );
			$assignment->settings = get_post_meta( $assignment_id, 'academy_assignment_settings', true );
			$enable_resubmit  = get_post_meta( $assignment_id, 'academy_assignment_enable_resubmit', true );
			$submitted_assignments = get_comments(array(
				'post_id' => $assignment->ID,
				'comment_type' => 'academy_assignments',
				'status' => array( 'submitted', 'submitting' )
			));
			$submitted_assignments = Helper::prepare_submitted_assignment_items( $submitted_assignments );
			$assignment->submitted_assignment = current( $submitted_assignments );

			if ( Helper::is_assignment_submission_expired( $assignment, $time_zone ) ) {
				wp_send_json_error( __( 'Expired Your Submission. Contact with instructor', 'academy-pro' ) );
			}

			// Update comment
			$data = array(
				'comment_ID'           => $assignment_comment_id,
				'comment_post_ID'      => $assignment_id,
				'comment_content'      => $assignment_answer,
				'comment_date_gmt'     => $started_assignment->comment_date_gmt,
				'comment_approved'     => 'submitted',
				'comment_meta'         => array(
					'academy_pro_assignment_end_time' => $submitted_time,
					'academy_pro_assignment_attachment' => $assignment_attachment,
				)
			);
			wp_update_comment( $data );
			$response = get_comment( $assignment_comment_id );
			$response = Helper::prepare_submitted_assignment_item( $response );
			$resubmit_limit = (int) get_post_meta( $assignment_id, 'academy_assignment_resubmit_limit', true ) ?? 0;
			if ( $enable_resubmit && $resubmit_limit > 0 ) {
				$option_key = 'academy_pro_assignment_' . $assignment_comment_id . '_submission_attempt';
				$assignment_attempt = get_option( $option_key, 0 );
				if ( $assignment_attempt >= $resubmit_limit ) {
					wp_send_json_error( __( 'You have reached the maximum number of submission attempts.', 'academy-pro' ) );
				}
				$assignment_attempt++;
				update_option( $option_key, $assignment_attempt );
			}
			do_action( 'academy_pro/frontend/submitted_assignment', $response );
			do_action( 'academy_pro_assignment/after_submit_assignment', $assignment_id, get_current_user_id(), $course_id );
			wp_send_json_success( $response );
		}//end if
		wp_send_json_error( __( 'Access Denied', 'academy-pro' ) );
	}

	public function delete_submitted_assignment() {
		check_ajax_referer( 'academy_nonce', 'security' );
		if ( ! current_user_can( 'manage_academy_instructor' ) ) {
			wp_die();
		}

		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
		$comment_ID = (int) sanitize_text_field( $_POST['comment_ID'] );
		$is_delete = wp_delete_comment( $comment_ID, true );
		if ( $is_delete ) {
			wp_send_json_success( array(
				'id' => $comment_ID
			) );
		}

		wp_send_json_error( __( 'Sorry, Failed to delete submission.', 'academy-pro' ) );
	}

	public function mark_assignment_complete( $topic_type, $course_id, $topic_id, $user_id ) {
		if ( 'assignment' === $topic_type ) {
			$assignment = \AcademyProAssignments\Helper::has_submitted_assignment( $topic_id, $user_id );

			if ( ! $assignment || 'pass' !== current( $assignment )->comment_approved ) {
				if ( \Academy\Helper::get_settings( 'is_enabled_lessons_php_render' ) ) {
					wp_safe_redirect( \Academy\Helper::sanitize_referer_url( wp_get_referer() ) );
					exit;
				}

				$message = $assignment ? __( 'Pass the assignment before marking it as done.', 'academy-pro' ) : __( 'Complete the assignment before marking it as done.', 'academy-pro' );
				wp_send_json_error( $message );
			}
		}
	}
}
