<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

/**
 * @package    block_ned_student_menu
 * @copyright  Michael Gardener <mgardener@cissq.com>
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */

use block_ned_student_menu as NED;
use block_ned_student_menu\shared_lib as SH;
use local_ned_controller\mod_assign\assign as ned_assign;

require_once($CFG->libdir . '/completionlib.php');
require_once($CFG->dirroot . '/blocks/ned_student_menu/lib.php');

/**
 *
 * base class for block
 * @author     MoodleFn
 */
class block_ned_student_menu extends block_list {
    protected $_config;

    public function init() {
        $this->title = get_string('pluginname', 'block_ned_student_menu');
    }

    /**
     * Constrols the block title based on instance configuration
     *
     * @return bool
     */
    public function specialization() {
        $this->_config = get_config(NED\PLUGIN_NAME);
        if (!isset($this->config)) {
            $this->config = new stdClass;
        }

        if (!isset($this->config->customlinks)) {
            $this->config->customlinks = '';
        }

        $this->title = $this->config->block_title ?? ($this->_config->blocktitlesitelevel ?: NED\str('blocktitle'));

        // Need the bigger course object.
        $this->course = $this->page->course;

        // Custom links defaults.
        if (!isset($this->config->showcompleted)) {
            $this->config->showcompleted = 1;
        }
        if (!isset($this->config->shownotattempted)) {
            $this->config->shownotattempted = 1;
        }
        if (!isset($this->config->showwaitingforgrade)) {
            $this->config->showwaitingforgrade = 1;
        }
        if (!isset($this->config->showdraft)) {
            $this->config->showdraft = $this->_config->showdraft ?? null;
        }
        return true;
    }

    /**
     * Return the block content
     *
     * @return \stdClass|string block content
     */
    public function get_content(){
        if (empty($this->content)){
            $this->content = new stdClass;
            $this->content->items = array();
            $this->content->icons = array();
            $this->content->text = '';
            $this->content->footer = '';

            try {
                $this->_get_content();
            } catch (\Throwable $ex){
                $this->content->items[] = '';
                $this->content->footer = NED\print_hidden_error($ex, [], \html_writer::div(NED\str('blockcontenterror'), 'alert-error'));
            }
        }

        return $this->content;
    }

