<?php

namespace Masteriyo\Addons\CourseBundle\Models;

defined( 'ABSPATH' ) || exit;


use Masteriyo\Enums\PostStatus;
use Masteriyo\Models\Course;
use Masteriyo\Models\CourseCategory;

class CourseBundle extends Course {

	/**
	 * This is the name of this object type.
	 *
	 * @since 2.12.0
	 *
	 * @var string
	 */
	protected $object_type = 'course-bundle';

	/**
	 * Post type.
	 *
	 * @since 2.12.0
	 *
	 * @var string
	 */
	protected $post_type = 'mto-course-bundle';

	/**
	 * Cache group.
	 *
	 * @since 2.12.0
	 *
	 * @var string
	 */
	protected $cache_group = 'course-bundles';

	/**
	 * Extra data for this object. Name value pairs (name + default value).
	 * Used as a standard way for sub classes (like product types) to add
	 * additional information to an inherited class.
	 *
	 * @since 2.12.0
	 * @var array
	 */
	protected $extra_data = array(
		'courses' => array(),
	);

	/**
	 * Get the bundled courses for this course bundle.
	 *
	 * @since 2.12.0
	 *
	 * @param string $status The status of the courses to retrieve. Defaults to any status.
	 *
	 * @return \Masteriyo\Models\Course[] The bundled courses.
	 */
	public function get_bundled_courses( $status = PostStatus::ANY ) {
		$courses = array_filter(
			array_map(
				function( $course_id ) use ( $status ) {
					$current_status = get_post_status( absint( $course_id ) );

					if ( PostStatus::ANY === $status || $current_status === $status ) {
						/**
						 * Filters the bundled course for the course bundle.
						 *
						 * @since 2.21.0
						 *
						 * @param \Masteriyo\Models\Course $course The bundled course.
						 * @param \Masteriyo\Models\CourseBundle $this_bundle The course bundle object.
						 *
						 * @return \Masteriyo\Models\Course
						 */
						return apply_filters( 'masteriyo_bundled_course', masteriyo_get_course( absint( $course_id ) ), $this );
					}

					return null;

				},
				$this->get_courses()
			),
			function ( $v ) {
				return $v instanceof \Masteriyo\Models\Course;
			}
		);

		/**
		 * Filters the list of bundled courses for the course bundle.
		 *
		 * @since 2.12.0
		 *
		 * @param \Masteriyo\Models\Course[] $courses The bundled courses.
		 * @param \Masteriyo\Models\CourseBundle $this_bundle The course bundle object.
		 *
		 * @return \Masteriyo\Models\Course[] The filtered list of bundled courses.
		 */
		return apply_filters( 'masteriyo_bundled_courses', $courses, $this );
	}

	/**
	 * Get bundled courses instructors.
	 *
	 * @return \Masteriyo\Models\User[]
	 */
	public function get_instructors() {
		$bundled_courses = $this->get_bundled_courses();

		$author_ids  = array_unique(
			array_map(
				function( $course ) {
					return $course->get_author_id();
				},
				$bundled_courses
			)
		);
		$instructors = array_map( 'masteriyo_get_user', $author_ids );

		return apply_filters( 'masteriyo_bundled_courses_instructors', $instructors, $this );
	}

	/**
	 * Get categories
	 *
	 * @return CourseCategory[]
	 */
	public function get_categories() {
		$bundled_courses = $this->get_bundled_courses();
		$cat_ids         = array_unique(
			masteriyo_array_flatten(
				array_map(
					function( $course ) {
						return $course->get_category_ids();
					},
					$bundled_courses
				)
			)
		);
		$store           = masteriyo( 'course_cat.store' );

		$categories = array_map(
			function( $cat_id ) use ( $store ) {
				$cat_obj = masteriyo( 'course_cat' );
				$cat_obj->set_id( $cat_id );
				$store->read( $cat_obj );
				return $cat_obj;
			},
			$cat_ids
		);

		return apply_filters( 'masteriyo_bundled_courses_categories', $categories, $this );
	}

	/**
	 * Get courses.
	 *
	 * @param string $context
	 * @return array
	 */
	public function get_courses( $context = 'view' ) {
		return $this->get_prop( 'courses', $context );
	}

	/**
	 * Set courses.
	 *
	 * @param array $courses
	 * @return void
	 */
	public function set_courses( $courses ) {
		$this->set_prop( 'courses', $courses );
	}

	/**
	 * Get course billing cycle.
	 *
	 * @since 2.12.0
	 * @param string $context What the value is for. Valid values are view and edit.
	 * @return int
	 */
	public function get_billing_cycle( $context = 'view' ) {
		return $this->get_prop( 'billing_cycle', $context );
	}
}
