<?php
/**
 * Masteriyo Zoom setup.
 *
 * @package Masteriyo\Zoom
 *
 * @since 2.5.19
 */

namespace Masteriyo\Addons\Zoom;

use DateTime;
use Masteriyo\Addons\Zoom\Listener\NewZoomMeetingListener;
use Masteriyo\PostType\PostType;
use Masteriyo\Addons\Zoom\PostType\Zoom;
use Masteriyo\Addons\Zoom\RestApi\ZoomController;
use Masteriyo\Addons\Zoom\RestApi\ZoomSettingController;
use Masteriyo\Enums\PostStatus;
use Masteriyo\Query\UserCourseQuery;

defined( 'ABSPATH' ) || exit;

/**
 * Main Masteriyo Zoom class.
 *
 * @class Masteriyo\Addons\Zoom\ZoomAddon
 */

class ZoomAddon {
	/**
	 * Initialize the application.
	 *
	 * @since 2.5.19
	 */
	public function init() {
		$this->init_hooks();
	}

	/**
	 * Initialize hooks.
	 *
	 * @since 2.5.19
	 */
	public function init_hooks() {
		add_filter( 'masteriyo_admin_submenus', array( $this, 'add_zoom_submenu' ) );
		add_filter( 'masteriyo_register_post_types', array( $this, 'register_post_type' ) );
		add_filter( 'masteriyo_rest_api_get_rest_namespaces', array( $this, 'register_rest_namespaces' ) );

		add_filter( 'masteriyo_course_children_post_types', array( $this, 'include_zoom_post_type' ) );
		add_filter( 'masteriyo_course_progress_post_types', array( $this, 'include_zoom_post_type' ) );
		add_filter( 'masteriyo_section_children_post_types', array( $this, 'include_zoom_post_type' ) );

		add_filter( 'masteriyo_course_progress_item_types', array( $this, 'include_zoom_item_type' ) );
		add_filter( 'masteriyo_section_children_item_types', array( $this, 'include_zoom_item_type' ) );

		add_filter( 'masteriyo_single_course_curriculum_summaries', array( $this, 'include_zoom_in_curriculum_summary' ), 10, 3 );
		add_filter( 'masteriyo_single_course_curriculum_section_summaries', array( $this, 'include_zoom_in_curriculum_section_summary' ), 10, 4 );

		add_filter( 'masteriyo_localized_admin_scripts', array( $this, 'add_localization_to_admin_scripts' ) );
		add_action( 'masteriyo_new_zoom', array( $this, 'set_new_zoom_notification_to_student' ), 10, 2 );
		add_action( 'masteriyo_set_notification_early', array( $this, 'schedule_new_zoom_notification_to_student' ), 10, 1 );

		add_filter( 'masteriyo_webhook_listeners', array( $this, 'register_listener_class' ) );

		add_action( 'masteriyo_layout_1_single_course_curriculum_shortinfo_item', array( $this, 'shortinfo_item' ), 20, 1 );
		add_action( 'masteriyo_layout_1_single_course_curriculum_accordion_header_info_item', array( $this, 'header_info_item' ), 20, 1 );

		add_filter( 'masteriyo_courses_analytics_data', array( $this, 'append_zoom_data_in_response' ), 10, 4 );
		add_filter( 'masteriyo_post_type_default_labels', array( $this, 'append_post_type_default_label' ), 10 );
	}

	/**
	 * Add post type default label.
	 *
	 * @since 2.17.0
	 *
	 * @param string $post_type Post type slug.
	 *
	 * @return array default labels.
	 */
	public function append_post_type_default_label( $original_labels ) {
		$original_labels[ PostType::ZOOM ] = 'Zoom';

		return $original_labels;
	}

	/**
	 * Append course zoom count to course analytics resource.
	 *
	 * @since 2.14.4
	 *
	 * @param array $data Course data.
	 * @param \Masteriyo\Models\Course $course Course object.
	 * @param string $context What the value is for. Valid values are view and edit.
	 * @param \Masteriyo\RestApi\Controllers\Version1\CoursesController $controller REST courses controller object.
	 *
	 * @return array Course data.
	 */
	public function append_zoom_data_in_response( $data, $course, $context, $controller ) {
		$zoom_count         = $this->get_zoom_data( $course->get_id() );
		$data['zoom_count'] = $zoom_count['total'];

		return $data;
	}

	/**
	 * Get quizzes count.
	 *
	 * @since 2.14.4
	 *
	 * @param array $course_ids Course IDs.
	 *
	 * @return array
	 */
	protected function get_zoom_data( $course_ids ) {
		$data = array(
			'total' => 0,
		);

		if ( $course_ids ) {
			$query         = new \WP_Query(
				array(
					'post_status'    => PostStatus::ANY,
					'post_type'      => PostType::ZOOM,
					'posts_per_page' => 1,
					'meta_query'     => array(
						array(
							'key'     => '_course_id',
							'value'   => $course_ids,
							'compare' => 'IN',
						),
					),
					'fields'         => 'ids',
				)
			);
			$data['total'] = $query->found_posts;
		}

		return $data;
	}

