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

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

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

/**
 * Generic one-student results grid: a niveau select + a comment box per
 * competency. Reused as-is by the eval/stage/CAPP screens (phases 3-5) —
 * only the customdata (competencies, niveaux, existing results, and
 * whether the comment column is read-only feedback vs an editable plugin
 * comment) changes per domain.
 */
class local_kid_entry_grid_form extends moodleform {

    protected function definition() {
        $mform = $this->_form;

        $mform->addElement('hidden', 'entryid');
        $mform->setType('entryid', PARAM_INT);

        // Optimistic-conflict detection (entry_conflict_service) + the
        // navigation-guard's "Enregistrer et continuer": expectedtimemodified
        // is the entry's timemodified as of this render (compared against
        // the DB's current value before writing); returnurl defaults to the
        // current page and is overwritten by amd/src/unsaved_guard.js right
        // before a guarded submit, so a successful save can redirect
        // straight to the student the user was navigating to instead of
        // always reloading the one just saved.
        $mform->addElement('hidden', 'expectedtimemodified');
        $mform->setType('expectedtimemodified', PARAM_INT);
        $mform->addElement('hidden', 'returnurl');
        $mform->setType('returnurl', PARAM_LOCALURL);

        $competencies = $this->_customdata['competencies'];
        $niveaux = $this->_customdata['niveaux'];
        $results = $this->_customdata['results'];
        // Read-only history entry point (comment_history_service) — optional
        // customdata so screens that don't pass it (there are none today,
        // but keeps this form usable standalone) simply render no link.
        $commenthistory = $this->_customdata['commenthistory'] ?? [];
        $historycontext = $this->_customdata['historycontext'] ?? '';

        $niveauoptions = [0 => get_string('niveau_none', 'local_kid')];
        foreach ($niveaux as $niveau) {
            $niveauoptions[$niveau->id] = $niveau->libelle;
        }

        foreach ($competencies as $competency) {
            $mform->addElement('header', 'comp_' . $competency->id, \local_kid\local\competency_repository::label($competency));

            $existing = $results[$competency->id] ?? null;

            $mform->addElement('select', "results[{$competency->id}][niveauid]", get_string('niveau_libelle', 'local_kid'), $niveauoptions);

            // Read-only badge mirroring the currently saved niveau, since a
            // native <select>/<option> can't carry the level's colour —
            // shown next to the (still editable) select, using the same
            // niveau_repository::badge_class() as every other on-screen
            // niveau label. Also visible when the form is hardFrozen
            // (readonly customdata) since static elements always render
            // their content regardless of freeze state.
            $currentniveau = ($existing && !empty($existing->niveauid)) ? ($niveaux[$existing->niveauid] ?? null) : null;
            if ($currentniveau) {
                $badgehtml = \html_writer::tag('span', s($currentniveau->libelle), [
                    'class' => 'fr-badge kid-level-badge ' . \local_kid\local\niveau_repository::badge_class($currentniveau->code),
                ]);
                $mform->addElement('static', "niveaubadge_{$competency->id}", get_string('entry_current_niveau', 'local_kid'), $badgehtml);
            }

            $mform->addElement('textarea', "results[{$competency->id}][commentaire]", get_string('entry_comment', 'local_kid'), ['rows' => 2, 'cols' => 60]);

            // Echoes the commentaire's value as of this render, invisible to
            // the user — entry_conflict_service's 3-way compare (original vs
            // submitted vs fresh DB) needs it to tell "the user edited this"
            // apart from "this field was merely re-submitted unchanged".
            $mform->addElement('hidden', "results[{$competency->id}][origcommentaire]");
            $mform->setType("results[{$competency->id}][origcommentaire]", PARAM_RAW);

            $versions = $commenthistory[$competency->id] ?? [];
            if ($versions) {
                $linkhtml = \local_kid\local\comment_history_service::render_link($versions,
                    $historycontext . ' · ' . \local_kid\local\competency_repository::label($competency));
                $mform->addElement('static', "historylink_{$competency->id}", '', $linkhtml);
            }

            if ($existing) {
                $mform->setDefault("results[{$competency->id}][niveauid]", $existing->niveauid ?: 0);
                $mform->setDefault("results[{$competency->id}][commentaire]", $existing->commentaire ?? '');
                $mform->setDefault("results[{$competency->id}][origcommentaire]", $existing->commentaire ?? '');
            } else {
                $mform->setDefault("results[{$competency->id}][origcommentaire]", '');
            }
        }

        // Single entry-level comment, shown once after every competency —
        // opt-in via customdata so the eval screen (same shared form) never
        // gets it. Never repeated per competency, never merged with the
        // per-competency commentaire above.
        if (!empty($this->_customdata['showglobalcomment'])) {
            $mform->addElement('header', 'globalcommentheader', get_string('stage_commentaire_global', 'local_kid'));
            $mform->setExpanded('globalcommentheader', true);
            $mform->addElement('textarea', 'commentaireglobal', get_string('stage_commentaire_global', 'local_kid'), ['rows' => 5, 'cols' => 60]);
            $mform->setType('commentaireglobal', PARAM_TEXT);
            $mform->addElement('hidden', 'origcommentaireglobal');
            $mform->setType('origcommentaireglobal', PARAM_RAW);
        }

        if (!empty($this->_customdata['readonly'])) {
            $mform->hardFreezeAllVisibleExcept([]);
        } else {
            $this->add_action_buttons(true, get_string('action_save', 'local_kid'));
        }
    }
}
