<?php
/**
 * Masteriyo public profile setup.
 *
 * @package Masteriyo\Addons\PublicProfile
 *
 * @since 2.6.8
 */
namespace Masteriyo\Addons\PublicProfile;

use Masteriyo\Addons\Certificate\PDF\CertificatePDF;
use Masteriyo\Addons\PublicProfile\AjaxHandlers\PaginationAjaxHandler;
use Masteriyo\Addons\PublicProfile\Setting;
use Masteriyo\Constants;

defined( 'ABSPATH' ) || exit;
/**
 * Main Masteriyo Public Profile class.
 *
 * @class Masteriyo\Addons\PublicProfile
 */
class PublicProfileAddon {

	/**
	 * Instance
	 *
	 * @since 2.6.8
	 *
	 * @var \Masteriyo\Addons\PublicProfile\PublicProfileAddon
	 */
	protected static $instance = null;

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

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

		return self::$instance;
	}

	/**
	 * Initialization.
	 *
	 * @since 2.6.8
	 */
	public function init() {
		$this->init_hooks();
	}

	/**
	 * Initialize hooks.
	 *
	 * @since 2.6.8
	 */
	public function init_hooks() {
		add_filter( 'masteriyo_ajax_handlers', array( $this, 'register_ajax_handlers' ) );
		add_filter( 'masteriyo_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
		add_filter( 'masteriyo_localized_public_scripts', array( $this, 'localize_public_profile_scripts' ) );
		add_action( 'generate_rewrite_rules', array( $this, 'register_public_profile_rewrite_rules' ) );
		add_filter( 'query_vars', array( $this, 'add_public_profile_query_vars' ) );
		add_action( 'template_redirect', array( $this, 'handle_certificate_preview' ), 10 );
		add_action( 'template_redirect', array( $this, 'render_public_profile_template' ), 11 );
		add_filter( 'masteriyo_rest_response_setting_data', array( $this, 'append_setting_in_response' ), 10, 4 );
		add_action( 'masteriyo_new_setting', array( $this, 'save_public_profile_settings' ), 10, 1 );
	}

	/**
	 * Enqueue scripts.
	 *
	 * @since 2.6.8
	 *
	 * @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(
				'public-profile-tab'        => array(
					'src'      => plugin_dir_url( Constants::get( 'MASTERIYO_PUBLIC_PROFILE_ADDON_FILE' ) ) . '/assets/js/public-profile' . $suffix . '.js',
					'context'  => 'public',
					'callback' => array( $this, 'load_js' ),
					'deps'     => array( 'jquery' ),
				),
				'public-profile-pagination' => array(
					'src'      => plugin_dir_url( Constants::get( 'MASTERIYO_PUBLIC_PROFILE_ADDON_FILE' ) ) . '/assets/js/pagination' . $suffix . '.js',
					'context'  => 'public',
					'callback' => array( $this, 'load_js' ),
					'deps'     => array( 'jquery', 'masteriyo-jquery-block-ui' ),
				),
			)
		);
	}

	/**
	 * Localize public profile page scripts.
	 *
	 * @since 2.6.80
	 *
	 * @param array $scripts
	 *
	 * @return array
	 */
	public function localize_public_profile_scripts( $scripts ) {
		return masteriyo_parse_args(
			$scripts,
			array(
				'public-profile-pagination' => array(
					'name' => 'MASTERIYO_PUBLIC_PROFILE_DATA',
					'data' => array(
						'ajax_url' => admin_url( 'admin-ajax.php' ),
						'nonce'    => wp_create_nonce( 'masteriyo_public_profile_pagination_nonce' ),
					),
				),
			)
		);

	}

	/**
	 * Register ajax handlers.
	 *
	 * @since 2.6.8
	 *
	 * @param array $handlers
	 *
	 * @return array
	 */
	public function register_ajax_handlers( $handlers ) {
		$handlers[] = PaginationAjaxHandler::class;

		return $handlers;
	}

	/**
	 * Load public profile js and libs only on student/instructor public profile page.
	 *
	 * @since 2.6.8
	 *
	 * @return boolean
	 */
	public function load_js() {
		return masteriyo_is_valid_public_profile_plain_slug();
	}

	/**
	 * Register public profile rewrite rules.
	 *
	 * @param WP_Rewrite $wp_rewrite The WP_Rewrite instance.
	 *
	 * @since 2.6.8
	 */
	public function register_public_profile_rewrite_rules( $wp_rewrite ) {
		$profile_slug = masteriyo_get_public_profile_slug();

		$new_rules = array(
			'^' . preg_quote( trim( $profile_slug, '/' ), '/' ) . '/([^/]+)/?$' => 'index.php?username=$matches[1]',
		);

		$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
	}

	/**
	 * Add public profile query vars.
	 *
	 * @param array $query_vars The existing query vars.
	 *
	 * @return array The modified query vars.
	 *
	 * @since 2.6.8
	 */
	public function add_public_profile_query_vars( $query_vars ) {
		$query_vars[] = 'username';
		$query_vars[] = 'certificate_id';
		$query_vars[] = 'course_id';

		return $query_vars;
	}

	/**
	 * Render public profile template.
	 *
	 * Redirects to the student/instructor public profile page.
	 *
	 * @since 2.6.8
	 */
	public function render_public_profile_template() {
		$username = get_query_var( 'username' );

		if ( ! masteriyo_is_valid_public_profile_plain_slug() ) {
			return;
		}

		$user = masteriyo_get_user_by_username( $username );

		if ( ! $user ) {
			return;
		}

		$data = masteriyo_get_public_profile_data( $user );

		if ( ! empty( $data ) ) {

			$user_full_name = empty( trim( $data['user_profile']['full_name'] ) ) ? $data['user_profile']['username'] : $data['user_profile']['full_name'];
			$new_page_title = masteriyo_get_public_profile_site_title( $user_full_name );

			// Add the public profile page title.
			add_action(
				'pre_get_document_title',
				function() use ( $new_page_title ) {
					return $new_page_title;
				}
			);

			/* Start Elearning theme compatibility. */
			add_filter(
				'elearning_title',
				function ( $title ) use ( $user_full_name ) {
					return $user_full_name;
				}
			);

			add_filter(
				'elearning_breadcrumb_trail_args',
				function ( $args ) {
					$args['echo'] = false;
					return $args;
				}
			);
			/* End Elearning theme compatibility. */

			// Remove WordPress admin bar.
			add_filter( 'show_admin_bar', '__return_false' );

			require Constants::get( 'MASTERIYO_PUBLIC_PROFILE_ADDON_TEMPLATES' ) . '/public-profile.php';
		}

		exit;
	}

	/**
	 * Handles the preview of a certificate.
	 *
	 * @since 2.6.8
	 */
	public function handle_certificate_preview() {
		$username       = sanitize_text_field( get_query_var( 'username' ) );
		$certificate_id = absint( get_query_var( 'certificate_id' ) );
		$course_id      = absint( get_query_var( 'course_id' ) );

		if ( ! masteriyo_is_valid_public_profile_plain_slug() ) {
			return;
		}

		$user = masteriyo_get_user_by_username( $username );

		if ( ! $user ) {
			return;
		}

		if ( $certificate_id && $course_id ) {
			$certificate = masteriyo_get_certificate( $certificate_id );

			if ( ! $certificate ) {
				return;
			}

			$certificate_html_content = $certificate->get_html_content();

			if ( is_wp_error( $certificate_html_content ) ) {
				return;
			}

			$certificate_pdf = new CertificatePDF( $course_id, $user->get_id(), $certificate_html_content );

			if ( ! $certificate_pdf || is_wp_error( $certificate_pdf ) ) {
				return;
			}

			$certificate_pdf->serve_preview();
		}
	}

	/**
	 * Append setting to response.
	 *
	 * @since 2.6.8
	 *
	 * @param array $data Setting data.
	 * @param \Masteriyo\Models\Setting $setting Setting object.
	 * @param string $context What the value is for. Valid values are view and edit.
	 * @param \Masteriyo\RestApi\Controllers\Version1\SettingsController $controller REST settings controller object.
	 *
	 * @return array
	 */
	public function append_setting_in_response( $data, $setting, $context, $controller ) {
		$data['advance']['public_profile'] = Setting::all();

		return $data;
	}

	/**
	 * Save global public profile settings.
	 *
	 * @since 2.6.8
	 *
	 * @param \Masteriyo\Models\Setting $setting Setting object.
	 */
	public function save_public_profile_settings( $setting ) {
		$request = masteriyo_current_http_request();

		if ( ! masteriyo_is_rest_api_request() ) {
			return;
		}

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

		$settings = masteriyo_array_only( $request['advance']['public_profile'], array_keys( Setting::all() ) );
		$settings = masteriyo_parse_args( $settings, Setting::all() );

		// Sanitization.
		$settings['slug'] = sanitize_text_field( $settings['slug'] );

		Setting::set_props( $settings );

		Setting::save();
	}
}
