<?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/>.

/**
 * Simulatore contabilità
 *
 * @package    mod_mtcontabilita
 * @copyright  2026 Mediatouch 2000 Srl <https://www.mediatouch.it>
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 * @author     Marco Cappuccio <m.cappuccio@mediatouch.it>
 */

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

require_once($CFG->libdir.'/formslib.php');

define('MTCONTABILITA_ANONYMOUS_YES', 1);
define('MTCONTABILITA_ANONYMOUS_NO', 0);

/**
 * mtcontabilita_extend_navigation_course
 */
function mtcontabilita_extend_navigation_course($navigation, $course, $context) {

    if (has_capability('mod/mtcontabilita:addinstance', $context)) {
        $url = new moodle_url('/mod/mtcontabilita/import/index.php', array('id' => $course->id));
        $settingsnode = navigation_node::create(get_string('import', 'mod_mtcontabilita'), $url, navigation_node::TYPE_SETTING,
            null, 'mtcontabilitaimport', new pix_icon('i/settings', ''));
        $navigation->add_node($settingsnode);

        $url = new moodle_url('/mod/mtcontabilita/manage/index.php', array('id' => $course->id));
        $settingsnode = navigation_node::create(get_string('manage', 'mod_mtcontabilita'), $url, navigation_node::TYPE_SETTING,
            null, 'mtcontabilitamanage', new pix_icon('i/settings', ''));
        $navigation->add_node($settingsnode);

    }
}

/**
 * mtcontabilita_add_session
 */
function mtcontabilita_add_session(\stdClass $item, array $itemdates, $context): int {
    global $DB;

    $cminstance = $DB->get_field('course_modules', 'instance', ['id' => $context->instanceid], MUST_EXIST);
    $item->mtcontabilitaid = $cminstance;

    $mtcontabilita = $DB->get_record('mtcontabilita', ['id' => $item->mtcontabilitaid], '*', MUST_EXIST);

    $now = time();
    $item->timecreated = $now;
    $item->timemodified = $now;
    // $item = mtcontabilita_cleanup_session_data($item);

    $transaction = $DB->start_delegated_transaction();
    $item->id = $DB->insert_record('mtcontabilita_item', $item);

    if (!empty($itemdates)) {
        foreach ($itemdates as $date) {
            $date->itemid = $item->id;
            $DB->insert_record('mtcontabilita_itemdet', $date);
        }
    }

    if (isset($item->description_editor)) {
        $editoroptions = [
            'noclean' => false,
            'maxfiles' => EDITOR_UNLIMITED_FILES,
            'context' => $context,
        ];
        $item = file_postupdate_standard_editor($item, 'description', $editoroptions,
            $context, 'mod_mtcontabilita', 'session', $item->id);

        $DB->update_record('mtcontabilita_item',
            ['id' => $item->id, 'description' => $item->description, 'descriptionformat' => $item->descriptionformat]);
            // ['id' => $item->id, 'description' => $item->description, 'descriptionformat' => $item->descriptionformat]);

        $description = file_rewrite_pluginfile_urls($item->description, 'pluginfile.php', $context->id,
            'mod_mtcontabilita', 'session', $item->id);

        $item->description = format_text($description, $item->descriptionformat);
    }

    $item->sessiondates = $itemdates;

    $transaction->allow_commit();

    // Trigger event.
    $item = mtcontabilita_get_session($item->id);
    $params = [
        'context' => $context,
        'objectid' => $item->id,
    ];
    $event = \mod_mtcontabilita\event\add_session::create($params);
    $event->add_record_snapshot('mtcontabilita_item', $item);
    // $event->add_record_snapshot('mtcontabilita', $mtcontabilita);
    $event->trigger();

    return $item->id;
}

/**
 * mtcontabilita_update_session
 */
