<?php
/**
 * Assignment Reply model.
 *
 * @since 2.3.5
 *
 * @package Masteriyo\Models;
 */

namespace Masteriyo\Addons\Assignment\Models;

use Masteriyo\Addons\Assignment\Enums\AssignmentReplyStatus;
use Masteriyo\Database\Model;
use Masteriyo\Addons\Assignment\Repository\AssignmentReplyRepository;
use Masteriyo\Enums\PostStatus;
use Masteriyo\PostType\PostType;

defined( 'ABSPATH' ) || exit;

/**
 * Assignment Reply model (post type).
 *
 * @since 2.3.5
 */
class AssignmentReply extends Model {

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

	/**
	 * Post type.
	 *
	 * @since 2.3.5
	 *
	 * @var string
	 */
	protected $post_type = 'mto-assignment-reply';

	/**
	 * Comment type.
	 *
	 * @since 2.3.5
	 *
	 * @var string
	 */
	protected $comment_type = 'mto_assignment_reply';

	/**
	 * Cache group.
	 *
	 * @since 2.3.5
	 *
	 * @var string
	 */
	protected $cache_group = 'assignment_replies';

	/**
	 * Stores assignment reply data.
	 *
	 * @since 2.3.5
	 *
	 * @var array
	 */
	protected $data = array(
		'answer'        => '',
		'menu_order'    => 0,
		'parent_id'     => 0, // Parent ID is Assignment ID.
		'user_id'       => 0,
		'created_at'    => null,
		'modified_at'   => null,
		'status'        => false,
		'earned_points' => 0,
		'note'          => '',
		'attachments'   => array(),
	);

	/**
	 * Get the assignment reply if ID
	 *
	 * @since 2.3.5
	 *
	 * @param \Masteriyo\Addons\Assignment\Repository\AssignmentReplyRepository $assignment_reply_repository Assignment Reply Repository.
	 */
	public function __construct( AssignmentReplyRepository $assignment_reply_repository ) {
		$this->repository = $assignment_reply_repository;
	}

	/*
	|--------------------------------------------------------------------------
	| Alias functions.
	|--------------------------------------------------------------------------
	*/

	/**
	 * Returns the assignment reply's course id.
	 *
	 * @since  2.3.5
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 *
	 * @return string
	 */
	public function get_assignment_id( $context = 'view' ) {
		return $this->get_parent_id( $context );
	}

	/**
	 * Set the assignment reply's course id.
	 *
	 * @since 2.3.5
	 *
	 * @param int $assignment_id Course id.
	 */
	public function set_assignment_id( $assignment_id ) {
		$this->set_parent_id( $assignment_id );
	}

	/**
	 * Set assignment reply modified date.
	 *
	 * @since 2.3.5
	 *
	 * @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_date_modified( $date ) {
		$this->set_modified_at( $date );
	}

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

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

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

	/**
	 * Return assignment object.
	 *
	 * @since 2.5.20
	 *
	 * @return \Masteriyo\Addons\Assignment\Models\Assignment|null
	 */
	public function get_assignment() {
		return masteriyo_get_assignment( $this->get_assignment_id() );
	}

	/**
	 * Set reviewed.
	 *
	 * @since 2.5.20
	 *
	 * @param bool $reviewed
	 */
	public function set_reviewed( $reviewed ) {
		$reviewed = masteriyo_string_to_bool( $reviewed );
		$status   = $reviewed ? PostStatus::PUBLISH : PostStatus::DRAFT;
		$this->set_status( $status );
	}

	/**
	 * Get pass or fail result.
	 *
	 * @since 2.5.20
	 *
	 * @param string $context
	 * @return string
	 */
	public function get_result() {
		$text = $this->is_passed() ? 'pass' : 'fail';
		$text = $this->is_reviewed() ? $text : 'pending';

		/**
		 * Filters assignment reply result.
		 *
		 * @since 2.5.20
		 *
		 * @param string $text
		 * @param \Masteriyo\Addons\Assignment\Models\AssignmentReply $submission
		 *
		 */
		return apply_filters( 'masteriyo_assignment_reply_result', $text, $this );
	}

	/*
	|--------------------------------------------------------------------------
	| Conditional
	|--------------------------------------------------------------------------
	*/