    /**
     * Return the real block content
     *
     * @return \stdClass|string block content
     */
    protected function _get_content()
    {
        global $USER, $SCRIPT;
        $userid = $USER->id;
        $context = context_course::instance($this->page->course->id);

        $isteacher = false;
        if ($teachers = get_enrolled_users($context, 'moodle/course:manageactivities', 0, 'u.id')) {
            if (in_array($USER->id, array_keys($teachers))) {
                $isteacher = true;
            }
        }

        if (!has_capability('block/ned_student_menu:viewblock', $context, null, false)) {
            return $this->content;
        } else if ($isteacher && !$this->page->user_is_editing()) {
            return $this->content;
        }

        if (!$isteacher && $SCRIPT == ned_assign::MOODLE_URL && $id = optional_param('id', 0,PARAM_INT)){
            $cm = SH::get_cm_by_cmorid($id, $this->page->course, null, SH::ASSIGN);
            $ned_assign = SH::ned_assign_by_cm($cm, $cm->course);
            if ($ned_assign->is_need_substitute_page()){
                $urlparams = [
                    'id' => $id,
                    'action' => optional_param('action', '', PARAM_ALPHA),
                    'rownum' => optional_param('rownum', 0, PARAM_INT)
                ];

                NED\redirect(new moodle_url(ned_assign::URL, $urlparams));
            }
        }

        if ($numberoflinks = $this->_config->numberoflinks) {
            for ($i = 0; $i <= $numberoflinks; $i++) {
                $var = 'sitelink_' . $i;
                if (!isset($this->config->$var)) {
                    $this->config->$var = 1;
                }
            }
        }

        $courseid = $this->page->course->id;
        $coursename = $this->page->course->shortname;
        $params = ['id' => $courseid];
        $params2 = ['courseid' => $courseid];

        $showtitles = $this->_config->showtitles;
        $showclassparticipants = $this->_config->showclassparticipants;
        $line = html_writer::div(html_writer::empty_tag('hr'), '', array('style' => 'width:156px;'));

        // Grade as link to gradebook
        if ($this->_config->replacewithkicagrade && NED\utils::kica_gradebook_enabled($courseid)) {
            $gradebook_url = new moodle_url('/local/kica/grade_user.php', $params2);
        } else {
            $gradebook_url = new moodle_url('/grade/report/user/index.php', $params);
        }

        $course_grade = SH::get_course_grade($courseid, $USER->id);
        $this->content->items[] = NED\link($gradebook_url, NED\str('currentgrade2', $course_grade),
            '', ['title' => NED\str('opensmth', NED\str('gradebook'))]);
        $this->content->icons[] = html_writer::div(NED\fa('fa-table'), 'fa');

        // Academic integrity flag
        $ai_status = SH::get_ai_flag_status($userid);
        if (!empty($ai_status)) {
            $this->content->items[] = NED\str('academicintegritystatus') . SH::get_ai_flag($userid) . $ai_status;
            $this->content->icons[] = html_writer::div(NED\fa('fa-shield'), 'fa');
        }

        // resubmission used - insert after PP, if it will be
        $resumbission_data = null;
        $tt_config = SH::get_site_and_course_block_config($courseid, SH::TT_NAME);
        $rm_config = SH::get_rm_config_by_courseid($courseid, $tt_config);

        if ($rm_config){
            $submissions_count = \local_ned_controller\mod_assign\assign_info::get_course_submissions_count($courseid, $USER->id);
            // if $rm_config->max_course_attempts == 0, then no resubmission limit
            $max_course_attempts = $rm_config->max_course_attempts ?: '∞';
            $resumbission_data = [NED\str('resubmissionused2', [$submissions_count, $max_course_attempts]), \html_writer::div(NED\fa('fa-retweet'), 'fa')];
        }

        if (has_capability('block/ned_student_menu:viewblock', $context) && !is_siteadmin($USER)){
            $check_show_activity = function($block, $completed, $notattempted, $waitingforgrade, $saved){
                $completed = ($this->_config->showcompleted && $block->config->showcompleted) ? $completed : null;
                $notattempted = ($this->_config->shownotattempted && $block->config->shownotattempted) ? $notattempted : null;
                $waitingforgrade = ($this->_config->showwaitingforgrade && $block->config->showwaitingforgrade) ? $waitingforgrade : null;
                $saved = ($block->config->showdraft) ? $saved : null;
                return [$completed, $notattempted, $waitingforgrade, $saved];
            };

            $student_progress_data = [
                NED\link([NED\PLUGIN_URL . 'student_progress.php', $params2],'myprogress',
                'my-progress-title', ['title' => NED\str('opensmth', NED\str('studentprogress'))]),
                \html_writer::div(NED\fa('fa-check-square-o my-progress-title'), 'fa')
            ];

            $user_status = new NED\activity_status();
            $user_status->check_activities_by_course($this->page->course, $USER);

            [
                $completedactivities,
                $incompletedactivities,
                $savedactivities,
                $notattemptedactivities,
                $waitingforgradeactivities,
                $status
            ] = $user_status->get_list();

            [$completedactivities, $notattemptedactivities, $waitingforgradeactivities, $savedactivities] =
                $check_show_activity($this, $completedactivities, $notattemptedactivities, $waitingforgradeactivities, $savedactivities);

            $participationpower_option = $tt_config->participationpower_option ?? false;
            if ($participationpower_option){
                [$summative_score, $formative_score, $participationpower, $divided_score, $text_status] = $user_status->get_full_pp_data();
                if ($summative_score){
                    SH::$C::js_call_amd('participationpower', 'init', ['.block a.participationpower']);

                    // Show PP
                    $pp_status = 'pp-'.$text_status;
                    $this->content->items[] =
                        SH::div(SH::$C::str($pp_status), 'pp-status mr-1 inline-block') .
                        SH::$C::link(['#'], 'participationpower', 'participationpower', [
                        'title' => SH::$C::str('participationpower_title'), 'data-course' => $coursename,
                        'data-data' => "$summative_score $formative_score $divided_score $participationpower $pp_status",
                    ]);
                    $this->content->icons[] = SH::div(SH::fa('fa-rocket'),
                        "participationpower $pp_status", ['title' => $participationpower]);
                }
            }

            // show resubmission used
            if (!is_null($resumbission_data)){
                [$this->content->items[], $this->content->icons[]] = $resumbission_data;
            }
            [$this->content->items[], $this->content->icons[]] = $student_progress_data;

            if ($participationpower_option) {
                $s_activity = $user_status->get_summative_activity_status();
                $this->content->icons[] = ' ';
                $this->content->items[] =
                    SH::span('', 'my-progress-data add-tag-icon', ['data-tags' => 'Summative']).
                    SH::str('summativecomplete', [$s_activity->get_all_completed(), $s_activity->all]);

                $f_activity = $user_status->get_formative_activity_status();
                $this->content->icons[] = ' ';
                $this->content->items[] =
                    SH::span('', 'my-progress-data add-tag-icon', ['data-tags' => 'Formative']).
                    SH::str('formativecomplete', [$f_activity->get_all_completed(), $f_activity->all]);

                $items = block_ned_student_get_activity_menu(null, null, $savedactivities,
                    null, $waitingforgradeactivities);
            } else {
                $items = block_ned_student_get_activity_menu($completedactivities, $incompletedactivities, $savedactivities,
                    $notattemptedactivities, $waitingforgradeactivities);
            }

            if (!empty($items)){
                $this->content->items = array_merge($this->content->items, $items);
                $this->content->icons = array_merge($this->content->icons, array_fill(0, count($items), ' '));
            }
        } else {
            $this->content->items[] = NED\str('disabledviewmessage');
            $this->content->icons[] = NED\fa('fa-warning');
        }

        if ($showclassparticipants) {
            if ($showtitles) {
                $this->content->items[] = html_writer::div(NED\str('quicklinks'), 'block-subtitle');
            } else {
                $this->content->items[] = $line;
            }

            $this->content->icons[] = '';

            $this->content->items[] = NED\link(['/user/index.php', ['contextid' => $context->id]], 'classparticipants');
            $this->content->icons[] = NED\img('i/group');
        }

        // Custom links.
        if ($custommenuitems = $this->render_custom_links($this->config->customlinks)) {
            $numberofcourselinks = count($custommenuitems);
        } else {
            $numberofcourselinks = 0;
        }

        $numberofsitelinks = $this->_config->numberoflinks;
        $enabledsitelinks = 0;

        if ($numberofsitelinks) {
            for ($i = 1; $i <= $numberofsitelinks; $i++) {
                $var = 'sitelink_' . $i;
                $enabledsitelinks += (int)$this->config->$var;
            }
        }

        if ($enabledsitelinks + $numberofcourselinks) {
            $this->content->items[] = html_writer::div($this->_config->customlinkstitle, 'block-subtitle');
        } else {
            $this->content->items[] = $line;
        }
        $this->content->icons[] = '';

        if ($numberofcourselinks) {
            foreach ($custommenuitems as $custommenuitem) {
                $cls = '';
                if ($custommenuitem->itembehavior == '_popup') {
                    $cls = 'popup';
                }
                $link = NED\link([$custommenuitem->itemurl],
                    $custommenuitem->itemtitle, $cls, ['target' => $custommenuitem->itembehavior]);
                $this->content->items[] = format_text($link, FORMAT_HTML);
                $this->content->icons[] = NED\fa($custommenuitem->itemicon);
            }
        }

        if ($enabledsitelinks) {
            for ($i = 1; $i <= $numberofsitelinks; $i++) {
                $var = 'sitelink_' . $i;
                $icon =  $this->_config->{'iconcode_' . $i};
                $target =  $this->_config->{'linkbehaviour_' . $i};
                $url =  $this->_config->{'customlinkurl_' . $i};
                $title =  $this->_config->{'customlinkstitle_' . $i};

                $cls = '';
                if ($target == '_popup') {
                    $cls = 'popup';
                }
                if ($this->_config->{'linkbehaviour_' . $i}){
                    if ((int)$this->config->$var) {
                        $this->content->items[] = NED\link([$url], $title, $cls, ['target' => $target]);
                        $this->content->icons[] = NED\fa($icon);
                    }
                }
            }
        }

        return $this->content;
    }

