<?php
/**
 * Grade model.
 *
 * @since 2.5.20
 *
 * @package Masteriyo\Addons\Gradebook
 */

namespace Masteriyo\Addons\Gradebook\Models;

use Masteriyo\Database\Model;
use Masteriyo\Addons\Gradebook\Repository\GradeRepository;

defined( 'ABSPATH' ) || exit;

/**
 * Grade model (post type).
 *
 * @since 2.5.20
 */
class Grade extends Model {

	/**
	 * This is the name of this object type.
	 *
	 * @since 2.5.20
	 *
	 * @var string
	 */
	protected $object_type = 'grade';

	/**
	 * Post type.
	 *
	 * @since 2.5.20
	 *
	 * @var string
	 */
	protected $post_type = 'mto-grade';

	/**
	 * Cache group.
	 *
	 * @since 2.5.20
	 *
	 * @var string
	 */
	protected $cache_group = 'grades';

	/**
	 * Stores grade data.
	 *
	 * @since 2.5.20
	 *
	 * @var array
	 */
	protected $data = array(
		'name'        => '',
		'status'      => false,
		'menu_order'  => 0,
		'author_id'   => 0,
		'color'       => '',
		'points'      => 0,
		'min'         => 0,
		'max'         => 100,
		'children'    => array(),
		'created_at'  => null,
		'modified_at' => null,
	);

	/**
	 * Get the grade if ID
	 *
	 * @since 2.5.20
	 *
	 * @param GradeRepository $grade_repository Grade Repository.
	 */
	public function __construct( GradeRepository $grade_repository ) {
		$this->repository = $grade_repository;
	}

	/*
	|--------------------------------------------------------------------------
	| Non-CRUD Getters
	|--------------------------------------------------------------------------
	*/

	/**
	 * Get the grade's title. For grades this is the grade name.
	 *
	 * @since 2.5.20
	 *
	 * @return string
	 */
	public function get_title() {
		/**
		 * Filters grade title.
		 *
		 * @since 2.5.20
		 *
		 * @param string $title Grade title.
		 * @param Masteriyo\Models\Grade $grade Grade object.
		 */
		return apply_filters( 'masteriyo_grade_title', $this->get_name(), $this );
	}


	/**
	 * Get the grade's code. For grades this is the grade name.
	 *
	 * @since 2.5.20
	 *
	 * @return string
	 */
	public function get_code() {
		/**
		 * Filters grade code.
		 *
		 * @since 2.5.20
		 *
		 * @param string $code Grade code.
		 * @param Masteriyo\Models\Grade $grade Grade object.
		 */
		return apply_filters( 'masteriyo_grade_code', $this->get_name(), $this );
	}

	/**
	 * Grade permalink.
	 *
	 * @return string
	 */
	public function get_permalink() {
		return get_permalink( $this->get_id() );
	}

	/**
	 * Returns the children IDs if applicable. Overridden by child classes.
	 *
	 * @return array of IDs
	 */
	public function get_children() {
		return get_children( $this->get_id() );
	}

	/**
	 * Get the object type.
	 *
	 * @since 2.5.20
	 *
	 * @return string
	 */
	public function get_object_type() {
		return $this->object_type;
	}

	/**
	 * Get the post type.
	 *
	 * @since 2.5.20
	 *
	 * @return string
	 */
	public function get_post_type() {
		return $this->post_type;
	}

	/**
	 * Get post preview link.
	 *
	 * @since 2.5.20
	 *
	 * @return string
	 */
	public function get_post_preview_link() {
		$preview_link = get_preview_post_link( $this->get_id() );

		/**
		 * Grade post preview link.
		 *
		 * @since 2.5.20
		 *
		 * @param string $url Preview URL.
		 * @param Masteriyo\Models\Grade $grade Grade object.
		 */
		return apply_filters( 'masteriyo_grade_post_preview_link', $preview_link, $this );
	}

	/**
	 * Get preview link in learn page.
	 *
	 * @since 2.5.20
	 *
	 * @return string
	 */
	public function get_preview_link() {
		$preview_link = '';
		$grade        = masteriyo_get_grade( $this->get_grade_id() );

		if ( $grade ) {
			$grade_preview_link = $grade->get_preview_link( false );
			$preview_link       = trailingslashit( $grade_preview_link ) . 'grade/' . $this->get_id();
		}

		/**
		 * Grade preview link for learn page.
		 *
		 * @since 2.5.20
		 *
		 * @param string $url Preview URL.
		 * @param Masteriyo\Models\Grade $grade Grade object.
		 */
		return apply_filters( 'masteriyo_grade_preview_link', $preview_link, $this );
	}

	/*
	|--------------------------------------------------------------------------
	| Getters
	|--------------------------------------------------------------------------
	*/

