<?php
// This file is part of mod_datalynx for Moodle - http://moodle.org/
//
// It 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.
//
// It 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/>.

namespace mod_datalynx\form;

use coding_exception;
use mod_datalynx\local\rule\manager;
use moodleform;
use stdClass;

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

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

/**
 * Datalynx rule form base class.
 *
 * @package    mod_datalynx
 * @copyright  2025 Wunderbyte GmbH
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
class rule_form extends moodleform {
    /**
     * @var object
     */
    protected $rule = null;

    /**
     * @var \mod_datalynx\datalynx
     */
    protected $dl = null;

    /**
     * rule_form constructor.
     *
     * @param mixed $rule
     * @param mixed $action
     * @param mixed $customdata
     * @param string $method
     * @param string $target
     * @param mixed $attributes
     * @param bool $editable
     */
    public function __construct(
        $rule,
        $action = null,
        $customdata = null,
        $method = 'post',
        $target = '',
        $attributes = null,
        $editable = true
    ) {
        $this->rule = $rule;
        $this->dl = $this->rule->df;

        parent::__construct($action, $customdata, $method, $target, $attributes, $editable);
    }

    /**
     * Form definition
     *
     * @throws coding_exception
     */
    public function definition() {
        global $CFG;
        $mform = &$this->_form;

        // Buttons.
        $this->add_action_buttons();

        $mform->addElement('header', 'general', get_string('general', 'form'));

        // Name.
        $mform->addElement('text', 'name', get_string('name'), ['size' => '32']);
        $mform->addRule('name', null, 'required', null, 'client');

        // Description.
        $mform->addElement('text', 'description', get_string('description'), ['size' => '64']);
        if (!empty($CFG->formatstringstriptags)) {
            $mform->setType('name', PARAM_TEXT);
            $mform->setType('description', PARAM_TEXT);
        } else {
            $mform->setType('name', PARAM_RAW);
            $mform->setType('description', PARAM_RAW);
        }

        // Enabled.
        $mform->addElement(
            'advcheckbox',
            'enabled',
            get_string('ruleenabled', 'datalynx'),
            '',
            null,
            [0, 1]
        );

        // Events.
        $eventmenu = manager::get_event_data($this->dl->id());
        $eventgroup = [];
        foreach ($eventmenu as $eventname => $eventlabel) {
            $eventgroup[] = &$mform->createElement('checkbox', $eventname, null, $eventlabel, ['size' => 32]);
        }
        $mform->addGroup(
            $eventgroup,
            'eventsgroup',
            get_string('triggeringevent', 'datalynx'),
            '<br />',
            false
        );

        // If we have selected entry updated, add a new UI when the instance includes a checkbox.
        $checkboxes = $this->dl->get_fields_by_type('checkbox', true);
        $radiobuttons = $this->dl->get_fields_by_type('radiobutton', true);
        $choices = $radiobuttons + $checkboxes;
        if (!empty($choices)) {
            $choices = ['0' => get_string('noselection', 'datalynx')] + $choices;
            $mform->addElement(
                'select',
                'param5',
                get_string('triggerspecificevent', 'datalynxrule_eventnotification'),
                $choices
            );
            $attributes = ['size' => '5'];
            $mform->addElement(
                'text',
                'param10',
                get_string('condition', 'datalynxrule_eventnotification'),
                $attributes
            );
            $mform->setType('param10', PARAM_TEXT);
            $mform->addHelpButton('param10', 'condition', 'datalynxrule_eventnotification');
            $mform->disabledIf('param10', 'param5', 'eq', 0);
        }
        $this->rule_definition();
        // Buttons.
        $this->add_action_buttons();
    }

    /**
     * Data to form
     *
     * @param array|stdClass $data
     */
    public function set_data($data) {
        if (!empty($data->param1)) {
            $selectedevents = unserialize($data->param1);
            if ($selectedevents) {
                foreach ($selectedevents as $eventname) {
                    $data->$eventname = true;
                }
            }
        }
        parent::set_data($data);
    }

    /**
     * Get data
     *
     * @param bool $slashed
     * @return object
     * @throws coding_exception
     */
    public function get_data($slashed = true) {
        if ($data = parent::get_data($slashed)) {
            $eventmenu = manager::get_event_data($this->dl->id());
            $selectedevents = [];
            foreach (array_keys($eventmenu) as $eventname) {
                if (isset($data->$eventname)) {
                    $selectedevents[] = $eventname;
                }
            }
            $data->param1 = serialize($selectedevents);
        }
        return $data;
    }

    /**
     * Add action buttons
     *
     * @param bool $cancel
     * @param null $submit
     * @throws coding_exception
     */
    public function add_action_buttons($cancel = true, $submit = null) {
        $mform = &$this->_form;

        $buttonarray = [];
        // Save and display.
        $buttonarray[] = &$mform->createElement('submit', 'submitbutton', get_string('savechanges'));
        // Save and continue.
        $buttonarray[] = &$mform->createElement(
            'submit',
            'submitbutton',
            get_string('savecontinue', 'datalynx')
        );
        // Cancel.
        $buttonarray[] = &$mform->createElement('cancel');
        $mform->addGroup($buttonarray, 'buttonar', '', [' '], false);
        $mform->closeHeaderBefore('buttonar');
    }

    /**
     * Validate user data
     *
     * @param array $data
     * @param array $files
     * @return array
     * @throws coding_exception
     */
    public function validation($data, $files) {
        $errors = parent::validation($data, $files);

        if ($this->dl->name_exists('rules', $data['name'], $this->rule->get_id())) {
            $errors['name'] = get_string('invalidname', 'datalynx', get_string('rule', 'datalynx'));
        }

        return $errors;
    }
}