	/**
	 * Displays a short information item for the Zoom addon.
	 *
	 * This function generates an HTML span element that displays the number of Zoom meetings
	 * associated with the given section.
	 *
	 * @since 2.10.0
	 *
	 * @param \Masteriyo\Models\Section $section The section object.
	 */
	public function header_info_item( $section ) {
		if ( ! $section instanceof \Masteriyo\Models\Section ) {
			return;
		}

		$zoom_count = get_course_section_children_count_by_section( $section->get_id(), PostType::ZOOM );

		if ( 0 === $zoom_count ) {
			return;
		}

		$html  = '<span class="masteriyo-single-body-accordion-info">';
		$html .= sprintf(
			/* translators: %1$s: Zooms count */
			esc_html( _nx( '%1$s Zoom', '%1$s Zooms', $zoom_count, 'Zooms Count', 'learning-management-system' ) ),
			esc_html( number_format_i18n( $zoom_count ) )
		);
		$html .= '</span>';

		echo $html; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
	}

	/**
	 * Displays a short information item for the Zoom addon.
	 *
	 * This function generates an HTML list item that displays the number of Zoom meetings
	 * associated with the given course.
	 *
	 * @since 2.10.0
	 *
	 * @param \Masteriyo\Models\Course $course The course object.
	 */
	public function shortinfo_item( $course ) {
		if ( ! $course instanceof \Masteriyo\Models\Course ) {
			return;
		}

		$zoom_count = get_course_section_children_count_by_course( $course->get_id(), PostType::ZOOM );

		if ( 0 === $zoom_count ) {
			return;
		}

		$html  = '<li class="masteriyo-single-body__main--curriculum-content-top--shortinfo-item">';
		$html .= sprintf(
			/* translators: %1$s: Zooms count */
			esc_html( _nx( '%1$s Zoom', '%1$s Zooms', $zoom_count, 'Zooms Count', 'learning-management-system' ) ),
			esc_html( number_format_i18n( $zoom_count ) )
		);
		$html .= '</li>';

		echo $html; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
	}

	/**
	 * Register Zoom Listener.
	 *
	 * @since 2.8.3
	 *
	 * @param array $listeners
	 * @return array
	 */
	public function register_listener_class( $listeners ) {
		$listeners[] = NewZoomMeetingListener::class;

		return $listeners;
	}

	/**
	 * Add localization data to admin scripts.
	 *
	 * @since 2.5.19
	 *
	 * @param array $localized_scripts
	 * @return array
	 */
	public function add_localization_to_admin_scripts( $localized_scripts ) {
		return masteriyo_parse_args(
			$localized_scripts,
			array(
				'backend' => array(
					'data' => array(
						'isZoomCredentialsSet' => masteriyo_bool_to_string( masteriyo_is_zoom_credentials_set() ),
					),
				),
			)
		);
	}

	/**
	 * Schedule zoom notification action to student.
	 *
	 * @since 2.8.0
	 *
	 * @param int $id zoom id.
	 * @param \Masteriyo\Addons\Zoom\Models\Zoom $object The zoom object.
	 */
	public function set_new_zoom_notification_to_student( $id, $zoom ) {
		$result = masteriyo_get_setting( 'notification.student.zoom' );

		if ( isset( $result['enable'] ) && ! $result['enable'] ) {
			return;
		}

		$timestamp = $zoom->get_starts_at();

		as_schedule_single_action( strtotime( $timestamp->modify( ' - 10 minutes' ) ), 'masteriyo_set_notification_early', $zoom->get_data(), 'learning-management-system' );

	}

	/**
	 * Schedule zoom notification to student.
	 *
	 * @since 2.8.0
	 *
	 * @param \Masteriyo\Addons\Zoom\Models\Zoom $object The zoom object.
	 */
	public function schedule_new_zoom_notification_to_student( $zoom ) {

		$result = masteriyo_get_setting( 'notification.student.zoom' );

		$zoom_data = masteriyo_get_zoom( $zoom );

		if ( ! isset( $zoom_data ) ) {
			return;
		}

		$users = masteriyo_get_enrolled_users( $zoom_data->get_course_id() );

		if ( ! isset( $users ) ) {
			return;
		}

		foreach ( $users as $user ) {

			$query = new UserCourseQuery(
				array(
					'course_id' => $zoom_data->get_course_id(),
					'user_id'   => $user,
				)
			);

			$user_courses = $query->get_user_courses();

			$user_course = current( $user_courses );

			try {
				$notification_obj = masteriyo( 'notification' );

				$course = $user_course->get_course();

				$notification_obj->set_user_id( $user_course->get_user_id() );
				$notification_obj->set_created_by( $course->get_author_id() );
				$notification_obj->set_title( $course->get_title() );

				$today        = new DateTime( 'now' );
				$today_string = $today->format( 'Y - m - d H:i:s' );
				$notification_obj->set_created_at( $today_string );
				$notification_obj->set_type( $result['type'] );
				$notification_obj->set_status( 'unread' );

				$notification_obj->set_description( $result['content'] );
				$notification_obj->set_topic_url( $course->get_preview_course_link() );
				$notification_obj->set_post_id( $course->get_id() );

				$notification_obj->save();

			} catch ( \Exception $e ) {
				$notification_obj = null;
			}
		}

	}