	/**
	 * Get grade name.
	 *
	 * @since  2.5.20
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 *
	 * @return string
	 */
	public function get_name( $context = 'view' ) {
		/**
		 * Filters grade name.
		 *
		 * @since 2.5.20
		 *
		 * @param string $name Grade name.
		 * @param \Masteriyo\Models\Grade $grade Grade object.
		 */
		return apply_filters( 'masteriyo_grade_name', $this->get_prop( 'name', $context ), $this );
	}

	/**
	 * Get grade created date.
	 *
	 * @since  2.5.20
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 *
	 * @return \Masteriyo\DateTime|null object if the date is set or null if there is no date.
	 */
	public function get_created_at( $context = 'view' ) {
		return $this->get_prop( 'created_at', $context );
	}

	/**
	 * Get grade modified date.
	 *
	 * @since  2.5.20
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 *
	 * @return \Masteriyo\DateTime|null object if the date is set or null if there is no date.
	 */
	public function get_modified_at( $context = 'view' ) {
		return $this->get_prop( 'modified_at', $context );
	}

	/**
	 * Get grade color.
	 *
	 * @since  2.5.20
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 *
	 * @return string
	 */
	public function get_color( $context = 'view' ) {
		return $this->get_prop( 'color', $context );
	}

	/**
	 * Get grade points.
	 *
	 * @since  2.5.20
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 *
	 * @return string
	 */
	public function get_points( $context = 'view' ) {
		return $this->get_prop( 'points', $context );
	}

	/**
	 * Get grade min (percentage).
	 *
	 * @since  2.5.20
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 *
	 * @return string
	 */
	public function get_min( $context = 'view' ) {
		return $this->get_prop( 'min', $context );
	}


	/**
	 * Get grade max (percentage).
	 *
	 * @since  2.5.20
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 *
	 * @return string
	 */
	public function get_max( $context = 'view' ) {
		return $this->get_prop( 'max', $context );
	}

	/**
	 * Returns the grade's author id.
	 *
	 * @since  1.3.2
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 *
	 * @return string
	 */
	public function get_author_id( $context = 'view' ) {
		return $this->get_prop( 'author_id', $context );
	}

	/**
	 * Returns grade menu order.
	 *
	 * @since  2.5.20
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 *
	 * @return string
	 */
	public function get_menu_order( $context = 'view' ) {
		return $this->get_prop( 'menu_order', $context );
	}

	/**
	 * Get grade status.
	 *
	 * @since  2.5.20
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 *
	 * @return string
	 */
	public function get_status( $context = 'view' ) {
		return $this->get_prop( 'status', $context );
	}

	/*
	|--------------------------------------------------------------------------
	| Setters
	|--------------------------------------------------------------------------
	*/

	/**
	 * Set grade name.
	 *
	 * @since 2.5.20
	 *
	 * @param string $name grade name.
	 */
	public function set_name( $name ) {
		$this->set_prop( 'name', $name );
	}

	/**
	 * Set grade created date.
	 *
	 * @since 2.5.20
	 *
	 * @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date.
	 */
	public function set_created_at( $date = null ) {
		$this->set_date_prop( 'created_at', $date );
	}

	/**
	 * Set grade modified date.
	 *
	 * @since 2.5.20
	 *
	 * @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date.
	 */
	public function set_modified_at( $date = null ) {
		$this->set_date_prop( 'modified_at', $date );
	}

	/**
	 * Set grade color.
	 *
	 * @since 2.5.20
	 *
	 * @param string $color Grade color.
	 */
	public function set_color( $color ) {
		$this->set_prop( 'color', $color );
	}

	/**
	 * Set the grade's author id.
	 *
	 * @since 1.3.2
	 *
	 * @param int $author_id author id.
	 */
	public function set_author_id( $author_id ) {
		$this->set_prop( 'author_id', absint( $author_id ) );
	}

	/**
	 * Set the grade menu order.
	 *
	 * @since 2.5.20
	 *
	 * @param int $menu_order Menu order id.
	 */
	public function set_menu_order( $menu_order ) {
		$this->set_prop( 'menu_order', absint( $menu_order ) );
	}

	/**
	 * Set the grade points.
	 *
	 * @since 2.5.20
	 *
	 * @param int $points Points
	 */
	public function set_points( $points ) {
		$this->set_prop( 'points', floatval( $points ) );
	}

	/**
	 * Set the grade min.
	 *
	 * @since 2.5.20
	 *
	 * @param int $min min
	 */
	public function set_min( $min ) {
		$this->set_prop( 'min', absint( $min ) );
	}

	/**
	 * Set the grade max.
	 *
	 * @since 2.5.20
	 *
	 * @param int $max max
	 */
	public function set_max( $max ) {
		$this->set_prop( 'max', absint( $max ) );
	}

	/**
	 * Set grade status.
	 *
	 * @since 2.5.20
	 *
	 * @param string $status Grade status.
	 */
	public function set_status( $status ) {
		$this->set_prop( 'status', $status );
	}
}
