<?php
namespace AcademyProNotifications\Classes;

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

use AcademyProNotifications\Helper;

class Pusher extends PushNotifications {
	public static function init() {
		$require_extension = array( 'curl', 'gmp', 'mbstring', 'openssl' );
		foreach ( $require_extension as $ext ) {
			if ( ! extension_loaded( $ext ) ) {
				return;
			}
		}

		$self = new self();
		parent::init();

		add_action( 'academy/admin/update_instructor_status', array( $self, 'instructor_approval_or_remove_push' ), 10, 2 );
		add_action( 'academy/course/after_enroll', array( $self, 'after_enroll_new_course_push' ), 10, 3 );
		add_action( 'academy_pro_enrollment/course/after_cancel_enroll', array( $self, 'after_cancel_enroll_push' ), 10, 3 );
		add_action( 'rest_after_insert_academy_announcement', array( $self, 'after_academy_announcement_push' ) );
		add_action( 'academy/shortcode/after_instructor_registration', array( $self, 'after_instructor_registration_push' ) );
		add_action( 'academy/admin/after_register_instructor', array( $self, 'after_instructor_registration_push' ) );
		add_action( 'academy/admin/after_register_student', array( $self, 'after_student_registration_push' ) );
		add_action( 'academy/shortcode/before_student_registration', array( $self, 'after_student_registration_push' ) );
		add_action( 'transition_post_status', array( $self, 'after_academy_course_publish_push' ), 10, 3 );
		add_action( 'academy/admin/course_complete_after', array( $self, 'after_course_complete_push' ), 10, 2 );
		add_action( 'academy/templates/review_after_comment_text', array( $self, 'after_new_course_review_push' ), 10, 2 );
		add_action( 'academy_quizzes/after_quiz_insert', array( $self, 'after_quiz_submit_push' ) );
		add_action( 'academy_quizzes/after_quiz_attempt_manual_review', array( $self, 'after_quiz_attempt_manual_review_push' ) );
		add_action( 'academy_pro/frontend/submitted_assignment', array( $self, 'after_assignment_submit_push' ) );
		add_action( 'academy_pro/frontend/after_evaluate_assignment', array( $self, 'after_assignment_evaluate_push' ) );
		add_action( 'academy/multi_instructor/withdraw_request_approved', array( $self, 'after_withdraw_request_updated_push' ) );
		add_action( 'academy/multi_instructor/withdraw_request_rejected', array( $self, 'after_withdraw_request_updated_push' ) );
		add_action( 'academy/frontend/insert_course_qa', array( $self, 'course_question_answer_submit_push' ) );
		add_action( 'academy/frontend/insert_course_qa_answered', array( $self, 'course_question_answer_reply_push' ) );
	}

	public function instructor_approval_or_remove_push( $ID, $status ) : void {
		if ( ! $this->is_subscriber( $ID ) ) {
			return;
		}
		if ( 'approved' === $status && $this->is_enable_setting( 'instructor_approval' ) ) {
			$this->instructor_approval_push( $ID, $status );
		} elseif ( 'remove' === $status && $this->is_enable_setting( 'instructor_removal' ) ) {
			$this->instructor_removal_push( $ID, $status );
		}
	}

	public function instructor_approval_push( $ID, $status ) : void {
		if ( 'approved' !== $status ) {
			return;
		}

		$name = \Academy\Helper::get_instructor( $ID )->display_name;

		$url = site_url();
		/* translators: %s is a username. */
		$body = sprintf( __( 'Congratulations, %s! You are become an instructor now.', 'academy-pro' ), $name );
		$title = __( 'Instructor Approval', 'academy-pro' );

		$this->send_notification_to_users( $title, $body, $url, array( $ID ) );
	}

	public function instructor_removal_push( $ID, $status ) : void {
		if ( 'remove' !== $status ) {
			return;
		}

		$name = \Academy\Helper::get_instructor( $ID )->display_name;

		$url = site_url();
		/* translators: %s is a username. */
		$body = sprintf( __( 'Alas, %s! You are removed from instructor.', 'academy-pro' ), $name );
		$title = __( 'Instructor Removal', 'academy-pro' );

		$this->send_notification_to_users( $title, $body, $url, array( $ID ) );
	}