	/**
	 * Include zoom in single course curriculum.
	 *
	 * @since 2.5.19
	 *
	 * @param array $summaries Section summaries.
	 * @param \Masteriyo\Models\Course $course Course object.
	 * @param \Masteriyo\Models\Section $section Section object.
	 * @param \WP_Post[] $posts Children of section (lessons and quizzes).
	 *
	 * @return array
	 */
	public function include_zoom_in_curriculum_section_summary( $summaries, $course, $section, $posts ) {
		$zoom_count = array_reduce(
			$posts,
			function( $count, $post ) {
				if ( PostType::ZOOM === $post->post_type ) {
					++$count;
				}

				return $count;
			},
			0
		);

		if ( 0 === $zoom_count ) {
			return $summaries;
		}

		$zoom_summary = array(
			array(
				'wrapper_start' => '<span class="masteriyo-zooms-count">',
				'wrapper_end'   => '</span>',
				'content'       => sprintf(
					/* translators: %d: Course zooms count */
					esc_html( _nx( '%d Zoom', '%d Zooms', $zoom_count, 'Zooms Count', 'learning-management-system' ) ),
					esc_html( number_format_i18n( $zoom_count ) )
				),
			),
		);

		// @see https://stackoverflow.com/questions/3797239/insert-new-item-in-array-on-any-position-in-php
		array_splice( $summaries, 2, 0, $zoom_summary );

		return $summaries;
	}

	/**
	 * Include zoom in single course curriculum.
	 *
	 * @since 2.5.19
	 *
	 * @param array $summaries Summaries.
	 * @param \Masteriyo\Models\Course $course Course object.
	 * @param WP_Post[] $posts Array of sections, quizzes and sections.

	 * @return array
	 */
	public function include_zoom_in_curriculum_summary( $summaries, $course, $posts ) {
		$zoom_count = array_reduce(
			$posts,
			function( $count, $post ) {
				if ( PostType::ZOOM === $post->post_type ) {
					++$count;
				}

				return $count;
			},
			0
		);

		if ( 0 === $zoom_count ) {
			return $summaries;
		}

		$zoom_summary = array(
			array(
				'wrapper_start' => ' < li > ',
				'wrapper_end'   => ' < / li > ',
				'content'       => sprintf(
					/* translators: %d: Course zooms count */
					esc_html( _nx( ' % d Zoom', ' % d Zooms', $zoom_count, 'Zooms Count', 'learning-management-system' ) ),
					esc_html( number_format_i18n( $zoom_count ) )
				),
			),
		);

		// @see https://stackoverflow.com/questions/3797239/insert-new-item-in-array-on-any-position-in-php
		array_splice( $summaries, 3, 0, $zoom_summary );

		return $summaries;
	}

	/**
	 * Include zoom item type.
	 *
	 * @since 2.5.19
	 *
	 * @param array $types Item types.
	 * @return array
	 */
	public function include_zoom_item_type( $types ) {
		return array_merge( $types, array( 'zoom' ) );
	}

	/**
	 * Include zoom post type.
	 *
	 * @since 2.5.19
	 *
	 * @param array $types post types.
	 * @return array
	 */
	public function include_zoom_post_type( $types ) {
		return array_merge( $types, array( PostType::ZOOM ) );
	}

	/**
	 * Register zoom post type.
	 *
	 * @since 2.5.19
	 *
	 * @param array $post_types
	 * @return array
	 */
	public function register_post_type( $post_types ) {
		$post_types['zoom'] = Zoom::class;
		return $post_types;
	}

	/**
	 * Add zoom submenu.
	 *
	 * @since 2.5.19
	 */
	public function add_zoom_submenu( $submenus ) {
		$submenus['zoom'] = array(
			'page_title' => __( 'Zoom', 'learning-management-system' ),
			'menu_title' => __( 'Zoom', 'learning-management-system' ),
			'capability' => 'edit_zooms',
			'position'   => 74,
		);
		return $submenus;
	}

		/**
	 * Register namespaces.
	 *
	 * @since 2.5.19
	 *
	 * @param array $namespaces
	 * @return array
	 */
	public function register_rest_namespaces( $namespaces ) {
		$namespaces['masteriyo / pro / v1']['zoom']                  = ZoomController::class;
		$namespaces['masteriyo / pro / v1']['zoomsettingcontroller'] = ZoomSettingController::class;

		return $namespaces;
	}
}
