<?php
/**
 * Masteriyo CourseAttachments setup.
 *
 * @package Masteriyo\Addons\CourseAttachments
 *
 * @since 2.3.0
 */

namespace Masteriyo\Addons\CourseAttachments;

use Masteriyo\Constants;
use Masteriyo\Addons\CourseAttachments\Helper;

defined( 'ABSPATH' ) || exit;

/**
 * Main Masteriyo CourseAttachments class.
 *
 * @class Masteriyo\Addons\CourseAttachments\CourseAttachmentsAddon
 */

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

	/**
	 * Initialize hooks.
	 *
	 * @since 2.3.0
	 */
	public function init_hooks() {
		add_filter( 'masteriyo_rest_course_schema', array( $this, 'add_attachments_schema' ) );
		add_action( 'masteriyo_new_course', array( $this, 'save_attachments_data' ), 10, 2 );
		add_action( 'masteriyo_update_course', array( $this, 'save_attachments_data' ), 10, 2 );
		add_filter( 'masteriyo_rest_response_course_data', array( $this, 'append_attachments_data_in_response' ), 10, 4 );
		add_action( 'masteriyo_single_course_main_content_tab', array( $this, 'display_attachments_tab' ), 10 );
		add_action( 'masteriyo_layout_1_single_course_main_content_tabbar', array( $this, 'display_attachments_tab' ), 10 );
		add_action( 'masteriyo_single_course_main_content', array( $this, 'render_course_attachments' ), 50 );
		add_action( 'masteriyo_layout_1_single_course_tabbar_content', array( $this, 'render_course_attachments' ), 50 );

		add_action( 'masteriyo_new_setting', array( $this, 'save_settings' ) );
		add_filter( 'masteriyo_rest_response_setting_data', array( $this, 'append_setting_in_response' ) );

	}

	/**
	 * Saves Attachment Access settings.
	 *
	 * @since 2.17.2
	 *
	 * @return void
	 */
	public function save_settings() {
		if ( ! masteriyo_is_rest_api_request() ) {
			return;
		}

		$request = masteriyo_current_http_request();

		if ( ! isset( $request['single_course']['display']['attachment_access'] ) ) {
			return;
		}

		$attachment_access = $request['single_course']['display']['attachment_access'];

		$settings = get_option( 'masteriyo_attachment_access', array() );

		if ( ! is_array( $settings ) ) {
			$settings = array();
		}

		$settings['attachment_access'] = $attachment_access;

		update_option( 'masteriyo_attachment_access', $settings );
	}

	/**
	 * Appends Attachment Access settings to the response data.
	 *
	 * @since 2.17.2
	 *
	 * @param array $data Response data.
	 * @return array Modified response data.
	 */
	public function append_setting_in_response( $data ) {
		$settings = get_option( 'masteriyo_attachment_access', array() );

		$attachment_access = isset( $settings['attachment_access'] )
		? masteriyo_string_to_bool( $settings['attachment_access'] )
		: true;

		$data['single_course']['display']['attachment_access'] = $attachment_access;

		return $data;
	}

	/**
	 * Render attachments tab.
	 *
	 * @since 2.3.0
	 *
	 * @param \Masteriyo\Models\Course $course Course object.
	 */
	public function render_course_attachments( $course ) {
		$template_path = Constants::get( 'MASTERIYO_COURSE_ATTACHMENTS_TEMPLATES' ) . '/attachments.php';
		$template_path = apply_filters( 'masteriyo_pro_course_attachments_template_path', $template_path );

		$attachments = $this->get_attachments( $course, 'view' );

		if ( $attachments ) {
			require_once $template_path;
		}
	}

	/**
	 * Display attachments tab.
	 *
	 * @since 2.3.0
	 *
	 * @param \Masteriyo\Models\Course $course Course object.
	 */
	public function display_attachments_tab( $course ) {

		$settings = get_option( 'masteriyo_attachment_access', array() );

		$attachment_access = isset( $settings['attachment_access'] )
		? masteriyo_string_to_bool( $settings['attachment_access'] )
		: true;

		// Allow access to admins and post authors
		$is_admin_or_author = masteriyo_is_current_user_admin() || masteriyo_is_current_user_post_author( $course->get_id() );

		if ( ! $is_admin_or_author ) {
			// If attachment access is enabled and user is not enrolled, don't show the tab.
			if ( $attachment_access && ! masteriyo_is_user_enrolled_in_course( $course->get_id() ) ) {
				return;
			}
		}

		$attachments = $this->get_attachments( $course, 'view' );

		if ( $attachments ) {

			$layout = masteriyo_get_setting( 'single_course.display.template.layout' ) ?? 'default';

			if ( 'layout1' === $layout ) {
				$html  = '<li class="masteriyo-single-body__main--tabbar-item" onClick="masteriyoSelectSingleCoursePageTabById(event);" data-tab-id="masteriyoSingleCourseAttachmentsTab">';
				$html .= esc_html__( 'Attachments', 'learning-management-system' );
				$html .= '</li>';
			} else {
				$html  = '<div class="masteriyo-tab" onClick="masteriyo_select_single_course_page_tab(event, \'.tab-content.course-attachments\');">';
				$html .= esc_html__( 'Attachments', 'learning-management-system' );
				$html .= '</div>';
			}

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

	/**
	 * Add course faq fields to course schema.
	 *
	 * @since 2.3.0
	 *
	 * @param array $schema
	 * @return array
	 */
	public function add_attachments_schema( $schema ) {
		$schema = wp_parse_args(
			$schema,
			array(
				'attachments' => array(
					'description' => __( 'Course attachments', 'learning-management-system' ),
					'type'        => 'array',
					'context'     => array( 'view', 'edit' ),
					'items'       => array(
						'type'       => 'object',
						'properties' => array(
							'id'                  => array(
								'description' => __( 'Course attachment ID', 'learning-management-system' ),
								'type'        => 'integer',
								'default'     => 0,
								'context'     => array( 'view', 'edit' ),
							),
							'title'               => array(
								'description' => __( 'Course attachment title', 'learning-management-system' ),
								'type'        => 'string',
								'context'     => array( 'view', 'edit' ),
								'readonly'    => true,
							),
							'url'                 => array(
								'description' => __( 'Course attachment URL', 'learning-management-system' ),
								'type'        => 'string',
								'format'      => 'uri',
								'context'     => array( 'view', 'edit' ),
								'readonly'    => true,
							),
							'mime_type'           => array(
								'description' => __( 'Course attachment mime type', 'learning-management-system' ),
								'type'        => 'string',
								'context'     => array( 'view', 'edit' ),
								'readonly'    => true,
							),
							'file_size'           => array(
								'description' => __( 'Course attachment file size', 'learning-management-system' ),
								'type'        => 'integer',
								'context'     => array( 'view', 'edit' ),
								'readonly'    => true,
							),
							'formatted_file_size' => array(
								'description' => __( 'Course attachment formatted file size', 'learning-management-system' ),
								'type'        => 'string',
								'context'     => array( 'view', 'edit' ),
								'readonly'    => true,
							),
							'created_at'          => array(
								'description' => __( 'Course attachment creation/upload date.', 'learning-management-system' ),
								'type'        => 'string',
								'format'      => 'date-time',
								'context'     => array( 'view', 'edit' ),
								'readonly'    => true,
							),
						),
					),
				),
			)
		);

		return $schema;
	}

	/**
	 * Save course FAQ data.
	 *
	 * @since 2.3.0
	 *
	 * @param integer $id The course ID.
	 * @param \Masteriyo\Models\Course $object The course object.
	 */
	public function save_attachments_data( $course_id, $course ) {
		$request = masteriyo_current_http_request();

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

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

		if ( isset( $request['attachments'] ) ) {
			$attachment_ids = wp_list_pluck( $request['attachments'], 'id' );
			$attachment_ids = array_filter(
				$attachment_ids,
				function( $attachment_id ) {
					$post = get_post( $attachment_id );
					return $post && 'attachment' === $post->post_type;
				}
			);

			$course->update_meta_data( '_attachments', $attachment_ids );
			$course->save_meta_data();
		}
	}

	/**
	 * Append course attachments to course response.
	 *
	 * @since 2.3.0
	 *
	 * @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.
	 */
	public function append_attachments_data_in_response( $data, $course, $context, $controller ) {
		$data['attachments'] = $this->get_attachments( $course, $context );

		return $data;
	}

	/**
	 * Get course attachments
	 *
	 * @since 2.3.0
	 *
	 * @param \Masteriyo\Models\Course $course Course object.
	 * @param string $context Request context.
	 *
	 * @return array
	 */
	protected function get_attachments( $course, $context ) {
		// Filter invalid attachments.
		$attachments = array_filter(
			array_map(
				function( $attachment ) {
					$post = get_post( $attachment );

					if ( $post && 'attachment' === $post->post_type ) {
						return $post;
					}

					return false;
				},
				(array) $course->get_meta( '_attachments' )
			)
		);

		// Convert the attachments to the response format.
		$attachments = (array) array_reduce(
			$attachments,
			function( $result, $attachment ) {
				$file_size = absint( filesize( get_attached_file( $attachment->ID ) ) );

				$result[] = array(
					'id'                  => $attachment->ID,
					'url'                 => wp_get_attachment_url( $attachment->ID ),
					'title'               => $attachment->post_title,
					'mime_type'           => $attachment->post_mime_type,
					'filename'            => basename( get_attached_file( $attachment->ID ) ),
					'file_size'           => $file_size,
					'formatted_file_size' => size_format( $file_size ),
					'created_at'          => masteriyo_rest_prepare_date_response( $attachment->post_date_gmt ),
					'svg'                 => Helper::get_svg_from_mime_type( $attachment->post_mime_type ),
				);
				return $result;
			},
			array()
		);

		/**
		 * Course attachment filter.
		 *
		 * @since 2.3.0
		 *
		 * @return array[] $attachments Course attachments.
		 * @param \Masteriyo\Models\Course $course Course object.
		 * @param string $context Context.
		 */
		return apply_filters( 'masteriyo_rest_course_attachments', $attachments, $course, $context );
	}
}