	public function after_enroll_new_course_push( $course_id, $enroll_id, $user_id ) : void {

		if ( ! Helper::is_enrollment_completed( $course_id, $user_id ) ||
			Helper::is_duplicate( $course_id, $user_id ) ||
			! $this->is_subscriber( $user_id ) ||
			! $this->is_enable_setting( 'course_enrollment' )
		) {
			return;
		}

		$url          = get_permalink( $course_id );
		$title        = __( 'Successfully Enrolled', 'academy-pro' );
		$name         = get_userdata( $user_id )->display_name;
		$course_title = get_the_title( $course_id );
		/* translators: %s is a username. */
		$body         = sprintf( __( 'Hey, %1$s! You have successfully enrolled the course `%2$s`', 'academy-pro' ), $name, $course_title );

		$this->send_notification_to_users( $title, $body, $url, $user_id );
	}

	public function after_cancel_enroll_push( $course_id, $enroll_id, $user_id ) : void {
		if ( \Academy\Helper::is_enrolled( $course_id, $user_id ) || ! ( $this->is_subscriber( $user_id ) ) || ! ( $this->is_enable_setting( 'cancel_enrollment' ) ) ) {
			return;
		}

		$url          = get_permalink( $course_id );
		$title        = __( 'Cancel Enrollment', 'academy-pro' );
		$name         = get_userdata( $user_id )->display_name;
		$course_title = get_the_title( $course_id );
		/* translators: %s is a username. */
		$body         = sprintf( __( 'Alas, %1$s! Your enrollment has been removed from the course `%2$s`', 'academy-pro' ), $name, $course_title );

		$this->send_notification_to_users( $title, $body, $url, $user_id );
	}

	public function after_academy_announcement_push( $announcement ) : void {
		if ( ! $this->is_enable_setting( 'announcement_publish' ) ) {
			return;
		}
		$announcement_course = get_post_meta( $announcement->ID, 'academy_announcements_course_ids', true );
		if ( $announcement_course ) {
			$announcement_course = current( maybe_unserialize( $announcement_course ) );
		} else {
			return;
		}

		$course_id = $announcement_course['value'];

		$student_ids = Helper::get_students_ids_by_course_id( $course_id );

		$final_students = [];

		foreach ( $student_ids as $student_id ) {
			if ( $this->is_subscriber( $student_id->post_author ) ) {
				$final_students[] = $student_id->post_author;
			}
		}

		if ( empty( $final_students ) ) {
			return;
		}

		$title = __( 'Announcement Publish', 'academy-pro' );
		$url = esc_url( \Academy\Helper::get_start_course_permalink( $course_id ) );
		/* translators: %s is a coursename. */
		$body = sprintf( __( 'New announcement publish for the course `%s`', 'academy-pro' ), $announcement_course['label'] );

		$this->send_notification_to_users( $title, $body, $url, $final_students );
	}

	public function after_instructor_registration_push( $user_id ) {
		if ( ! $this->is_enable_setting( 'instructor_registration' ) ) {
			return;
		}

		$admin_data = get_users(
			array( 'role' => 'administrator' )
		);

		$admins = [];

		foreach ( $admin_data as $admin ) {
			if ( $this->is_subscriber( $admin->ID ) ) {
				$admins = $admin->ID;
			}
		}

		if ( empty( $admins ) ) {
			return;
		}

		$user_data = get_userdata( $user_id );
		$title = __( 'Instructor Approval Request', 'academy-pro' );
		$url   = admin_url( 'admin.php?page=academy-instructors' );
		/* translators: %s is a username. */
		$body  = sprintf( __( 'New Instructor Registration Approval Request by %s .', 'academy-pro' ), $user_data->display_name );
		$this->send_notification_to_users( $title, $body, $url, $admins );
	}

