<?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 datalynxrule_eventnotification\form;

use datalynxrule_eventnotification\rule;
use html_writer;
use mod_datalynx\datalynx;
use mod_datalynx\form\rule_form as base_rule_form;
use stdClass;

/**
 * Event notification rule form
 *
 * @package    datalynxrule_eventnotification
 * @copyright  2026 Wunderbyte GmbH
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
class rule_form extends base_rule_form {
    /**
     * Definition of the rule settings form
     */
    public function rule_definition() {
        $br = html_writer::empty_tag('br');
        $mform = &$this->_form;

        // Message subject. When empty then use default subject in message.
        $mform->addElement('text', 'param6', get_string('asyncmessagesubject', 'backup'), ['size' => '64']);
        $mform->setType('param6', PARAM_TEXT);

        $mform->addElement(
            'select',
            'param8',
            get_string('emailtemplate', 'datalynxrule_eventnotification'),
            $this->get_email_template_menu()
        );
        $mform->addHelpButton('param8', 'emailtemplate', 'datalynxrule_eventnotification');

        $mform->addElement('header', 'settingshdr', get_string('settings'));

        // Sender.
        $options = [
                rule::FROM_AUTHOR => get_string('author', 'datalynx'),
                rule::FROM_CURRENT_USER => get_string('user')];
        $mform->addElement('select', 'param2', get_string('fromsender', 'moodle'), $options);

        // Recipient.
        $grp = [];
        $grp[] = &$mform->createElement('checkbox', 'author', null, get_string('author', 'datalynx'), ['size' => 1]);

        $options = ['multiple' => true];
        $grp[] = &$mform->createElement('static', '', '', "<br><h4 class=\"w-100 mt-3\">" . get_string('roles') . "</h4>");

        $grp[] = &$mform->createElement(
            'autocomplete',
            'roles',
            get_string('roles'),
            $this->dl->get_datalynx_permission_names(true),
            $options
        );
        $grp[] = &$mform->createElement('static', '', '', $br);

        $grp[] = &$mform->createElement(
            'static',
            '',
            '',
            "<br><h4 class=\"w-100 mt-3\">" . get_string('teammembers', 'datalynx') . "</h4>"
        );
        $grp[] = &$mform->createElement(
            'autocomplete',
            'teams',
            get_string('teams', 'datalynx'),
            $this->get_datalynx_team_fields(),
            $options
        );

        // Single userid can be selected.
        $grp[] = &$mform->createElement(
            'static',
            '',
            '',
            "<br><h4 class=\"w-100 mt-3\">" . get_string('otheruser', 'datalynx') . "</h4>"
        );
        $allusers = $this->get_allusers();
        $grp[] = $mform->createElement('autocomplete', 'specificuserid', get_string('otheruser', 'datalynx'), $allusers);

        $mform->addGroup($grp, 'recipientgrp', get_string('torecipient'), $br, false);

        // Link settings.
        $mform->addElement('header', 'settingshdr', get_string('linksettings', 'datalynx'));
        $mform->addElement('static', '', get_string('targetviewforroles', 'datalynx'));

        foreach ($this->dl->get_datalynx_permission_names(true) as $permissionid => $permissionname) {
            $views = $this->get_views_visible_to_datalynx_permission($permissionid);
            if (!empty($views)) {
                $mform->addElement('select', "param4[$permissionid]", $permissionname, $views);
            } else {
                $mform->addElement(
                    'static',
                    '',
                    $permissionname,
                    get_string('noviewsavailable', 'datalynx')
                );
            }
        }

        // Content to be included.
        $mform->addElement('header', 'message', get_string('messagecontent', 'datalynxrule_eventnotification'));
        $dlfields = $this->dl->get_fields();
        $fieldmenu = [];
        foreach ($dlfields as $fieldid => $field) {
            if ($field->type == 'text' || $field->type == 'editor' || $field->type == 'textarea') {
                $fieldmenu[$fieldid] = $field->field->name;
            }
        }
        $options = [
                'multiple' => true,
                'noselectionstring' => get_string('noselection', 'form'),
        ];
        $mform->addElement('autocomplete', 'param7', get_string('searcharea', 'search'), $fieldmenu, $options);
    }

    /**
     * Get all users in moodle instance for autocomplete list.
     *
     * @return array with userid -> firstname lastname.
     * @throws coding_exception
     */
    public function get_allusers(): array {
        global $DB;
        $tempusers = $DB->get_records('user', [], '', 'id, firstname, lastname');

        $allusers[0] = get_string('noselection', 'datalynx');
        foreach ($tempusers as $userdata) {
            // Remove empties to make list more usable.
            if ($userdata->lastname == '') {
                continue;
            }
            $allusers[$userdata->id] = "$userdata->firstname $userdata->lastname";
        }
        return $allusers;
    }

    /**
     * Definition after data
     */
    public function definition_after_data() {
        $mform = &$this->_form;
        $data = $this->get_submitted_data();

        foreach (array_keys($this->dl->get_datalynx_permission_names(true)) as $permissionid) {
            $views = $this->get_views_visible_to_datalynx_permission($permissionid);
            $defaultview = $this->dl->get_default_view_id();
            if (
                isset($data) && isset($data->param4[$permissionid]) && $defaultview &&
                    in_array($defaultview, array_keys($views))
            ) {
                $mform->setDefault("param4[$permissionid]", $defaultview);
            }
        }
    }

    /**
     * Get the visible to permissions for a view.
     *
     * @param int $permissionid
     * @return array
     */
    private function get_views_visible_to_datalynx_permission(int $permissionid): array {
        global $DB;
        if ($permissionid == datalynx::PERMISSION_ADMIN) {
            $sql = "SELECT id, name
                      FROM {datalynx_views}
                     WHERE dataid = :dataid
                       AND type <> :internaltype";
            return $DB->get_records_sql_menu($sql, ['dataid' => $this->dl->id(), 'internaltype' => datalynx::INTERNAL_VIEW_EMAIL]);
        } else {
            $sql = "SELECT id, name
                      FROM {datalynx_views}
                     WHERE dataid = :dataid
                       AND type <> :internaltype
                       AND visible & :permissionid <> 0";
            return $DB->get_records_sql_menu($sql, ['dataid' => $this->dl->id(), 'internaltype' => datalynx::INTERNAL_VIEW_EMAIL,
                    'permissionid' => $permissionid]);
        }
    }

    /**
     * Get the selectable email template views.
     *
     * @return array
     */
    private function get_email_template_menu(): array {
        $views = [0 => get_string('emailtemplatenone', 'datalynxrule_eventnotification')];
        foreach ($this->dl->get_all_views() as $view) {
            if ($view->type === datalynx::INTERNAL_VIEW_EMAIL) {
                $views[$view->id] = $view->name;
            }
        }

        if (count($views) > 1) {
            $templates = $views;
            unset($templates[0]);
            asort($templates);
            $views = [0 => get_string('emailtemplatenone', 'datalynxrule_eventnotification')] + $templates;
        }

        return $views;
    }

    /**
     * Get team member select fields
     *
     * @return array
     */
    protected function get_datalynx_team_fields() {
        global $DB;
        $sql = "SELECT id, name
                  FROM {datalynx_fields}
                 WHERE dataid = :dataid
                   AND " . $DB->sql_like('type', ':type');
        $params = ['dataid' => $this->dl->id(), 'type' => 'teammemberselect'];
        return $DB->get_records_sql_menu($sql, $params);
    }

    /**
     * Get roles used in context
     *
     * @return array
     */
    protected function menu_roles_used_in_context(): array {
        $roles = [];
        foreach (get_roles_used_in_context($this->dl->context) as $roleid => $role) {
            $roles[$roleid] = $role->coursealias ? $role->coursealias : ($role->name ? $role->name : $role->shortname);
        }
        return $roles;
    }

    /**
     * Set data for the form
     *
     * @param stdClass $data
     */
    public function set_data($data) {
        $recipients = [];
        if (!empty($data->param3)) {
            $unserialized = @unserialize($data->param3);
            $recipients = is_array($unserialized) ? $unserialized : [];
        }
        if (isset($recipients['author'])) {
            $data->author = $recipients['author'];
        }
        if (isset($recipients['roles'])) {
            $data->roles = $recipients['roles'];
        }
        if (isset($recipients['teams'])) {
            $data->teams = $recipients['teams'];
        }
        if (isset($recipients['specificuserid'])) {
            $data->specificuserid = $recipients['specificuserid'];
        }

        if (!empty($data->param4)) {
            $unserialized = @unserialize($data->param4);
            $data->param4 = is_array($unserialized) ? $unserialized : [];
        }
        if (!empty($data->param7)) {
            $decoded = json_decode($data->param7);
            $data->param7 = is_array($decoded) ? $decoded : [];
        } else {
            $data->param7 = [];
        }
        parent::set_data($data);
    }

    /**
     * Get data from the form
     *
     * @param bool $slashed
     * @return ?stdClass
     */
    public function get_data($slashed = true) {
        if ($data = parent::get_data($slashed)) {
            // Set recipient.
            $recipients = [];
            if (isset($data->author)) {
                $recipients['author'] = 1;
            }

            if (isset($data->roles)) {
                $recipients['roles'] = $data->roles;
            }

            if (isset($data->teams)) {
                $recipients['teams'] = $data->teams;
            }
            if (isset($data->specificuserid)) {
                $recipients['specificuserid'] = $data->specificuserid;
            }
            $data->param3 = serialize($recipients);
            $data->param4 = serialize(!empty($data->param4) && is_array($data->param4) ? $data->param4 : []);
            $data->param7 = json_encode(!empty($data->param7) && is_array($data->param7) ? $data->param7 : []);
        }
        return $data;
    }
}
