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

if (!defined('MOODLE_INTERNAL')) {
    die('Direct access to this script is forbidden.');
}

require_once($CFG->dirroot.'/course/moodleform_mod.php');
require_once($CFG->dirroot.'/mod/mtcontabilita/locallib.php');

/**
 * form
 */
class mod_mtcontabilita_mod_form extends moodleform_mod {

    /**
     * definition
     */
    public function definition() {
        $editoroptions = mtcontabilita_get_editor_options();

        $mt = new mtcontabilita();

        $mform =& $this->_form;
        $mform->addElement('header', 'general', get_string('general', 'form'));

        $mform->addElement('text', 'name', get_string('name', 'mtcontabilita'), array('size' => '64'));
        $mform->setType('name', PARAM_TEXT);
        $mform->addRule('name', null, 'required', null, 'client');
        $mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');

        $this->standard_intro_elements(get_string('description', 'mtcontabilita'));
        // Opzioni.
        $mform->addElement('header', 'h1', get_string('h1', 'mtcontabilita'));
        // Testo descrittivo esercizio.
        $mform->addElement('editor', 'description', get_string('description2', 'mtcontabilita'), null, $editoroptions);
        $mform->setType('description', PARAM_RAW);
        // Tipologia.
        $mform->addElement('select', 'type', get_string('type', 'mtcontabilita'), $mt->get_opt_tipologia() );
        $mform->addHelpButton('type', 'type', 'mtcontabilita');
        $mform->addRule('type', null, 'required', null, 'client');
        // Correzione istantanea.
        $mform->addElement('selectyesno', 'inline', get_string('inline', 'mtcontabilita'));
        $mform->addHelpButton('inline', 'inline', 'mtcontabilita');
        $mform->hideIf('inline', 'type', 'neq', 0);
        // Lingua conti.
        $l = [
            '' => get_string('choose'),
            'it' => get_string_manager()->get_string('thislanguage', 'langconfig', null, 'it'),
            'en' => get_string_manager()->get_string('thislanguage', 'langconfig', null, 'en'),
        ];

        $mform->addElement('select', 'slang', get_string('lang', 'mtcontabilita'), $l);
        $mform->addRule('slang', null, 'required', null, 'client');
        // Riprendi tentativo.
        $mform->addElement('selectyesno', 'resume', get_string('resume', 'mtcontabilita'));
        $mform->addHelpButton('resume', 'resume', 'mtcontabilita');
        // numero tentativi.
        $mform->addElement('select', 'attempt', get_string('attempt', 'mtcontabilita'), $mt->get_opt_tentativi() );
        $mform->addHelpButton('attempt', 'attempt', 'mtcontabilita');
        $mform->addRule('attempt', null, 'required', null, 'client');

        $mform->addElement('duration', 'timelimit', get_string('timelimit', 'quiz'), ['optional' => true]);
        $mform->addHelpButton('timelimit', 'timelimit', 'quiz');
        // Situazione iniziale.
        $opt = ['' => get_string('choose'), 0 => get_string('no'), 1 => get_string('yes')];
        $mform->addElement('select', 'binit', get_string('binit', 'mtcontabilita'), $opt );
        $mform->addHelpButton('binit', 'binit', 'mtcontabilita');
        $mform->addRule('binit', null, 'required', null, 'client');
        // Macroclasse.
        $opt = ['' => get_string('choose'), 0 => get_string('no'), 1 => get_string('yes')];
        $mform->addElement('select', 'bmacroclasse', get_string('macroclasse', 'mtcontabilita'), $opt );
        // $mform->addHelpButton('macroclasse', 'macroclasse', 'mtcontabilita');
        $mform->hideIf('bmacroclasse', 'binit', 'neq', 1);
        $mform->hideIf('bmacroclasse', 'slang', 'neq', 'it');

        // Calcolo voto finale.
        $opt = [/*'' => get_string('choose'),*/ 1 => get_string('calcolo1', 'mtcontabilita'), 2 => get_string('calcolo2', 'mtcontabilita')];
        $mform->addElement('select', 'calcolo', get_string('calcolo', 'mtcontabilita'), $opt );
        $mform->addHelpButton('calcolo', 'calcolo', 'mtcontabilita');
        $mform->hideIf('calcolo', 'binit', 'neq', 1);
        // Mostra decimali.
        $opt = ['' => get_string('choose'), 1 => get_string('bdecimali1', 'mtcontabilita'), 2 => get_string('bdecimali2', 'mtcontabilita')];
        $mform->addElement('select', 'bdecimali', get_string('bdecimali', 'mtcontabilita'), $opt );
        $mform->addRule('bdecimali', null, 'required', null, 'client');

        $opt = [];
        for ($i = 0; $i <= 100; $i += 5) {
            $opt[$i] = $i;
        }
        // Pesatura situazione iniziale
        $tit = get_string('h2', 'mtcontabilita')." ".get_string('init', 'mtcontabilita');
        $mform->addElement('header', 'h2', $tit);
        // CE SP PN.
        $str = get_string('ce', 'mtcontabilita')."/".get_string('sp', 'mtcontabilita');
        $mform->addElement('select', 'criterio_i_1', $str, $opt );
        // D A.
        $mform->addElement('select', 'criterio_i_2', get_string('dareavere', 'mtcontabilita'), $opt );
        // Macroclasse.
        $mform->addElement('select', 'criterio_i_3', get_string('macroclasse', 'mtcontabilita'), $opt );
        $mform->hideIf('criterio_i_3', 'bmacroclasse', 'neq', 1);
        $mform->hideIf('criterio_i_3', 'slang', 'neq', 'it');
        // Pesatura scritture.
        $tit = get_string('h2', 'mtcontabilita')." ".get_string('scritture', 'mtcontabilita');
        $mform->addElement('header', 'h3', $tit);
        // Data.
        $mform->addElement('select', 'criterio_s_1', get_string('data', 'mtcontabilita'), $opt );
        // denominazione.
        $mform->addElement('select', 'criterio_s_2', get_string('denominazioneconto', 'mtcontabilita'), $opt );
        // Dare.
        $mform->addElement('select', 'criterio_s_3', get_string('d', 'mtcontabilita')."/".get_string('a', 'mtcontabilita'), $opt );
        // Avere.
        $mform->addElement('select', 'criterio_s_4', get_string('itemamount', 'mtcontabilita'), $opt );

        $mform->addElement('static', 'bmsg', "", get_string('bmsg', 'mtcontabilita') );

        $mform->hideIf('criterio_i_1', 'binit', 'neq', 1);
        $mform->hideIf('criterio_i_2', 'binit', 'neq', 1);
        $mform->hideIf('criterio_i_3', 'binit', 'neq', 1);
        $mform->hideIf('bmsg', 'binit', 'eq', 1);
        $this->standard_coursemodule_elements();
        // Buttons.
        $this->add_action_buttons();
    }

