<?php
/**
 * Masteriyo manual enrollment setup.
 *
 * @package Masteriyo\Addons\ManualEnrollment
 *
 * @since 2.4.4
 */
namespace Masteriyo\Addons\ManualEnrollment;

use Masteriyo\Enums\UserCourseStatus;

defined( 'ABSPATH' ) || exit;
/**
 * Main Masteriyo Manual Enrollment class.
 *
 * @class Masteriyo\Addons\ManualEnrollment
 */
class ManualEnrollmentAddon {
	/**
	 * The single instance of the class.
	 *
	 * @since 2.6.1
	 *
	 * @var \Masteriyo\Addons\ManualEnrollment\ManualEnrollmentAddon
	 */
	protected static $instance = null;

	/**
	 * Constructor.
	 *
	 * @since 2.6.1
	 *
	 * @return void
	 */
	protected function __construct() {}

	/**
	 * Get class instance.
	 *
	 * @since 2.6.1
	 *
	 * @return \Masteriyo\Addons\ManualEnrollment\ManualEnrollmentAddon Instance.
	 */
	final public static function instance() {
		if ( null === static::$instance ) {
			static::$instance = new static();
		}
		return static::$instance;
	}

	/**
	 * Prevent cloning.
	 *
	 * @since 2.6.1
	 */
	public function __clone() {}

	/**
	 * Prevent unserializing.
	 *
	 * @since 2.6.1
	 */
	public function __wakeup() {}

	/**
	 * Initialize module.
	 *
	 * @since 2.4.4
	 */
	public function init() {
		$this->init_hooks();
	}

	/**
	 * Initialize hooks.
	 *
	 * @since 2.4.4
	 */
	public function init_hooks() {
		add_filter( 'masteriyo_admin_submenus', array( $this, 'add_submenu' ) );

		add_filter( 'masteriyo_rest_response_order_data', array( $this, 'append_manual_enrollment_data_in_response' ), 10, 4 );

		add_action( 'masteriyo_update_order', array( $this, 'save_manual_enrollment_data' ), 10, 3 );

		add_action( 'masteriyo_after_trash_order', array( $this, 'update_user_course_status' ), 10, 3 );
		add_action( 'masteriyo_after_restore_order', array( $this, 'update_user_course_status' ), 10, 3 );

	}

	/**
	 * Add manual enrollment submenu.
	 *
	 * @param array $submenus
	 * @return array
	 */
	public function add_submenu( $submenus ) {
		$submenus['manual-enrollment'] = array(
			'page_title' => __( 'Manual Enrollment', 'learning-management-system' ),
			'menu_title' => __( 'Manual Enrollment', 'learning-management-system' ),
			'capability' => 'edit_orders',
			'position'   => 72,
		);

		return $submenus;
	}

	/**
	 * Append manual enrollment data in course response.
	 *
	 * @since 2.9.3
	 *
	 * @param array $data Order data.
	 * @param \Masteriyo\Models\Order\Order $order Order object.
	 * @param string $context What the value is for. Valid values are view and edit.
	 * @param \Masteriyo\RestApi\Controllers\Version1\OrdersController $controller REST Orders controller object.
	 *
	 * @return array
	 */
	public function append_manual_enrollment_data_in_response( $data, $order, $context, $controller ) {

		if ( ! $order instanceof \Masteriyo\Models\Order\Order ) {

			return $data;
		}

		if ( ! isset( $data['created_via'] ) || 'manual-enrollment' !== $data['created_via'] ) {
			return $data;
		}

		$additional_customers_info = array();
		$customer_ids              = get_post_meta( $order->get_id(), '_additional_customer_ids', true ) ?? array();

		if ( is_array( $customer_ids ) && count( $customer_ids ) ) {
			$additional_customers_info = array_filter(
				array_map(
					function( $customer_id ) {
						$user = masteriyo_get_user( $customer_id );

						if ( is_wp_error( $user ) ) {
							return null;
						}

						return array(
							'id'           => $user->get_id(),
							'display_name' => $user->get_display_name(),
							'avatar_url'   => $user->get_avatar_url(),
							'email'        => $user->get_email(),
						);
					},
					$customer_ids
				)
			);
		}

		$data['additional_customer_ids'] = $customer_ids;
		$data['customers']               = $additional_customers_info;

		return $data;
	}

	/**
	 * Save manual enrollment data.
	 *
	 * @since 2.9.3
	 *
	 * @param integer $id The order ID.
	 * @param \Masteriyo\Models\Order\Order $object The order object.
	 * @param \Masteriyo\Repository\OrderRepository $order_repository The order repository.
	 */
	public function save_manual_enrollment_data( $id, $order, $order_repository ) {
		if ( ! $order instanceof \Masteriyo\Models\Order\Order || ! $order_repository instanceof \Masteriyo\Repository\OrderRepository ) {
			return;
		}

		$request = masteriyo_current_http_request();

		if ( ! $request || 'manual-enrollment' !== $order->get_created_via() || ! isset( $request['additional_customer_ids'] ) ) {
			return;
		}

		$order_item = current( $order->get_items() );

		if ( ! $order_item instanceof \Masteriyo\Models\Order\OrderItemCourse ) {
			return;
		}

		$course_id = $order_item->get_course_id();
		$user_id   = $order->get_user_id();

		$user_course = masteriyo_get_user_course_by_user_and_course( $user_id, $course_id );
		if ( $user_course instanceof \Masteriyo\Models\UserCourse && UserCourseStatus::ACTIVE === $user_course->get_status() ) {
			/**
			 * Fires when a user is enrolled manually.
			 *
			 * @since 2.21.0
			 *
			 * @param \Masteriyo\Models\UserCourse $user_course
			 */
			do_action( 'masteriyo_user_enrolled_manually', $user_course );
		}

		$additional_customer_ids = array_map( 'absint', $request['additional_customer_ids'] );

		update_post_meta( $id, '_additional_customer_ids', $additional_customer_ids );

		if ( ! is_array( $additional_customer_ids ) || ! count( $additional_customer_ids ) ) {
			return;
		}

		foreach ( $additional_customer_ids as $customer_id ) {
			$order_repository->create_or_update_user_course( $order, $customer_id );

			$user_course = masteriyo_get_user_course_by_user_and_course( $customer_id, $course_id );

			if ( $user_course instanceof \Masteriyo\Models\UserCourse && UserCourseStatus::ACTIVE === $user_course->get_status() ) {
				/**
				 * Fires when a user is enrolled manually.
				 *
				 * @since 2.21.0
				 *
				 * @param \Masteriyo\Models\UserCourse $user_course
				 */
				do_action( 'masteriyo_user_enrolled_manually', $user_course );
			}
		}
	}

	/**
	 * Update the user course status.
	 *
	 * @since 2.9.3
	 *
	 * @param integer $id The order ID.
	 * @param \Masteriyo\Models\Order\Order $object The order object.
	 * @param \Masteriyo\Repository\OrderRepository $order_repository The order repository.
	 */
	public function update_user_course_status( $id, $order, $order_repository ) {
		if ( ! $order instanceof \Masteriyo\Models\Order\Order || ! $order_repository instanceof \Masteriyo\Repository\OrderRepository ) {
			return;
		}

		if ( 'manual-enrollment' !== $order->get_created_via() ) {
			return;
		}

		$additional_customer_ids = get_post_meta( $id, '_additional_customer_ids', true );

		if ( ! is_array( $additional_customer_ids ) || ! count( $additional_customer_ids ) ) {
			return;
		}

		foreach ( $additional_customer_ids as $customer_id ) {
			$order_repository->update_user_course_status( $order, $customer_id );
		}
	}
}
