<?php
/**
 * Masteriyo course preview setup.
 *
 * @package Masteriyo\Addons\CoursePreview
 *
 * @since 2.6.7
 */
namespace Masteriyo\Addons\CoursePreview;

use Masteriyo\Constants;
use Masteriyo\Models\Lesson;
use Masteriyo\PostType\PostType;

defined( 'ABSPATH' ) || exit;
/**
 * Main Masteriyo Course Preview class.
 *
 * @class Masteriyo\Addons\CoursePreview
 */
class CoursePreviewAddon {

	/**
	 * Instance
	 *
	 * @since 2.6.7
	 *
	 * @var \Masteriyo\Addons\CoursePreview\CoursePreviewAddon
	 */
	protected static $instance = null;

	/**
	 * Constructor.
	 *
	 * @since 2.6.7
	 */
	private function __construct() {
	}

	/**
	 * Return the instance.
	 *
	 * @since 2.6.7
	 *
	 * @return \Masteriyo\Addons\CoursePreview\CoursePreviewAddon
	 */
	public static function instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}

		return self::$instance;
	}
	/**
	 * Initialize module.
	 *
	 * @since 2.6.7
	 */
	public function init() {
		$this->init_hooks();
	}

	/**
	 * Initialize hooks.
	 *
	 * @since 2.6.7
	 */
	public function init_hooks() {
		add_filter( 'masteriyo_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
		add_action( 'masteriyo_new_lesson', array( $this, 'save_course_preview_lesson_settings' ), 10, 2 );
		add_action( 'masteriyo_update_lesson', array( $this, 'save_course_preview_lesson_settings' ), 10, 2 );

		add_filter( 'masteriyo_rest_response_lesson_data', array( $this, 'append_course_preview_lesson_data' ), 10, 4 );
		add_filter( 'masteriyo_rest_lesson_schema', array( $this, 'add_course_preview_lesson_schema_to_lesson' ) );

		add_filter( 'masteriyo_single_course_curriculum_section_content_html', array( $this, 'add_course_preview_link' ), 10, 2 );
		add_action( 'masteriyo_single_course_main_content', array( $this, 'render_course_preview_video_player_playlist_modal' ), 100 );
		add_action( 'masteriyo_after_layout_1_single_course_main_content', array( $this, 'render_course_preview_video_player_playlist_modal' ), 100 );

		add_filter( 'masteriyo_rest_response_lesson_data', array( $this, 'modify_course_item_response' ), 10, 1 );
		add_filter( 'masteriyo_rest_response_quiz_data', array( $this, 'modify_course_item_response' ), 10, 1 );
		add_filter( 'masteriyo_rest_response_assignment_data', array( $this, 'modify_course_item_response' ), 10, 1 );
		add_filter( 'masteriyo_rest_response_zoom_data', array( $this, 'modify_course_item_response' ), 10, 1 );
		add_filter( 'masteriyo_rest_response_google-meet_data', array( $this, 'modify_course_item_response' ), 10, 1 );

		add_action( 'masteriyo_after_layout_1_single_course_curriculum_accordion_body_item_title', array( $this, 'add_course_preview_link_layout_1' ), 10, 2 );

		add_filter( 'masteriyo_course_progress_item_data', array( $this, 'add_locked_status_to_course_progress_item' ), 999, 3 );
	}

	/**
	 * Add locked status to course progress item like (lesson, quiz, assignment and zoom meeting).
	 *
	 * @since 2.11.0
	 *
	 * @param array $data The course progress item data.
	 * @param \Masteriyo\Models\CourseProgressItem $course_progress_item Course progress item object.
	 * @param string $context Context.
	 *
	 * @return array The updated course progress item data.
	 */
	public function add_locked_status_to_course_progress_item( $data, $course_progress_item, $context ) {
		if ( isset( $data['locked'] ) && masteriyo_string_to_bool( $data['locked'] ) ) {
			return $data;
		}

		$course_id = $course_progress_item->get_course_id();

		if ( $course_id && ! masteriyo_can_start_course( $course_id ) ) {
			$data['locked'] = true;

			if ( 'lesson' === $data['item_type'] ) {
				$lesson                 = masteriyo_get_lesson( $data['item_id'] );
				$lesson_preview_enabled = masteriyo_course_preview_is_lesson_preview_enabled( $lesson );

				if ( $lesson_preview_enabled ) {
					$data['locked'] = false;
				}
			}
		}

		return $data;
	}

	/**
	 * Adds a course preview link layout 1 to the lesson object.
	 *
	 * This function is used to add a course preview link to the lesson object, if the lesson preview is enabled or the lesson video preview is enabled.
	 *
	 * @since 2.10.0
	 *
	 * @param object $object The lesson object.
	 * @param object $course The course object.
	 *
	 * @return void
	 */
	public function add_course_preview_link_layout_1( $object, $course ) {
		if ( ! $object instanceof Lesson ) {
			return;
		}

		$lesson_preview_enabled = masteriyo_course_preview_is_lesson_preview_enabled( $object );

		if ( ! masteriyo_course_preview_is_lesson_video_preview_enabled( $object ) && ! $lesson_preview_enabled ) {
			return;
		}

		$course = masteriyo_get_course( $object->get_course_id() );

		if ( is_null( $course ) ) {
			return;
		}

		$categories        = $course->get_categories();
		$categories_string = '';

		if ( ! empty( $categories ) ) {
			foreach ( $categories as $category ) {
				$categories_string .= ', ' . $category->get_name();
			}
		}

		$categories_string = ltrim( $categories_string, ', ' );

		$learn_url = '';

		if ( $lesson_preview_enabled ) {
			$learn_url = $course->start_course_url( false ) . "/lesson/{$object->get_id()}";
		}

		include Constants::get( 'MASTERIYO_COURSE_PREVIEW_ADDON_TEMPLATES' ) . '/preview-link.php';
	}

	/**
	 * Modify course item response.
	 *
	 * @since 2.7.1
	 *
	 * @param array $data The lesson data.
	 *
	 * @return array The modified data.
	 */
	public function modify_course_item_response( $data ) {
		$course_id = $data['course_id'] ?? 0;

		if ( current_user_can( 'manage_masteriyo_settings' ) || current_user_can( 'edit_course', $course_id ) ) {
			return $data;
		}

		if ( ! masteriyo_can_start_course( $course_id ) ) {

			$post_type = get_post_type( $data['id'] );

			if ( PostType::LESSON !== $post_type || ! masteriyo_course_preview_is_lesson_preview_enabled( $data['id'] ) ) {
				return array_merge( masteriyo_array_only( $data, array( 'id', 'name', 'slug', 'permalink', 'course_id', 'parent_id', 'navigation' ) ), array( 'locked' => true ) );
			}

			$allowed_item_ids = masteriyo_get_previewable_lesson_ids_for_course( $course_id );

			if ( is_array( $allowed_item_ids ) ) {

				// Find the index of the current element
				$current_index = array_search( $data['id'], $allowed_item_ids, true );

				// Calculate the previous and next elements
				$previous = ( $current_index > 0 ) ? $allowed_item_ids[ $current_index - 1 ] : null;
				$next     = ( $current_index < count( $allowed_item_ids ) - 1 ) ? $allowed_item_ids[ $current_index + 1 ] : null;

				$data['navigation']['previous'] = null !== $previous ? $this->get_navigation_item( masteriyo_get_lesson( $previous ) ) : '';
				$data['navigation']['next']     = null !== $next ? $this->get_navigation_item( masteriyo_get_lesson( $next ) ) : '';
			}
		}

		return $data;
	}

	/**
	 * Get navigation item.
	 *
	 * @since 2.11.0
	 *
	 * @param \Masteriyo\Database\Model $object Model object.
	 * @param string $context Request context.
	 *                        Options: 'view' and 'edit'.
	 *
	 * @return array
	 */
	protected function get_navigation_item( $object, $context = 'view' ) {
		if ( empty( $object ) ) {
			return '';
		}
		$previous_parent = get_post( $object->get_parent_id() );
		$video           = get_post_meta( $object->get_id(), '_video_source_url', true );

		$previous = array(
			'id'     => $object->get_id(),
			'name'   => wp_specialchars_decode( $object->get_name() ),
			'type'   => $object->get_object_type(),
			'video'  => ! empty( trim( $video ) ),
			'parent' => is_null( $previous_parent ) ? null : array(
				'id'   => $previous_parent->ID,
				'name' => $previous_parent->post_title,
			),
		);

		return $previous;
	}

	/**
	 * Enqueue scripts.
	 *
	 * @since 2.6.7
	 *
	 * @param array $scripts Array of scripts.
	 * @return array
	 */
	public function enqueue_scripts( $scripts ) {
		$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';

		return masteriyo_parse_args(
			$scripts,
			array(
				'course-preview-video-playlist-popup-modal'        => array(
					'src'      => plugin_dir_url( Constants::get( 'MASTERIYO_COURSE_PREVIEW_ADDON_FILE' ) ) . '/assets/js/course-preview' . $suffix . '.js',
					'context'  => 'public',
					'callback' => 'masteriyo_is_single_course_page',
				),
			)
		);
	}

	/**
	 * Save course preview lesson settings.
	 *
	 * @since 2.6.7
	 *
	 * @param \Masteriyo\Models\Setting $setting Setting object.
	 */
	public function save_course_preview_lesson_settings( $id, $object ) {
		if ( ! masteriyo_is_rest_api_request() ) {
			return;
		}

		$request = masteriyo_current_http_request();

		if ( null === $request ) {
			return;
		}

		if ( ! isset( $request['course_preview'] ) ) {
			return;
		}

		if ( ! isset( $request['course_preview']['lesson'] ) ) {
			return;
		}

		if ( isset( $request['course_preview']['lesson']['video_preview_enabled'] ) ) {
			$object->update_meta_data( '_enable_video_preview', masteriyo_string_to_bool( $request['course_preview']['lesson']['video_preview_enabled'] ) );
		}

		if ( isset( $request['course_preview']['lesson']['lesson_preview_enabled'] ) ) {
			$object->update_meta_data( '_enable_preview', masteriyo_string_to_bool( $request['course_preview']['lesson']['lesson_preview_enabled'] ) );
		}

		$object->save_meta_data();
	}

	/**
	 * Append course preview lesson data to course response.
	 *
	 * @since 2.6.7
	 *
	 * @param array $data Lesson data.
	 * @param \Masteriyo\Models\Lesson $object Lesson object.
	 * @param string $context What the value is for. Valid values are view and edit.
	 * @param \Masteriyo\RestApi\Controllers\Version1\LessonsController $controller REST Lesson Controller object.
	 *
	 * @return \WP_REST_Response
	 */
	public function append_course_preview_lesson_data( $data, $object, $context, $controller ) {
		$video_preview_enabled  = $object->get_meta( '_enable_video_preview' ) ? masteriyo_string_to_bool( $object->get_meta( '_enable_video_preview' ) ) : false;
		$lesson_preview_enabled = $object->get_meta( '_enable_preview' ) ? masteriyo_string_to_bool( $object->get_meta( '_enable_preview' ) ) : false;

		$data['course_preview'] = array(
			'lesson' => array(
				'video_preview_enabled'  => $video_preview_enabled,
				'lesson_preview_enabled' => $lesson_preview_enabled,
				'can_user_start_course'  => masteriyo_can_start_course( $object->get_course_id() ),
			),
		);

		return $data;
	}

	/**
	 * Add course preview fields to lesson schema.
	 *
	 * @since 2.6.7
	 *
	 * @param array $schema
	 *
	 * @return array
	 */
	public function add_course_preview_lesson_schema_to_lesson( $schema ) {
		$schema = masteriyo_parse_args(
			$schema,
			array(
				'content_drip' => array(
					'description' => __( 'Course Preview setting', 'learning-management-system' ),
					'type'        => 'object',
					'context'     => array( 'view', 'edit' ),
					'items'       => array(
						'type'       => 'object',
						'properties' => array(
							'video_preview_enabled'  => array(
								'description' => __( 'course preview enable preview for video of the lesson.', 'learning-management-system' ),
								'type'        => 'boolean',
								'default'     => false,
								'context'     => array( 'view', 'edit' ),
							),
							'lesson_preview_enabled' => array(
								'description' => __( 'Enable this option to allow students to preview lesson, before accessing the full course.', 'learning-management-system' ),
								'type'        => 'boolean',
								'default'     => false,
								'context'     => array( 'view', 'edit' ),
							),
							'can_user_start_course'  => array(
								'description' => __( 'This checks either the user can start course or not.', 'learning-management-system' ),
								'type'        => 'boolean',
								'default'     => false,
								'context'     => array( 'view', 'edit' ),
							),
						),
					),
				),
			)
		);

		return $schema;
	}

	/**
	 * Renders the preview link.
	 *
	 * This function includes the template file "preview-link.php" to display the preview link.
	 *
	 * @since 2.6.7
	 *
	 * @param array $data Profile data.
	 */
	public function add_course_preview_link( $html, $object ) {
		if ( is_null( $object ) || is_wp_error( $object ) ) {
			$html;
		}

		if ( ! $object instanceof Lesson ) {
			return $html;
		}

		$lesson_preview_enabled = masteriyo_course_preview_is_lesson_preview_enabled( $object );

		$course = masteriyo_get_course( $object->get_course_id() );

		if ( is_null( $course ) ) {
			return $html;
		}

		$categories        = $course->get_categories();
		$categories_string = '';

		if ( ! empty( $categories ) ) {
			foreach ( $categories as $category ) {
				$categories_string .= ', ' . $category->get_name();
			}
		}

		$categories_string = ltrim( $categories_string, ', ' );

		$learn_url = '';

		if ( $lesson_preview_enabled ) {
			$learn_url = $course->start_course_url( false ) . "/lesson/{$object->get_id()}";
		}

		ob_start();
		include Constants::get( 'MASTERIYO_COURSE_PREVIEW_ADDON_TEMPLATES' ) . '/preview-link.php';
		$preview_html = ob_get_clean();

		$name_html = $object->get_name() . $preview_html;
		$html      = str_replace( $object->get_name(), $name_html, $html );

		return $html;
	}

	/**
	 * Renders the video player playlist popup modal.
	 *
	 * This function includes the template file "video-playlist-modal.php" to display the video player playlist popup modal.
	 *
	 * @since 2.6.7
	 *
	 * @param \Masteriyo\Models\Course
	 */
	public function render_course_preview_video_player_playlist_modal( $course ) {
		$video_playlist_items = masteriyo_get_previewable_lessons_video_data( $course->get_id() );
		include_once Constants::get( 'MASTERIYO_COURSE_PREVIEW_ADDON_TEMPLATES' ) . '/video-playlist-modal.php';
	}
}
