define([
    'app',
    'js/templates-loader'
],

    function (app, T ) {

        var Screen = {
            Models: {}, Views: {}, Collections: {},
        };

        function formatDatetimeLocal(d) {
            var pad = function (n) { return (n < 10 ? '0' : '') + n; };
            return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate()) + 'T' + pad(d.getHours()) + ':' + pad(d.getMinutes());
        }

        Screen.Models.AssignCoverModal = Backbone.Epoxy.Model.extend({
            defaults: {
                covers: null,
                coverId: 1,
                HeatNumber: "",
                assignStart: "",  // alias used by some templates/bindings (e.g. value:assignStart)
                action: 'A',
                heats: null,
                startDatetime: null,  // optional Start date/time for Assign; when set, sent as @Started to UpdateCoverHeat
                outOfCoverAlertHours: null,
                outOfCoverAlertOptions: [
                    { value: null, label: 'None' },
                    { value: 24, label: '24h' },
                    { value: 48, label: '48h' },
                    { value: 72, label: '72h' }
                ],
            },
            initialize: function () {
                this.fetchAvailableCoversAndHeats();
            },
            fetchAvailableCoversAndHeats: function () {
                var self = this;
                var covers = [];
                var heats = [];
                var qp = new Core.Database.QueryParameters();
                Core.Json.CallProcedure(
                    app.DatabaseNames.MES + '.CAS.GetAvailableCovers',
                    qp,
                    {
                        onSuccess: function (resp) {
                            try {

                                if (resp.Table) {
                                    covers = resp.Table.map(item => {
                                        return {
                                            value: item.CoverId,
                                            label: 'Cover '+item.CoverId
                                        };
                                    });

                                    heats = resp.Table1.map(item => {
                                        return {
                                            value: item.HeatNumber,
                                            label: item.HeatNumber
                                        };
                                    });
                                    self.set('covers', covers);
                                    self.set('heats', heats);
                                    if (covers.length > 0 && self.get('coverId') == null) {
                                        self.set('coverId', covers[0].value);
                                    }
                                }
                                else {
                                    if ((resp) && (resp.Message)) {
                                        app.views.topMessages.showMessage(resp.Message, { stay: 5000, });
                                        console.error(resp.Message);
                                        self.set({
                                            hasData: false,
                                            isLoading: false,

                                        });

                                    }
                                    else {
                                        app.views.topMessages.showMessage("Server response not valid.", { stay: 5000, });
                                        console.error("Server response not valid.");
                                        self.set({
                                            hasData: false,
                                            isLoading: false,
                                        });
                                    }

                                }


                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        },
                        Async: false,
                        Secured: true,
                    },
                    app.ConnectionStrings.app
                );

                return {covers: covers, heats:heats };
            },
            fetchAvailableHeats: function () {
                var covers = [];
                var qp = new Core.Database.QueryParameters();
                Core.Json.CallProcedure(
                    app.DatabaseNames.MES + '.CAS.GetAvailableHeatsToCover',
                    qp,
                    {
                        onSuccess: function (resp) {
                            try {

                                if (resp.Table) {
                                    covers = resp.Table.map(item => {
                                        return {
                                            value: item.CoverId,
                                            label: 'Cover '+item.CoverId
                                        };
                                    });
                                }
                                else {
                                    if ((resp) && (resp.Message)) {
                                        app.views.topMessages.showMessage(resp.Message, { stay: 5000, });
                                        console.error(resp.Message);
                                        that.set({
                                            hasData: false,
                                            isLoading: false,

                                        });

                                    }
                                    else {
                                        app.views.topMessages.showMessage("Server response not valid.", { stay: 5000, });
                                        console.error("Server response not valid.");
                                        that.set({
                                            hasData: false,
                                            isLoading: false,
                                        });
                                    }

                                }


                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        },
                        Async: false,
                        Secured: true,
                    },
                    app.ConnectionStrings.app
                );

                return covers;
            },
            updateCoverHeat: function (params) {
                try {
                    var that = this;
                    qp = new Core.Database.QueryParameters();

                    this.fixedParameters = [
                        { Name: '@CoverId', Type: 'INT', Value: params.CoverId, },
                        { Name: '@HeatName', Type: 'VARCHAR', Value: params.HeatNumber, },
                        { Name: '@action', Type: 'VARCHAR', Value: params.action, },
                        { Name: '@OutOfCoverAlertHours', Type: 'INT', Value: params.OutOfCoverAlertHours != null ? params.OutOfCoverAlertHours : null, },
                        // The Started datetime-local control returns local time;
                        // the SP needs to know the user's timezone to convert
                        // to UTC for storage.
                        { Name: '@timeZoneCode', Type: 'CHAR', Value: app.models.user.get('timezoneCode'), },
                    ];
                    if (params.action === 'A' && params.Started != null && params.Started !== '') {
                        var startedVal = params.Started;
                        if (typeof startedVal === 'string' && startedVal.indexOf('T') !== -1) {
                            startedVal = startedVal.replace('T', ' ') + (startedVal.length <= 16 ? ':00' : '');
                        }
                        this.fixedParameters.push({ Name: '@Started', Type: 'DATETIME', Value: startedVal });
                    }
                    _.each(this.fixedParameters, function (qpParams) {
                        qp.Add(qpParams.Name, qpParams.Type, qpParams.Value);
                    });
                    Core.Json.CallProcedure(
                        app.DatabaseNames.MES + '.CAS.UpdateCoverHeat',
                        qp,
                        {
                            onSuccess: function (resp) {
                                try {
                                    if (resp && !resp.Message) {
                                        if (params.action === 'A') {
                                            app.views.topMessages.showMessage('Heat : ' + params.HeatNumber + ' assigned to Cover: ' + params.CoverId, { stay: 2000, });
                                        } else if (params.action === 'E') {
                                            app.views.topMessages.showMessage('Out of Cover Alert updated for Heat ' + params.HeatNumber, { stay: 2000, });
                                        } else {
                                            app.views.topMessages.showMessage('Unassigned Heat: ' + params.HeatNumber + ' from Cover: ' + params.CoverId, { stay: 2000, });
                                        }
                                    }
                                    else {
                                        if ((resp) && (resp.Message)) {
                                            app.views.topMessages.showMessage(resp.Message, { stay: 5000, });
                                            console.error(resp.Message);
                                        }
                                        else {
                                            app.views.topMessages.showMessage("Server response not valid.", { stay: 5000, });
                                            console.error("Server response not valid.");
                                        }
                                    }
                                }
                                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                            },
                            onFailure: function (resp) {
                                console.error(resp);
                            },
                            Secured: true,
                            Async: false,
                        },
                        app.ConnectionStrings.app
                    );
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
        });
        Screen.Views.AssignCoverModal = Backbone.Epoxy.View.extend({
            template: "modal-assign-cover",
            className: "modal hide fade",
            bindings: "data-bind",
            title: "Assing Cover To Heat",
            isCacheable: true,
            events: function () {
                return {
                    "click #acceptBtn": this.acceptBtn_click,
                    "click #cancelBtn": this.close,
                    "submit form": this.form_submit,
                    "keypress": this.modal_keypress,
                    "show.bs.modal": this.modal_show,
                    "shown.bs.modal": this.modal_shown,
                    "hidden.bs.modal": this.modal_hidden,
                    "click .close": this.close,
                };
            },
            container: null,
            disposed: false,
            isRendered: false,
            preventDispose: false,
            visible: false,
            row: [],
            grid: [],
            initialize: function (options) {
                _.extend(this, options);
                if (!this.model) {
                    this.model = new Screen.Models.AssignCoverModal();
                }

                const row = options.rowModel;

                this.bus = options.bus;

                if (options.data) {
                    var data = options.data;
                    this.model.set({
                        HeatNumber: data.HeatNumber,
                        action: data.action
                    });
                }
               
                this.parent = options.parent;
                this.bindEvents();
                var that = this;

                return this;
            },
            hide: function (preventDispose) {
                this.preventDispose = (preventDispose);

                this.$el.modal('hide');

            },
            render: function (container) {
                if (container)
                    this.container = container;

                var that = this;
                var customPath = '/app/components/modal-covers/';
                T.render.call(this, this.template, function (tmp) {
                    if (!that.i18n) that.i18n = {};
                    app.getI18NJed(that, that.template, function (i18nJED) {
                        that.i18n[that.template] = i18nJED;
                        that.$el.html(tmp(that.model.toJSON()));
                        that.applyBindings();

                        that.isRendered = true;

                        that.trigger("render");
                       
                    }, true, customPath);

                }, customPath, "assign_cover");

            },
            show: function () {
                if (!this.isRendered) {

                    this.render();
                }
                else {
                    this.$el.modal({
                        keyboard: true,
                        backdrop: 'both',
                    });
                }

                return this;
            },

            bindEvents: function () {
                var that = this;
                this.listenToOnce(that, "render", that.view_render);
                this.listenTo(that.model, 'edited', () => { that.bus.trigger("modalAcceptBtn") });


            },

            cancelBtn_click: function() {
                this.close();
            },

            close: function () {
                if (this.disposed == false) {
                    if (this.visible == true) {
                        this.hide();
                    }
                    else {
                        this.trigger('close');

                        this.remove();
                        this.unbind();

                        this.disposed = true;
                    }
                }
            },
            preRender: function () {
            },
            reRender: function () {
            },

            acceptBtn_click: function () {
                try {
                    var that = this;
                    var params = { HeatNumber: that.model.get('HeatNumber'), CoverId: that.model.get('coverId'), action: that.model.get("action"), Started: that.model.get('startDatetime') };
                    that.model.updateCoverHeat(params)

                    this.close();

                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
            form_submit: function (e) {
                try {
                    e.preventDefault();
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
            modal_hidden: function (e) {
                try {
                    this.visible = false;

                    if (!this.preventDispose)
                        this.close();
                    else
                        this.preventDispose = false;
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
            modal_show: function (e) {
                try {
                    this.visible = true;
                    if (this.model.get('action') === 'A' && !this.model.get('startDatetime')) {
                        this.model.set('startDatetime', formatDatetimeLocal(new Date()));
                    }
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
            modal_shown: function (e) {
                try {
                    this.$el.find(".autofocus").focus();
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
            view_render: function () {
                try {
                    this.show();
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
        });

        Screen.Views.AssignHeatCover = Backbone.Epoxy.View.extend({
            template: "modal-assign-cover",
            className: "modal hide fade",
            bindings: "data-bind",
            title: "Assing Heat To Cover",
            isCacheable: true,
            events: function () {
                return {
                    "click #acceptBtn": this.acceptBtn_click,
                    "click #cancelBtn": this.close,
                    "submit form": this.form_submit,
                    "keypress": this.modal_keypress,
                    "show.bs.modal": this.modal_show,
                    "shown.bs.modal": this.modal_shown,
                    "hidden.bs.modal": this.modal_hidden,
                    "click .close": this.close,
                };
            },
            container: null,
            disposed: false,
            isRendered: false,
            preventDispose: false,
            visible: false,
            row: [],
            grid: [],
            initialize: function (options) {
                _.extend(this, options);
                if (!this.model) {
                    this.model = new Screen.Models.AssignCoverModal();
                }

                const row = options.rowModel;

                this.bus = options.bus;

                if (options.data) {
                    var data = options.data;
                    var heatNum = data.HeatNumber || '';
                    this.model.set({
                        CoverNumber: data.CoverNumber,
                        HeatNumber: heatNum,
                        assignStart: heatNum,
                        action: data.action,
                        startDatetime: (data.action === 'A') ? formatDatetimeLocal(new Date()) : null
                    });
                }
               
                this.parent = options.parent;
                this.bindEvents();
                var that = this;

                return this;
            },
            hide: function (preventDispose) {
                this.preventDispose = (preventDispose);

                this.$el.modal('hide');

            },
            render: function (container) {
                if (container)
                    this.container = container;

                var that = this;
                var customPath = '/app/components/modal-covers/';
                T.render.call(this, this.template, function (tmp) {
                    if (!that.i18n) that.i18n = {};
                    app.getI18NJed(that, that.template, function (i18nJED) {
                        that.i18n[that.template] = i18nJED;
                        var json = that.model.toJSON();
                        if (json.HeatNumber && !json.assignStart) json.assignStart = json.HeatNumber;
                        that.$el.html(tmp(json));
                        that.applyBindings();

                        that.isRendered = true;

                        that.trigger("render");
                       
                    }, true, customPath);

                }, customPath, "assign_heat_cover");

            },
            show: function () {
                if (!this.isRendered) {

                    this.render();
                }
                else {
                    this.$el.modal({
                        keyboard: true,
                        backdrop: 'both',
                    });
                }

                return this;
            },

            bindEvents: function () {
                var that = this;
                this.listenToOnce(that, "render", that.view_render);
                this.listenTo(that.model, 'edited', () => { that.bus.trigger("modalAcceptBtn") });


            },

            cancelBtn_click: function() {
                this.close();
            },

            close: function () {
                if (this.disposed == false) {
                    if (this.visible == true) {
                        this.hide();
                    }
                    else {
                        this.trigger('close');

                        this.remove();
                        this.unbind();

                        this.disposed = true;
                    }
                }
            },
            preRender: function () {
            },
            reRender: function () {
            },

            acceptBtn_click: function () {
                try {
                    var that = this;
                    var heatNum = that.model.get('HeatNumber') || that.model.get('assignStart');
                    var coverId = that.model.get('coverId');
                    if (coverId == null || coverId === '' || isNaN(parseInt(coverId, 10))) {
                        app.views.topMessages.showMessage('Please select a cover.', { stay: 3000 });
                        return;
                    }
                    var rawAlert = that.model.get('outOfCoverAlertHours');
                    var outOfCoverAlertHours = (rawAlert === '' || rawAlert === null || rawAlert === undefined) ? null : (parseInt(rawAlert, 10) || null);
                    var params = {
                        HeatNumber: heatNum,
                        CoverId: parseInt(coverId, 10),
                        action: that.model.get("action"),
                        Started: that.model.get('startDatetime'),
                        OutOfCoverAlertHours: outOfCoverAlertHours
                    };
                    that.model.updateCoverHeat(params);

                    this.close();

                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
            form_submit: function (e) {
                try {
                    e.preventDefault();
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
            modal_hidden: function (e) {
                try {
                    this.visible = false;

                    if (!this.preventDispose)
                        this.close();
                    else
                        this.preventDispose = false;
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
            modal_show: function (e) {
                try {
                    this.visible = true;
                    if (this.model.get('action') === 'A' && !this.model.get('startDatetime')) {
                        this.model.set('startDatetime', formatDatetimeLocal(new Date()));
                    }
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
            modal_shown: function (e) {
                try {
                    this.$el.find(".autofocus").focus();
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
            view_render: function () {
                try {
                    this.show();
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
        });

        Screen.Views.UnassignCover = Backbone.Epoxy.View.extend({
            template: "modal-assign-cover",
            className: "modal hide fade",
            bindings: "data-bind",
            title: "Unassign Cover",
            isCacheable: true,
            events: function () {
                return {
                    "click #acceptBtn": this.acceptBtn_click,
                    "click #cancelBtn": this.close,
                    "submit form": this.form_submit,
                    "keypress": this.modal_keypress,
                    "show.bs.modal": this.modal_show,
                    "shown.bs.modal": this.modal_shown,
                    "hidden.bs.modal": this.modal_hidden,
                    "click .close": this.close,
                };
            },
            container: null,
            disposed: false,
            isRendered: false,
            preventDispose: false,
            visible: false,
            row: [],
            grid: [],
            initialize: function (options) {
                _.extend(this, options);
                if (!this.model) {
                    this.model = new Screen.Models.AssignCoverModal();
                }

                const row = options.rowModel;

                this.bus = options.bus;

                if (options.data) {
                    var data = options.data;
                    this.model.set({
                        CoverNumber: data.CoverNumber,
                        HeatNumber: data.HeatNumber,
                        action: data.action
                    });
                }
               
                this.parent = options.parent;
                this.bindEvents();
                var that = this;

                return this;
            },
            hide: function (preventDispose) {
                this.preventDispose = (preventDispose);

                this.$el.modal('hide');

            },
            render: function (container) {
                if (container)
                    this.container = container;

                var that = this;
                var customPath = '/app/components/modal-covers/';
                T.render.call(this, this.template, function (tmp) {
                    if (!that.i18n) that.i18n = {};
                    app.getI18NJed(that, that.template, function (i18nJED) {
                        that.i18n[that.template] = i18nJED;
                        that.$el.html(tmp(that.model.toJSON()));
                        that.applyBindings();

                        that.isRendered = true;

                        that.trigger("render");
                       
                    }, true, customPath);

                }, customPath, "unassign_cover");

            },
            show: function () {
                if (!this.isRendered) {

                    this.render();
                }
                else {
                    this.$el.modal({
                        keyboard: true,
                        backdrop: 'both',
                    });
                }

                return this;
            },

            bindEvents: function () {
                var that = this;
                this.listenToOnce(that, "render", that.view_render);
                this.listenTo(that.model, 'edited', () => { that.bus.trigger("modalAcceptBtn") });


            },

            cancelBtn_click: function() {
                this.close();
            },

            close: function () {
                if (this.disposed == false) {
                    if (this.visible == true) {
                        this.hide();
                    }
                    else {
                        this.trigger('close');

                        this.remove();
                        this.unbind();

                        this.disposed = true;
                    }
                }
            },
            preRender: function () {
            },
            reRender: function () {
            },

            acceptBtn_click: function () {
                try {
                    var that = this;
                    var params = { HeatNumber: that.model.get('HeatNumber'), CoverId: that.model.get('CoverNumber'), action: that.model.get("action"), Started: that.model.get('startDatetime') };
                    that.model.updateCoverHeat(params)

                    this.close();

                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
            form_submit: function (e) {
                try {
                    e.preventDefault();
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
            modal_hidden: function (e) {
                try {
                    this.visible = false;

                    if (!this.preventDispose)
                        this.close();
                    else
                        this.preventDispose = false;
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
            modal_show: function (e) {
                try {
                    this.visible = true;
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
            modal_shown: function (e) {
                try {
                    this.$el.find(".autofocus").focus();
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
            view_render: function () {
                try {
                    this.show();
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
        });

        Screen.Views.EditOutOfCoverAlert = Backbone.Epoxy.View.extend({
            template: "modal-assign-cover",
            className: "modal hide fade",
            bindings: "data-bind",
            title: "Edit Out of Cover Alert",
            isCacheable: true,
            events: function () {
                return {
                    "click #saveAlertBtn": this.saveAlertBtn_click,
                    "click #cancelBtn": this.close,
                    "click .close": this.close,
                    "hidden.bs.modal": this.modal_hidden,
                };
            },
            container: null,
            disposed: false,
            isRendered: false,
            visible: false,
            initialize: function (options) {
                _.extend(this, options);
                if (!this.model) {
                    this.model = new Screen.Models.AssignCoverModal();
                }
                if (options.data) {
                    var d = options.data;
                    this.model.set({
                        CoverNumber: d.CoverNumber,
                        HeatNumber: d.HeatNumber,
                        outOfCoverAlertHours: d.OutOfCoverAlertHours != null ? d.OutOfCoverAlertHours : null
                    });
                }
                this.parent = options.parent;
                this.bindEvents();
                return this;
            },
            hide: function () {
                this.$el.modal('hide');
            },
            render: function (container) {
                if (container) this.container = container;
                var that = this;
                var customPath = '/app/components/modal-covers/';
                T.render.call(this, this.template, function (tmp) {
                    if (!that.i18n) that.i18n = {};
                    app.getI18NJed(that, that.template, function (i18nJED) {
                        that.i18n[that.template] = i18nJED;
                        var json = that.model.toJSON();
                        that.$el.html(tmp(json));
                        that.applyBindings();
                        that.isRendered = true;
                        that.trigger("render");
                    }, true, customPath);
                }, customPath, "edit_out_of_cover_alert");
            },
            show: function () {
                if (!this.isRendered) {
                    this.render();
                } else {
                    this.$el.modal({ keyboard: true, backdrop: 'both' });
                }
                return this;
            },
            bindEvents: function () {
                var that = this;
                this.listenToOnce(this, "render", this.view_render);
            },
            view_render: function () {
                try {
                    this.$el.modal({ keyboard: true, backdrop: 'both' });
                    this.$el.modal('show');
                    this.visible = true;
                } catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
            saveAlertBtn_click: function () {
                try {
                    var that = this;
                    var rawAlert = that.model.get('outOfCoverAlertHours');
                    var outOfCoverAlertHours = (rawAlert === '' || rawAlert === null || rawAlert === undefined) ? null : (parseInt(rawAlert, 10) || null);
                    var params = {
                        HeatNumber: that.model.get('HeatNumber'),
                        CoverId: that.model.get('CoverNumber'),
                        action: 'E',
                        OutOfCoverAlertHours: outOfCoverAlertHours
                    };
                    that.model.updateCoverHeat(params);
                    this.trigger('close');
                    if (this.parent && _.isFunction(this.parent.refreshRt)) {
                        this.parent.refreshRt();
                    }
                    if (this.parent && _.isFunction(this.parent.refresh)) {
                        this.parent.refresh();
                    }
                    this.close();
                } catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
            close: function () {
                if (this.disposed === false) {
                    if (this.visible === true) {
                        this.$el.modal('hide');
                    }
                    this.trigger('close');
                    this.remove();
                    this.unbind();
                    this.disposed = true;
                }
            },
            modal_hidden: function () {
                try {
                    this.visible = false;
                    this.close();
                } catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
        });

        // Required, return the module for AMD compliance.
        return Screen;

    });