<?php
/**
 * @package    block_ned_teacher_tools
 * @subpackage support
 * @category   NED
 * @copyright  2022 NED {@link http://ned.ca}
 * @author     NED {@link http://ned.ca}
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */

namespace block_ned_teacher_tools\support;

use block_ned_teacher_tools\deadline_manager as DM;
use block_ned_teacher_tools\shared_lib as SH;


defined('MOODLE_INTERNAL') || die();

/**
 * Class dm_entity_record
 * Synthetic class for working with {@see \block_ned_teacher_tools\deadline_manager_entity} at cmid level
 * @package block_ned_teacher_tools\support
 *
 * @property-read numeric $cmid
 * @property-read numeric $courseid
 * @property-read numeric $groupid
 * @property-read numeric $userid
 * @property-read \block_ned_teacher_tools\deadline_manager_entity $dm_entity {@see dm_entity_activity::get_dm_entity()}
 * @property-read \block_ned_teacher_tools\mod\deadline_manager_mod $dm_module
 * @property-read \cm_info $cm
 * @property-read object $tt_config {@see dm_entity_activity::get_tt_config()}
 *
 * All next methods use the {@see \block_ned_teacher_tools\deadline_manager_entity} methods,
 *  but also send current cmid to them:
 * @method string get_source(bool $original=false) -
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::get_source()}
 * @method string get_previous_source(string $source=null, bool $original=false) -
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::get_previous_source()}
 * @method string get_deadline_object(string $source=null, bool $original=false) -
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::get_deadline_object()}
 * @method string get_formatted_source() -
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::get_formatted_source()}
 * @method int|null get_deadline(string $source=null, bool $original=false)
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::get_deadline()}
 * @method string get_formatted_deadline(string $source=null)
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::get_formatted_deadline()}
 * @method string get_deadline_counter(string $source=null)
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::get_deadline_counter()}
 * @method bool get_overrule(string $source=null, bool $original=false)
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::get_overrule()}
 * @method bool is_proxy()
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::is_proxy()}
 * @method bool is_midterm()
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::is_midterm()}
 * @method bool is_final_cm()
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::is_final_cm()}
 * @method bool is_quiz()
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::is_quiz()}
 * @method bool is_test_or_assignment()
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::is_test_or_assignment()}
 * @method bool is_editable(string $source=DM::SOURCE_GROUP, bool $original=false)
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::is_editable()}
 * @method bool is_overruled(string $source=DM::SOURCE_GROUP, bool $original=false)
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::is_overruled()}
 * @method bool is_expired(string $source=DM::SOURCE_GROUP, bool $original=false)
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::is_expired()}
 * @method bool is_uneditable_expired(string $source=DM::SOURCE_GROUP, bool $original=false)
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::is_uneditable_expired()}
 * @method bool has_extension(bool $original=false)
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::has_extension()}
 * @method bool has_date_conflict()
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::has_date_conflict()}
 * @method bool get_date_conflict()
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::get_date_conflict()}
 *
 * @method string|null get_grade() -
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::get_grade()}
 * @method int|false get_submission_time() -
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::get_submission_time()}
 * @method int get_number_of_grades(array $userids=[]) -
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::get_number_of_grades()}
 * @method string|null get_grade_url() -
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::get_grade_url()}
 * @method array get_activity_extension_data() - return array($use_extension, $numberofextensions, $can_add_extension, $showextensionicon)
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::get_activity_extension_data()}
 *
 * @method void form_add_element(\MoodleQuickForm $mform, string $current_source=DM::SOURCE_GROUP, bool $disabled=false)
 *      {@see \block_ned_teacher_tools\deadline_manager_entity::form_add_element()} - add deadline elements to the moodle form
 */
class dm_entity_activity {
    use \local_ned_controller\base_get_set_by_get_method;

    /** @var \block_ned_teacher_tools\deadline_manager_entity - to get {@see dm_entity_activity::get_dm_entity()} */
    protected $_parent;
    protected $_cmid;

    /**
     * dm_entity_activity constructor.
     *
     * @param \block_ned_teacher_tools\deadline_manager_entity $parent
     * @param numeric                                          $cmid
     */
    public function __construct($parent, $cmid){
        $this->_parent = $parent;
        $this->_cmid = $cmid;
    }

    public function __destruct() {
        $this->_parent = null;
    }

    /**
     * @param string $name
     * @param array $arguments
     *
     * @return mixed
     */
    public function __call($name, $arguments){
        if (method_exists($this->_parent, $name)){
            return $this->_parent->$name($this->_cmid, ...$arguments);
        }
        return null;
    }

    /**
     * @return bool
     */
    public function is_enabled(){
        return !empty($this->get_dm_module());
    }

    /**
     * @return bool
     */
    public function is_activity_available(){
        return SH::get_cm_visibility_by_user($this->_cmid, $this->_parent->userid, true, false);
    }

    /**
     * @return \cm_info
     */
    public function get_cm(){
        return SH::get_cm_by_cmid($this->_cmid, $this->_parent->courseid);
    }

    /**
     * @return numeric
     */
    public function get_cmid(){
        return $this->_cmid;
    }

    /**
     * @return \block_ned_teacher_tools\deadline_manager_entity
     */
    public function get_dm_entity(){
        return $this->_parent;
    }

    /**
     * @return int
     */
    public function get_courseid(){
        return $this->_parent->courseid;
    }

    /**
     * @return int
     */
    public function get_userid(){
        return $this->_parent->userid;
    }

    /**
     * @return \block_ned_teacher_tools\mod\deadline_manager_mod|null
     */
    public function get_dm_module(){
        return $this->_parent->get_dm_module($this->_cmid);
    }

    /**
     * @return int
     */
    public function get_groupid(){
        return $this->_parent->groupid;
    }

    /**
     * Return tt block config, or its option, or null
     *
     * @param string|null $option - if option is set, return its value or null
     *
     * @return null|bool|object|mixed
     */
    public function get_tt_config($option=null){
        return $this->_parent->get_tt_config($option);
    }

    /**
     * Save user or group data in the row for the DM reports
     *
     * @return object
     */
    public function get_row(){
        $row = new \stdClass();
        $row->id = $row->cmid = $this->cmid;
        $row->activity = SH::q_cm_student_link($row->cmid, $this->userid, $this->courseid);

        $row->is_overruled = $this->is_overruled();
        $row->is_proxy = $this->is_proxy();
        $row->midterm = $this->is_midterm();
        $row->raw_deadline = $this->get_deadline();

        if ($row->raw_deadline){
            $row->countdown = $this->get_deadline_counter();
            $row->deadline = $this->get_formatted_deadline();
            $row->source = $this->get_formatted_source();
            $row->conflict = $this->has_date_conflict();
        } else {
            $row->deadline = $row->countdown = DM::format_none_deadline();
        }

        return $row;
    }
}