    public function applicable_formats() {
        return array('all' => false, 'course-*' => true);
    }

    public function has_config() {
        return true;
    }

    public function instance_allow_config() {
        return true;
    }

    public function render_custom_links($customlinkstext) {

        $customlinks = array();

        $lines = explode("\n", $customlinkstext);
        foreach ($lines as $linenumber => $line) {
            $line = trim($line);
            if (strlen($line) == 0) {
                continue;
            }
            // Parse item settings.
            $linkitem = new stdClass();
            $linkitem->itemicon = null;
            $linkitem->itemtext = null;
            $linkitem->itemurl = null;
            $linkitem->itembehavior = null;

            $linkbehaviouroptions = array(
                'new-window' => '_blank',
                'same-window' => '_self',
                'pop-up' => '_popup'
            );

            $settings = explode(',', $line);

            foreach ($settings as $i => $setting) {
                $setting = trim($setting);
                if (!empty($setting)) {
                    switch ($i) {
                        case 0:
                            $linkitem->itemicon = $setting;
                            break;
                        case 1:
                            $linkitem->itemtext = $setting;
                            $linkitem->itemtitle = $linkitem->itemtext;
                            break;
                        case 2:
                            if ($setting == 'auto-link') {
                                // Find course module.
                                if ($activityurl = $this->activity_link($linkitem->itemtext)) {
                                    $linkitem->itemurl = $activityurl;
                                } else {
                                    $linkitem->itemurl = '';
                                }
                            } else if ($setting == 'section-link') {
                                // Find section.
                                if ($sectionurl = $this->section_link($linkitem->itemtext)) {
                                    $linkitem->itemurl = $sectionurl;
                                } else {
                                    $linkitem->itemurl = '';
                                }
                            } else {
                                $linkitem->itemurl = $setting;
                            }
                            break;
                        case 3:
                            if (isset($linkbehaviouroptions[$setting])) {
                                $linkitem->itembehavior = $linkbehaviouroptions[$setting];
                            } else {
                                $linkitem->itembehavior = '_blank';
                            }
                            break;
                    }
                }
            }
            $customlinks[] = $linkitem;
        }
        return $customlinks;
    }