	public function after_student_registration_push( $user_id ) {
		if ( ! $this->is_enable_setting( 'student_registration' ) ) {
			return;
		}
		$admins = [];
		$admin_data = get_users(
			[
				'role' => 'administrator'
			]
		);
		foreach ( $admin_data as $admin ) {
			if ( $this->is_subscriber( $admin->ID ) ) {
				$admins = $admin->ID;
			}
		}
		if ( empty( $admins ) ) {
			return;
		}
		$user_data = get_userdata( $user_id );
		$title = __( 'Student Registration', 'academy-pro' );
		$url = esc_url( \Academy\Helper::get_frontend_dashboard_endpoint_url( 'profile' ) );
		/* translators: %s is a username. */
		$body = sprintf( __( 'New Student %s Registration Successfully', 'academy-pro' ), $user_data->display_name );
		$this->send_notification_to_users( $title, $body, $url, $admins );
	}

	public function after_academy_course_publish_push( $new_status, $old_status, $post ) {
		if ( ! $this->is_enable_setting( 'course_publish' ) ) {
			return;
		}

		if ( 'academy_courses' === $post->post_type && 'publish' === $new_status && 'publish' !== $old_status ) {
			$student_data = get_users(array(
				'role' => 'academy_student',
			));

			if ( empty( $student_data ) ) {
				return;
			}
			$students = [];
			foreach ( $student_data as $student ) {
				$students = $student->ID;
			}

			$title = __( 'New Course Publish', 'academy-pro' );
			$url = get_the_permalink( $post->ID );
			/* translators: %s is a coursename. */
			$body = sprintf( __( 'You will glad to know that A New Course %1$s Published', 'academy-pro' ), $post->post_title );
			$this->send_notification_to_users( $title, $body, $url, $students );
		}
	}

	public function after_course_complete_push( $course_id, array $user_ids ) {
		if ( ! $this->is_enable_setting( 'course_complete' ) ) {
			return;
		}
		$instructors = (array) Helper::get_instructors( $course_id );
		if ( empty( $instructors ) ) {
			return;
		}

		$user_ids = array_merge(
			$user_ids,
			$instructors
		);

		$title = __( 'Course Completed', 'academy-pro' );
		$url = get_permalink( $course_id );
		/* translators: %s is a coursename. */
		$body = sprintf( __( 'Hey, You have Complete a new course %1&s', 'academy-pro' ), get_the_title( $course_id ) );
		$this->send_notification_to_users( $title, $body, $url, $user_ids );
	}

	public function after_new_course_review_push( $data ) {
		if ( ! $this->is_enable_setting( 'course_review' ) ) {
			return;
		}

		$instructors = Helper::get_instructors( $data->comment_post_ID );
		$title = __( 'Course Review', 'academy-pro' );
		$url = get_permalink( $data->comment_post_ID );
		/* translators: %s is a coursename. */
		$body = sprintf( __( 'You have found %1$s star rating of this course %2$s', 'academy-pro' ), get_comment_meta( $data->comment_ID, 'academy_rating', true ), get_the_title( $data->comment_post_ID ) );
		$this->send_notification_to_users( $title, $body, $url, $instructors );
	}

	public function after_quiz_submit_push( $quiz_data ) {
		if ( ! $this->is_enable_setting( 'quiz_submit' ) ) {
			return;
		}

		$instructors = Helper::get_instructors( $quiz_data->course_id );
		$title = __( 'Quiz Submit', 'academy-pro' );
		$url   = get_permalink( $quiz_data->course_id );
		/* translators: %s is a coursename. */
		$body  = sprintf( __( 'Your Student Submitted A new quiz of %s.', 'academy-pro' ), get_the_title( $quiz_data->course_id ) );
		$this->send_notification_to_users( $title, $body, $url, $instructors );
	}

	public function after_quiz_attempt_manual_review_push( $attempt ) {
		if ( ! $this->is_enable_setting( 'quiz_evaluate' ) ) {
			return;
		}

		$url          = get_permalink( $attempt['course_id'] );
		$title        = __( 'Quiz Evaluated', 'academy-pro' );
		$name         = get_userdata( $attempt['user_id'] )->display_name;
		/* translators: %s is a username. */
		$body         = sprintf( __( 'Hey, %1$s! A new quiz has been evaluated.', 'academy-pro' ), $name );

		$this->send_notification_to_users( $title, $body, $url, $attempt['user_id'] );
	}