function mtcontabilita_update_session($session, $sessiondates) {
    global $DB;

    $oldsession = mtcontabilita_get_session($session->id, MUST_EXIST);
    [$course, $cm] = get_course_and_cm_from_instance($oldsession->mtcontabilitaid, 'mtcontabilita');
    $mtcontabilita = $DB->get_record('mtcontabilita', ['id' => $oldsession->mtcontabilitaid], '*', MUST_EXIST);
    // $session = mtcontabilita_cleanup_session_data($session);
    $session->mtcontabilitaid = $oldsession->mtcontabilitaid; // Just in case.
    $context = context_module::instance($cm->id);

    if (isset($session->description_editor)) {
        $editoroptions = [
            'noclean' => false,
            'maxfiles' => EDITOR_UNLIMITED_FILES,
            'context' => $context,
        ];
        $session = file_postupdate_standard_editor($session, 'description', $editoroptions,
            $context, 'mod_mtcontabilita', 'session', $session->id);
    }

    $transaction = $DB->start_delegated_transaction();
    $session->timemodified = time();
    $session->countmodified = (int) ++$oldsession->countmodified;
    $DB->update_record('mtcontabilita_item', $session);
    $DB->delete_records('mtcontabilita_itemdet', ['itemid' => $session->id]);

    if (!empty($sessiondates)) {
        foreach ($sessiondates as $date) {
            $date->itemid = $session->id;
            $DB->insert_record('mtcontabilita_itemdet', $date);
        }
    }

    if (isset($session->description_editor)) {
        $description = file_rewrite_pluginfile_urls($session->description, 'pluginfile.php', $context->id,
            'mod_mtcontabilita', 'session', $session->id);
        $session->description = format_text($description, $session->descriptionformat);
    }

    // Update any calendar entries.
    $session->sessiondates = $sessiondates;

    // Commit changes.
    $transaction->allow_commit();

    // Trigger event.
    $session = mtcontabilita_get_session($session->id);
    $params = [
        'context' => $context,
        'objectid' => $session->id,
    ];
    $event = \mod_mtcontabilita\event\update_session::create($params);
    $event->add_record_snapshot('mtcontabilita_item', $session);
    $event->add_record_snapshot('mtcontabilita', $mtcontabilita);
    $event->trigger();

    return $session->id;
}

/**
 * mtcontabilita_delete_session
 */
function mtcontabilita_delete_session($session) {
    global $CFG, $DB;

    $mtcontabilita = $DB->get_record('mtcontabilita', ['id' => $session->mtcontabilitaid]);

    $transaction = $DB->start_delegated_transaction();
    $DB->delete_records('mtcontabilita_item', ['id' => $session->id]);
    $DB->delete_records('mtcontabilita_itemdet', ['itemid' => $session->id]);
    $transaction->allow_commit();

    return true;
}

/**
 * mtcontabilita_get_session
 */
function mtcontabilita_get_session($sessionid, int $strictness = IGNORE_MISSING) {
    global $DB;

    $session = $DB->get_record('mtcontabilita_item', ['id' => $sessionid], '*', $strictness);
    if ($session) {
        $session->sessiondates = mtcontabilita_get_session_dates($sessionid);
    }

    return $session;
}

/**
 * mtcontabilita_get_session_dates
 */
function mtcontabilita_get_session_dates($sessionid) {
    global $DB;

    $ret = [];
    if ($dates = $DB->get_records('mtcontabilita_itemdet', ['itemid' => $sessionid], 'sortorder')) {
        $i = 0;
        foreach ($dates as $date) {
            $ret[$i++] = $date;
        }
    }

    return $ret;
}

/**
 * mtcontabilita_supports
 */
function mtcontabilita_supports($feature) {
    switch($feature) {
        case FEATURE_GROUPS:
        case FEATURE_GROUPINGS:
        case FEATURE_MOD_INTRO:
        case FEATURE_COMPLETION_TRACKS_VIEWS:
        case FEATURE_COMPLETION_HAS_RULES:
        case FEATURE_BACKUP_MOODLE2:
        case FEATURE_SHOW_DESCRIPTION:
            return true;
        case FEATURE_GRADE_HAS_GRADE:
        case FEATURE_GRADE_OUTCOMES:
            return false;
        case FEATURE_MOD_PURPOSE:
            return MOD_PURPOSE_ASSESSMENT;
        default:
            return null;
    }
}

/**
 * mtcontabilita_add_instance
 */
function mtcontabilita_add_instance($data) {
    global $DB;

    if ($data->slang == 'en') {
        $data->bmacroclasse = false;
    }

    $data->timemodified = time();
    $data->id = '';
    $data->options = json_encode([
        @$data->criterio_i_1,
        @$data->criterio_i_2,
        @$data->criterio_i_3,
        $data->criterio_s_1,
        $data->criterio_s_2,
        $data->criterio_s_3,
        $data->criterio_s_4,
    ]);
    $data->descriptionformat = $data->description['format'];
    $data->description = $data->description['text'];
    unset($data->criterio_i_1);
    unset($data->criterio_i_2);
    unset($data->criterio_i_3);
    unset($data->criterio_s_1);
    unset($data->criterio_s_2);
    unset($data->criterio_s_3);
    unset($data->criterio_s_4);

    $dataid = $DB->insert_record("mtcontabilita", $data);
    $data->id = $dataid;

    if (!isset($data->coursemodule)) {
        $cm = get_coursemodule_from_id('mtcontabilita', $data->id);
        $data->coursemodule = $cm->id;
    }
    $context = context_module::instance($data->coursemodule);

    if (!empty($data->completionexpected)) {
        \core_completion\api::update_completion_date_event($data->coursemodule, 'mtcontabilita', $data->id,
                $data->completionexpected);
    }
    return $dataid;
}

