// This file is part of the mod_mtcontabilita plugin for 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/>.

/**
 * @package    mod
 * @subpackage mtcontabilita
 * @copyright  2024 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>
 */

define([
    'jquery',
    'core/ajax',
    'core/modal_events',
    'core/modal_factory',
    'core/notification',
    'core/str',
    'core_form/modalform',
    'core/event_dispatcher',
    'core_reportbuilder/local/events',
    'core_reportbuilder/local/selectors'],
function($, Ajax, ModalEvents, ModalFactory, Notification, Str, ModalForm, EventDispatcher, ReportEvents, ReportSelectors) {

    /**
     * List of selectors.
     */
    var SELECTORS = {
        SESSIONSLIST: '[data-region=mtcontabilita-sessions-list]',
        SIGNUP: "[data-action=signup]",
        JOINWAITLIST: "[data-action=joinwaitlist]",
        CANCELSIGNUP: "[data-action=cancelsignup]",
        ADD: "[data-action=addsession]",
        // ADDMULTIPLE: "[data-action=addmultiple]",
        EDIT: "[data-action=editsession]",
        DELETE: "[data-action=deletesession]",
        DUPLICATE: "[data-action=duplicatesession]",
    };

    /**
     * Reload report
     *
     * @param {$} node that triggered the action.
     */
    var reloadReport = function(node) {
        var report = node.closest(ReportSelectors.regions.report);

        EventDispatcher.dispatchEvent(ReportEvents.tableReload, {preservePagination: true}, report.get(0));
    };

    /**
     * Modal to add/edit single mtcontabilita.
     *
     * @param {jQuery} triggerElement
     * @param {Number} cmid
     * @param {Number} sessionid
     * @return {ModalForm} modal
     */
    var showmtcontabilitaModal = function(triggerElement, cmid, sessionid) {
        var title = Str.get_string('mtitemadd', 'mod_mtcontabilita');
        if (sessionid > 0) {
            title = Str.get_string('mtitemupdate', 'mod_mtcontabilita');
        }
        var modal = new ModalForm({
            formClass: 'mod_mtcontabilita\\form\\mtitem',
            args: {cmid: cmid, sessionid: sessionid},
            modalConfig: {title: title},
            saveButtonText: Str.get_string('save'),
            returnFocus: triggerElement[0],
        });
        modal.show();
        $(document).on(ModalEvents.bodyRendered, function() {
            $('.modal-body input:not([type=submit])').on('keydown', function(ev) {
                if (ev.key == 'Enter') {
                    ev.preventDefault();
                    ev.stopPropagation();
                    $('.modal-footer button[data-action=save]').click();
                }
            });
        });
        return modal;
    };

    /**
     * Modal to duplicate single mtcontabilita.
     *
     * @param {jQuery} triggerElement
     * @param {Number} cmid
     * @param {Number} sessionid
     * @return {ModalForm} modal
     */
    var showmtcontabilitaDuplicateModal = function(triggerElement, cmid, sessionid) {
        var modal = new ModalForm({
            formClass: 'mod_mtcontabilita\\form\\duplicate',
            args: {cmid: cmid, sessionid: sessionid},
            modalConfig: {title: Str.get_string('duplicatemtcontabilita', 'mod_mtcontabilita')},
            saveButtonText: Str.get_string('duplicate', 'mod_mtcontabilita'),
            returnFocus: triggerElement[0],
        });
        modal.show();
        return modal;
    };

    // var showMultipleModal = function(triggerElement, cmid) {
    //     var modal = new ModalForm({
    //         formClass: 'mod_mtcontabilita\\form\\multiple',
    //         args: {cmid: cmid},
    //         modalConfig: {title: Str.get_string('addingmtcontabilitas', 'mod_mtcontabilita')},
    //         saveButtonText: Str.get_string('save'),
    //         returnFocus: triggerElement[0],
    //     });
    //     modal.show();
    //     return modal;
    // };

    /**
     * Modal to sign up to an mtcontabilita.
     *
     * @param {jQuery} triggerElement
     * @param {Number} sessionid
     * @return {ModalForm} modal
     */
    var showSignupModal = function(triggerElement, sessionid) {
        var modal = new ModalForm({
            formClass: 'mod_mtcontabilita\\form\\signup',
            args: {sessionid: sessionid},
            modalConfig: {title: Str.get_string('description', 'mod_mtcontabilita')},
            saveButtonText: Str.get_string('book', 'mod_mtcontabilita'),
            returnFocus: triggerElement[0],
        });
        modal.show();
        return modal;
    };

    /**
     * Button to sign up to an mtcontabilita.
     *
     * @param {jQuery} triggerElement
     * @param {Number} sessionid
     */
    var signupToSession = function(triggerElement, sessionid) {
        triggerElement.attr('disabled', 'disabled');
        var requests = Ajax.call([
            {methodname: 'mod_mtcontabilita_user_signup', args: {sessionid: sessionid}}
        ]);
        requests[0].then(function() {
            reloadReport(triggerElement);
            return null;
        }).fail(Notification.exception);
    };

    /**
     * Modal to join waitlist for an mtcontabilita.
     * Essentially this is signup but with different action title.
     *
     * @param {jQuery} triggerElement
     * @param {Number} sessionid
     * @return {ModalForm} modal
     */
    var showJoinWaitlistModal = function(triggerElement, sessionid) {
        var modal = new ModalForm({
            formClass: 'mod_mtcontabilita\\form\\signup',
            args: {sessionid: sessionid},
            modalConfig: {title: Str.get_string('description', 'mod_mtcontabilita')},
            saveButtonText: Str.get_string('joinwaitlist', 'mod_mtcontabilita'),
            returnFocus: triggerElement[0],
        });
        modal.show();
        return modal;
    };

    /**
     * Modal to cancel sign up to an mtcontabilita.
     *
     * @param {jQuery} triggerElement
     * @param {Number} sessionid
     * @return {ModalForm} modal
     */
    var showCancelSignupModal = function(triggerElement, sessionid) {
        var modal = new ModalForm({
            formClass: 'mod_mtcontabilita\\form\\cancelsignup',
            args: {sessionid: sessionid},
            modalConfig: {title: Str.get_string('cancelbooking', 'mod_mtcontabilita')},
            saveButtonText: Str.get_string('confirmcancelbooking', 'mod_mtcontabilita'),
            returnFocus: triggerElement[0],
        });
        modal.show();
        modal.addEventListener(modal.events.LOADED, () => {
            var saveButton = modal.modal.getFooter().find('button[data-action="save"]');
            saveButton.removeClass('btn-primary').addClass('btn-danger');
        });
        return modal;
    };

    /**
     * Modal to show details of an mtcontabilita.
     *
     * @param {jQuery} triggerElement
     * @param {Number} sessionid
     * @return {ModalForm} modal
     */
    var showDetailsModal = function(triggerElement, sessionid) {

        var body = Ajax.call([{
            methodname: 'mod_mtcontabilita_get_session_description',
            args: {sessionid: sessionid}
        }])[0]
        .then(function(data) {
            return data;
        }).fail(Notification.exception);

        return ModalFactory.create({
            type: ModalFactory.types.CANCEL,
            title: Str.get_string('description', 'mod_mtcontabilita'),
            buttons: {cancel: Str.get_string('closebuttontitle', 'moodle')},
            body: body,
            removeOnClose: true,
        }).done((modal) => {
            modal.setLarge();
            modal.getRoot().on(ModalEvents.hidden, () => triggerElement.focus());
            modal.show();
            return modal;
        }).fail(Notification.exception);
    };

    /**
     * Delete mtcontabilita.
     *
     * @param {Number} sessionid
     * @param {jQuery} triggerElement
     */
    var deletemtcontabilita = function(sessionid, triggerElement) {
        Str.get_strings([
            {key: 'confirm', component: 'moodle'},
            {key: 'deletemtcontabilitaconfirm', component: 'mod_mtcontabilita'},
            {key: 'delete', component: 'moodle'},
            {key: 'cancel', component: 'moodle'}
        ]).done(function(s) {
            Notification.confirm(s[0], s[1], s[2], s[3], function() {
                var requests = Ajax.call([
                    {methodname: 'mod_mtcontabilita_delete_session', args: {sessionid: sessionid}}
                ]);
                requests[0].then(function() {
                    reloadReport(triggerElement);
                    return null;
                }).fail(Notification.exception);
            });
            return null;
        }).fail(Notification.exception);
    };

    return /** @alias module:mod_mtcontabilita/sessions_list */ {

        /**
         * Initialise the page.
         */
        init: function() {
            M.util.js_pending('mod_mtcontabilita_sessions_list_init');
            $(SELECTORS.ADD).on('click', function(e) {
                e.preventDefault();
                var cmid = $(e.currentTarget).data('cmid');
                var modal = showmtcontabilitaModal($(e.currentTarget), cmid, 0);
                modal.addEventListener(modal.events.FORM_SUBMITTED, () => {
                    reloadReport($(ReportSelectors.regions.report));
                });
            });
            // $(SELECTORS.ADDMULTIPLE).on('click', function(e) {
            //     e.preventDefault();
            //     var cmid = $(e.currentTarget).data('cmid');
            //     var modal = showMultipleModal($(e.currentTarget), cmid);
            //     modal.addEventListener(modal.events.FORM_SUBMITTED, () => {
            //         reloadReport($(ReportSelectors.regions.report));
            //     });
            // });
            $(SELECTORS.SESSIONSLIST).on('click', SELECTORS.SIGNUP, function(e) {
                e.preventDefault();
                var id = $(e.currentTarget).data('id');
                signupToSession($(e.currentTarget), id);
            });
            $(SELECTORS.SESSIONSLIST).on('click', SELECTORS.JOINWAITLIST, function(e) {
                e.preventDefault();
                var id = $(e.currentTarget).data('id');
                var modal = showJoinWaitlistModal($(e.currentTarget), id);
                modal.addEventListener(modal.events.FORM_SUBMITTED, () => {
                    reloadReport($(e.currentTarget));
                });
            });
            $(SELECTORS.SESSIONSLIST).on('click', SELECTORS.CANCELSIGNUP, function(e) {
                e.preventDefault();
                var id = $(e.currentTarget).data('id');
                var modal = showCancelSignupModal($(e.currentTarget), id);
                modal.addEventListener(modal.events.FORM_SUBMITTED, () => {
                    reloadReport($(e.currentTarget));
                });
            });
            $(SELECTORS.SESSIONSLIST).on('click', SELECTORS.EDIT, function(e) {
                e.preventDefault();
                var cmid = $(SELECTORS.ADD).data('cmid');
                var id = $(e.currentTarget).data('id');
                var modal = showmtcontabilitaModal($(e.currentTarget), cmid, id);
                modal.addEventListener(modal.events.FORM_SUBMITTED, () => {
                    reloadReport($(e.currentTarget));
                });
            });
            $(SELECTORS.SESSIONSLIST).on('click', SELECTORS.DUPLICATE, function(e) {
                e.preventDefault();
                var cmid = $(SELECTORS.ADD).data('cmid');
                var id = $(e.currentTarget).data('id');
                var modal = showmtcontabilitaDuplicateModal($(e.currentTarget), cmid, id);
                modal.addEventListener(modal.events.FORM_SUBMITTED, () => {
                    reloadReport($(e.currentTarget));
                });
            });
            $(SELECTORS.SESSIONSLIST).on('click', SELECTORS.DELETE, function(e) {
                e.preventDefault();
                var id = $(e.currentTarget).data('id');
                deletemtcontabilita(id, $(e.currentTarget));
            });
            M.util.js_complete('mod_mtcontabilita_sessions_list_init');
        },
       /**
        * Open sign up modal on page load (used for accessing the page from the calendar).
        * If user already booked a session, show details instead.
        *
        * @param {Number} sessionid
        * @param {Boolean} cansignup Indicates if user can sign up
        */
        signup: function(sessionid, cansignup) {
            var reportContainer = $(ReportSelectors.regions.report);

            if (cansignup) {
                var modal = showSignupModal(reportContainer, sessionid);
                modal.addEventListener(modal.events.FORM_SUBMITTED, () => {
                    reloadReport(reportContainer);
                });
            } else {
                showDetailsModal(reportContainer, sessionid);
            }

            // Modify URL.
            var url = $(location).attr('href').replace(/&s=\d+$/g, '');
            window.history.replaceState(null, '', url);
        }
    };
});