    /**
     * preprocessing
     */
    public function data_preprocessing(&$toform) {
        // 1) Prepara l’editor 'description'.
        $text   = !empty($this->current->description) ? $this->current->description : '';
        $format = isset($this->current->descriptionformat) ? $this->current->descriptionformat : FORMAT_HTML;

        if (is_array($toform)) {
            $toform['description'] = [
                'text'   => $text,
                'format' => $format,
                'itemid' => 0,
            ];
        } else {
            $toform->description = [
                'text'   => $text,
                'format' => $format,
                'itemid' => 0,
            ];
        }

        // 2) Decodifica 'options' e mappa i criteri QUI (così sei sicuro che succede
        // Prima di parent::set_data()).
        $optionsjson = is_array($toform) ? ($toform['options'] ?? null) : ($toform->options ?? null);
        if (!empty($optionsjson)) {
            $opt = json_decode($optionsjson, true); // true => array
            if (is_array($opt)) {
                $map = [
                    'criterio_i_1' => 0,
                    'criterio_i_2' => 1,
                    'criterio_i_3' => 2,
                    'criterio_s_1' => 3,
                    'criterio_s_2' => 4,
                    'criterio_s_3' => 5,
                    'criterio_s_4' => 6,
                ];
                foreach ($map as $field => $idx) {
                    $val = isset($opt[$idx]) ? (int)$opt[$idx] : null;
                    if (is_array($toform)) {
                        $toform[$field] = $val;
                    } else {
                        $toform->$field = $val;
                    }
                }
            }
        }
    }

    /**
     * set data
     */
    public function set_data($defaultvalues) {
        // Non toccare 'description' qui.
        // Se proprio vuoi, puoi lasciare solo:
        parent::set_data($defaultvalues);
    }