/**
 * mtcontabilita_update_instance
 */
function mtcontabilita_update_instance($mtcontabilita) {
    global $DB;

    if ($mtcontabilita->slang == 'en') {
        $mtcontabilita->bmacroclasse = false;
    }

    $mtcontabilita->timemodified = time();
    $mtcontabilita->id = $mtcontabilita->instance;
    $mtcontabilita->options = json_encode([
        $mtcontabilita->criterio_i_1,
        $mtcontabilita->criterio_i_2,
        $mtcontabilita->criterio_i_3,
        $mtcontabilita->criterio_s_1,
        $mtcontabilita->criterio_s_2,
        $mtcontabilita->criterio_s_3,
        $mtcontabilita->criterio_s_4,
    ]);
    $mtcontabilita->descriptionformat = $mtcontabilita->description['format'];
    $mtcontabilita->description = $mtcontabilita->description['text'];
    unset($mtcontabilita->criterio_i_1);
    unset($mtcontabilita->criterio_i_2);
    unset($mtcontabilita->criterio_i_3);
    unset($mtcontabilita->criterio_s_1);
    unset($mtcontabilita->criterio_s_2);
    unset($mtcontabilita->criterio_s_3);
    unset($mtcontabilita->criterio_s_4);
    // Save the mtcontabilita into the db.
    $DB->update_record("mtcontabilita", $mtcontabilita);
    // create or update the new events.
    $completionexpected = (!empty($mtcontabilita->completionexpected)) ? $mtcontabilita->completionexpected : null;
    \core_completion\api::update_completion_date_event($mtcontabilita->coursemodule, 'mtcontabilita', $mtcontabilita->id, $completionexpected);

    $context = context_module::instance($mtcontabilita->coursemodule);

    $editoroptions = mtcontabilita_get_editor_options();

    $DB->update_record('mtcontabilita', $mtcontabilita);

    return true;
}

/**
 * mtcontabilita_pluginfile
 */
function mtcontabilita_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) {
    global $CFG, $DB;

    if ($filearea === 'item' || $filearea === 'template') {
        $itemid = (int)array_shift($args);
        // Get the item what includes the file.
        if (!$item = $DB->get_record('mtcontabilita_item', array('id' => $itemid))) {
            return false;
        }
        $mtcontabilitaid = $item->mtcontabilitaid;
        $templateid = $item->template;
    }

    if ($filearea === 'page_after_submit' || $filearea === 'item') {
        if (!$mtcontabilita = $DB->get_record("mtcontabilita", array("id" => $cm->instance))) {
            return false;
        }

        $mtcontabilitaid = $mtcontabilita->id;

        // If the filearea is "item" so we check the permissions like view/complete the mtcontabilita.
        $canload = false;
        // First check whether the user has the complete capability.
        if (has_capability('mod/mtcontabilita:complete', $context)) {
            $canload = true;
        }
        // Now we check whether the user has the view capability.
        if (has_capability('mod/mtcontabilita:view', $context)) {
            $canload = true;
        }
        // If the mtcontabilita is on frontpage and anonymous and the fullanonymous is allowed
        // So the file can be loaded too.
        if (isset($CFG->mtcontabilita_allowfullanonymous)
                && $CFG->mtcontabilita_allowfullanonymous
                && $course->id == SITEID
                && $mtcontabilita->anonymous == MTCONTABILITA_ANONYMOUS_YES ) {
            $canload = true;
        }

        if (!$canload) {
            return false;
        }
    } else if ($filearea === 'template') {
        if (!$template = $DB->get_record('mtcontabilita_template', array('id' => $templateid))) {
            return false;
        }

        // If the file is not public so the capability edititems has to be there.
        if (!$template->ispublic) {
            if (!has_capability('mod/mtcontabilita:edititems', $context)) {
                return false;
            }
        } else { // Oon public templates, at least the user has to be logged in.
            if (!isloggedin()) {
                return false;
            }
        }
    } else {
        return false;
    }

    if ($context->contextlevel == CONTEXT_MODULE) {
        if ($filearea !== 'item' && $filearea !== 'page_after_submit') {
            return false;
        }
    }

    if ($context->contextlevel == CONTEXT_COURSE || $context->contextlevel == CONTEXT_SYSTEM) {
        if ($filearea !== 'template') {
            return false;
        }
    }

    $relativepath = implode('/', $args);
    if ($filearea === 'page_after_submit') {
        $fullpath = "/{$context->id}/mod_mtcontabilita/$filearea/$relativepath";
    } else {
        $fullpath = "/{$context->id}/mod_mtcontabilita/$filearea/{$item->id}/$relativepath";
    }

    $fs = get_file_storage();

    if (!$file = $fs->get_file_by_hash(sha1($fullpath)) || $file->is_directory()) {
        return false;
    }

    // Finally send the file.
    send_stored_file($file, 0, 0, true, $options); // Download MUST be forced - security!

    return false;
}