	public function after_assignment_submit_push( $assignment_data ) {
		if ( ! $this->is_enable_setting( 'assignment_submit' ) ) {
			return;
		}

		$instructors = Helper::get_instructors( $assignment_data->comment_parent );
		$title = __( 'Quiz Submit', 'academy-pro' );
		$url   = get_permalink( $assignment_data->comment_parent );
		/* translators: %s is a coursename. */
		$body  = sprintf( __( 'Your Student Submitted A new assignment of %s.', 'academy-pro' ), get_the_title( $assignment_data->comment_parent ) );
		$this->send_notification_to_users( $title, $body, $url, $instructors );
	}

	public function after_assignment_evaluate_push( $assignment_data ) {
		if ( ! $this->is_enable_setting( 'assignment_evaluate' ) ) {
			return;
		}

		$url          = get_permalink( $assignment_data->course_id );
		$title        = __( 'Quiz Evaluated', 'academy-pro' );
		$name         = get_userdata( $assignment_data->user_id )->display_name;
		/* translators: %s is a username. */
		$body         = sprintf( __( 'Hey, %1$s! A new assignment has been evaluated.', 'academy-pro' ), $name );

		$this->send_notification_to_users( $title, $body, $url, $assignment_data->user_id );
	}

	public function after_withdraw_request_updated_push( $result ) : void {
		$is_approved = ( 'approved' === $result->status && $this->is_enable_setting( 'withdraw_request_approved' ) );
		$is_rejected = ( 'rejected' === $result->status && $this->is_enable_setting( 'withdraw_request_rejected' ) );
		if ( ! $is_approved || ! $is_rejected ) {
			return;
		}

		$name = $result->user_login;
		$url = \Academy\Helper::get_frontend_dashboard_endpoint_url( 'withdrawal' );
		$name = $result->display_name;
		// translators: %s is student name,  %s is student name
		$body = $is_approved ? sprintf( __( 'Congratulations, %s! Your submitted withdraw request is Approved.', 'academy-pro' ), $name ) : sprintf( __( 'Alas, %s! Your submitted withdraw request is Rejected.', 'academy-pro' ), $name );
		$title = $is_approved ? __( 'Withdraw Request Approved', 'academy-pro' ) : __( 'Withdraw Request Rejected', 'academy-pro' );

		$this->send_notification_to_users( $title, $body, $url, array( $result->user_id ) );
	}

	public function course_question_answer_submit_push( $comment ) {
		if ( ! $this->is_enable_setting( 'question_answer_submit' ) ) {
			return;
		}

		$url          = esc_url( \Academy\Helper::get_frontend_dashboard_endpoint_url( 'question-answer' ) );
		$title        = __( 'Question Answer Submit', 'academy-pro' );
		$instructors  = \Academy\Helper::get_course_instructor( $comment['post'] );
		/* translators: %s is a username., %s is a coursename */
		$body         = sprintf( __( 'Hey, your student %1$s submitted question in a course of %2$s', 'academy-pro' ), $comment['author_name'], get_the_title( $comment['post'] ) );

		$this->send_notification_to_users( $title, $body, $url, $instructors );
	}

	public function course_question_answer_reply_push( $comment ) {
		if ( ! $this->is_enable_setting( 'question_answer_reply' ) ) {
			return;
		}

		$url          = esc_url( \Academy\Helper::get_start_course_permalink( $comment['post'] ) );
		$title        = __( 'Question Answer Reply', 'academy-pro' );
		$name         = get_userdata( get_comment( $comment['parent'] )->comment_author )->display_name;
		/* translators: %s is a username., %s is a coursename */
		$body         = sprintf( __( 'Hey %1$s, your submitted question has replied in a course of %2$s', 'academy-pro' ), $name, get_the_title( $comment['post'] ) );

		$this->send_notification_to_users( $title, $body, $url, $comment['parent'] );
	}
}