	/**
	 * Return true if the assignment submission is already reviewed.
	 *
	 * @since 2.5.20
	 */
	public function is_reviewed() {
		$reviewed = AssignmentReplyStatus::PUBLISH === $this->get_status() ? true : false;

		/**
		 * Filters whether assignment submission/reply is reviewed or not.
		 *
		 * @since 2.5.20
		 *
		 * @param bool $reviewed
		 * @param \Masteriyo\Addons\Assignment\Models\AssignmentReply $assignment_reply
		 */
		return apply_filters( 'masteriyo_pro_is_assignment_reply_reviewed', $reviewed, $this );
	}

	/**
	 * Return true if the assignment submission is passed.
	 *
	 * @since 2.5.20
	 *
	 * @return boolean
	 */
	public function is_passed() {
		$assignment = $this->get_assignment();
		$passed     = false;

		if ( $assignment && $this->get_earned_points( 'edit' ) >= $assignment->get_pass_points( 'edit' ) ) {
			$passed = true;
		}

		/**
		 * Filters whether user for an assignment submission is passed or not.
		 *
		 * @since
		 *
		 * @param bool $passed
		 * @param \Masteriyo\Addons\Assignment\Models\AssignmentReply $submission
		 */
		return apply_filters( 'masteriyo_assignment_reply_is_passed', $passed, $this );
	}

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

	/**
	 * Get assignment reply created date.
	 *
	 * @since  2.3.5
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 *
	 * @return 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 assignment reply modified date.
	 *
	 * @since  2.3.5
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 *
	 * @return 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 assignment reply answer.
	 *
	 * @since  2.3.5
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 *
	 * @return string
	 */
	public function get_answer( $context = 'view' ) {
		return $this->get_prop( 'answer', $context );
	}

	/**
	 * Returns assignment reply parent id.
	 *
	 * @since  2.3.5
	 *
	 * @param  string $context What the value is for. Valid values are view and edit.
	 *
	 * @return string
	 */
	public function get_parent_id( $context = 'view' ) {
		return $this->get_prop( 'parent_id', $context );
	}

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

	/**
	 * Returns assignment reply menu order.
	 *
	 * @since  2.3.5
	 *
	 * @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 assignment reply status.
	 *
	 * @since  2.3.5
	 *
	 * @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 );
	}

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

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

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

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

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

	/**
	 * Set assignment reply created date.
	 *
	 * @since 2.3.5
	 *
	 * @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 ) {
		$this->set_date_prop( 'created_at', $date );
	}

	/**
	 * Set assignment reply 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 ) {
		$this->set_prop( 'modified_at', $date );
	}

	/**
	 * Set assignment reply answer.
	 *
	 * @since 2.3.5
	 *
	 * @param string $answer Assignment Reply answer.
	 */
	public function set_answer( $answer ) {
		$this->set_prop( 'answer', $answer );
	}

	/**
	 * Set the assignment reply parent id.
	 *
	 * @since 2.3.5
	 *
	 * @param int $parent Parent id.
	 */
	public function set_parent_id( $parent ) {
		$this->set_prop( 'parent_id', absint( $parent ) );
	}

	/**
	 * Set the assignment reply's author id.
	 *
	 * @since 2.3.5
	 *
	 * @param int $user_id author id.
	 */
	public function set_user_id( $user_id ) {
		$this->set_prop( 'user_id', absint( $user_id ) );
	}

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

	/**
	 * Set assignment reply status.
	 *
	 * @since 2.3.5
	 *
	 * @param string $status Assignment Reply status.
	 */
	public function set_status( $status ) {
		$this->set_prop( 'status', $status );
	}

	/**
	 * Set assignment reply earned points.
	 *
	 * @since 2.3.5
	 *
	 * @param float $earned_points Assignment Reply earned_points.
	 */
	public function set_earned_points( $earned_points ) {
		$this->set_prop( 'earned_points', floatval( $earned_points ) );
	}

	/**
	 * Set assignment reply note.
	 *
	 * @since 2.3.5
	 *
	 * @param string $note Assignment Reply note.
	 */
	public function set_note( $note ) {
		$this->set_prop( 'note', $note );
	}

	/**
	 * Set assignment reply attachments.
	 *
	 * @since 2.3.5
	 *
	 * @param string $attachments Assignment Reply attachments.
	 */
	public function set_attachments( $attachments ) {
		$this->set_prop( 'attachments', (array) $attachments );
	}
}