/**
 * mtcontabilita_delete_instance
 */
function mtcontabilita_delete_instance($id) {
    global $DB;

    $DB->delete_records("mtcontabilita_itemdet", ["mtcontabilitaid" => $id]);
    $DB->delete_records('mtcontabilita_attempts', ["mtcontabilitaid" => $id]);
    $DB->delete_records('mtcontabilita_attempt_items', ["mtcontabilitaid" => $id]);
    $DB->delete_records('event', array('modulename' => 'mtcontabilita', 'instance' => $id));
    return $DB->delete_records("mtcontabilita", array("id" => $id));
}

/**
 * mtcontabilita_get_editor_options
 */
function mtcontabilita_get_editor_options() {
    return array('maxfiles' => EDITOR_UNLIMITED_FILES,
                'trusttext' => true);
}

/**
 * mtcontabilita_delete_course_module
 */
function mtcontabilita_delete_course_module($id) {
    global $DB;

    if (!$cm = $DB->get_record('course_modules', array('id' => $id))) {
        return true;
    }
    return $DB->delete_records('course_modules', array('id' => $cm->id));
}

/**
 * mtcontabilita_extend_settings_navigation
 */
function mtcontabilita_extend_settings_navigation(settings_navigation $settings, navigation_node $mtcontabilitanode) {
    global $DB;

    $hassecondary = $settings->get_page()->has_secondary_navigation();
    if (!$context = context_module::instance($settings->get_page()->cm->id, IGNORE_MISSING)) {
        throw new \moodle_exception('badcontext');
    }

    if (has_capability('mod/mtcontabilita:edititems', $context)) {

        list($course, $cm) = get_course_and_cm_from_cmid($settings->get_page()->cm->id, 'mtcontabilita');
        $binit = $DB->get_field('mtcontabilita', 'binit', ['id' => $cm->instance]);

        if ($binit) {
            $mtcontabilitanode->add(get_string('init', 'mtcontabilita'),
                new moodle_url('/mod/mtcontabilita/question2/init.php', ['sez' => 1, 'id' => $settings->get_page()->cm->id]),
                navigation_node::TYPE_CUSTOM, null, 'intialnode');
        }

        $mtcontabilitanode->add(get_string('scritture', 'mtcontabilita'),
            new moodle_url('/mod/mtcontabilita/question2/details.php', ['id' => $settings->get_page()->cm->id]),
            navigation_node::TYPE_CUSTOM, null, 'itemnode');

        $mtcontabilitanode->add(get_string('situazionefinale', 'mtcontabilita'),
            new moodle_url('/mod/mtcontabilita/question2/excel.php', ['tp' => 1, 'id' => $settings->get_page()->cm->id]),
            navigation_node::TYPE_CUSTOM, null, 'finalnode');

        $mtcontabilitanode->add(get_string('evaluation', 'mtcontabilita'),
            new moodle_url('/mod/mtcontabilita/evaluation/', ['id' => $settings->get_page()->cm->id]),
            navigation_node::TYPE_CUSTOM, null, 'evaluationnode');

        $url = new moodle_url('/mod/mtcontabilita/credits.php', ['id' => $settings->get_page()->cm->id]);
        $mtcontabilitanode->add(
            get_string('credits', 'mtcontabilita'),
            $url,
            navigation_node::TYPE_SETTING,
            null,
            'mtcontabilita_credits'
        );
    }
}