    /**
     * Allows module to modify the data returned by form get_data().
     * This method is also called in the bulk activity completion form.
     *
     * Only available on moodleform_mod.
     *
     * @param stdClass $data the form data to be modified.
     */
    public function data_postprocessing($data) {
        parent::data_postprocessing($data);
        if (isset($data->page_after_submit_editor)) {
            $data->page_after_submitformat = $data->page_after_submit_editor['format'];
            $data->page_after_submit = $data->page_after_submit_editor['text'];

            if (!empty($data->completionunlocked)) {
                // Turn off completion settings if the checkboxes aren't ticked.
                $suffix = $this->get_suffix();
                $completion = $data->{'completion' . $suffix};
                $autocompletion = !empty($completion) && $completion == COMPLETION_TRACKING_AUTOMATIC;
                if (!$autocompletion || empty($data->{'completionsubmit' . $suffix})) {
                    $data->{'completionsubmit' . $suffix} = 0;
                }
            }
        }
    }

    /**
     * Enforce validation rules here
     *
     * @param array $data array of ("fieldname"=>value) of submitted data
     * @param array $files array of uploaded files "element_name"=>tmp_file_path
     * @return array
     **/
    public function validation($data, $files) {
        $errors = parent::validation($data, $files);
        // Verifica pesatura iniziale.
        if ($data['binit'] == 1) {
            $toti = ((int)@$data['criterio_i_1'] + (int)@$data['criterio_i_2'] + (int)@$data['criterio_i_3']);
            if ( $toti > 0 && $toti != 100 ) {
                $errors['criterio_i_1'] = $errors['criterio_i_2'] = $errors['criterio_i_3'] = get_string('err_criteria', 'mtcontabilita');
            }
        }
        // Verifica pesatura scritture.
        $tots = ((int)$data['criterio_s_1'] + (int)$data['criterio_s_2'] + (int)$data['criterio_s_3'] + (int)$data['criterio_s_4']);
        if ( $tots > 0 && $tots != 100 ) {
            $errors['criterio_s_1'] = $errors['criterio_s_2'] = $errors['criterio_s_3'] = $errors['criterio_s_4'] = get_string('err_criteria', 'mtcontabilita');
        }
        return $errors;
    }

    /**
     * add completion rules
     */
    public function add_completion_rules() {
        $mform =& $this->_form;

        $suffix = $this->get_suffix();
        $completionsubmitel = 'completionsubmit' . $suffix;
        $mform->addElement('checkbox',
            $completionsubmitel,
            '',
            get_string('completionsubmit', 'mtcontabilita')
        );
        // Enable this completion rule by default.
        $mform->setDefault($completionsubmitel, 1);
        return [$completionsubmitel];
    }

    /**
     * rule enabled
     */
    public function completion_rule_enabled($data) {
        $suffix = $this->get_suffix();
        return !empty($data['completionsubmit' . $suffix]);
    }

    /**
     * after data
     */
    public function definition_after_data() {
        global $DB;

        parent::definition_after_data();

        $mform = $this->_form;

        // Se sto creando una nuova attività, non blocco nulla.
        $instanceid = !empty($this->current->instance) ? (int)$this->current->instance : 0;
        if ($instanceid <= 0) {
            return;
        }

        // Se esiste almeno un tentativo "iniziato" (record presente), blocca campi.
        // Se vuoi essere più restrittivo, aggiungi condizioni tipo timestart > 0 o state != '...'.
        $hasattempts = $DB->record_exists('mtcontabilita_attempts', ['mtcontabilitaid' => $instanceid]);

        if ($hasattempts) {
            // Campi da bloccare:
            $lockfields = ['type', 'slang', 'binit', 'bdecimali'];

            foreach ($lockfields as $f) {
                if ($mform->elementExists($f)) {
                    $mform->freeze($f);
                }
            }

            // (Opzionale) messaggio informativo nel form.
            if (!$mform->elementExists('lockinfo')) {
                $mform->addElement(
                    'static',
                    'lockinfo',
                    '',
                    html_writer::div(
                        get_string('someattemptsstarted_lockfields', 'mtcontabilita'),
                        'alert alert-warning'
                    )
                );
            }
        }
    }
}