    public function activity_link($activityname) {
        $courseid = $this->page->course->id;
        if (!$coursectx = context_course::instance($courseid)) {
            return $activityname;
        }

        $modinfo = SH::get_fast_modinfo($courseid);
        if (!empty($modinfo->cms)) {
            foreach ($modinfo->cms as $cm) {
                // Use normal access control and visibility, but exclude labels and hidden activities.
                if ($cm->visible and $cm->has_view() and $cm->uservisible) {
                    if (trim($cm->name) == $activityname) {
                        $url = new moodle_url('/mod/'.$cm->modname.'/view.php', array('id'=>$cm->id));
                        return $url->out();
                    }
                }
            }
        }
        return false;
    }

    function section_link($sectionname) {
        $courseid = $this->page->course->id;
        // Activity selection.
        $modinfo = get_fast_modinfo($courseid);
        $sections = $modinfo->get_section_info_all();
        $counter = 0;

        foreach ($sections as $section) {
            if (trim($section->__get('name'))) {
                $sectiontitle = trim($section->__get('name'));
            } else {
                $sectiontitle = get_string('defaultsectionname', 'nedactivitycluster', $section->section);
            }
            if (trim($sectiontitle) == $sectionname) {
                $url = new moodle_url('/course/view.php', array('id'=>$courseid, 'section' => $counter));
                return $url->out();
            }
            $counter++;
        }
        return false;
    }

    /**
     * Return any HTML attributes that you want added to the outer <div> that
     * of the block when it is output.
     *
     * Because of the way certain JS events are wired it is a good idea to ensure
     * that the default values here still get set.
     * I found the easiest way to do this and still set anything you want is to
     * override it within your block in the following way
     *
     * <code php>
     * function html_attributes() {
     *    $attributes = parent::html_attributes();
     *    $attributes['class'] .= ' mynewclass';
     *    return $attributes;
     * }
     * </code>
     *
     * @return array attribute name => value.
     */
    function html_attributes() {
        $attributes = parent::html_attributes();
        $attributes['class'] .= ' block-NED';
        return $attributes;
    }
}
