define([
  // Application variable, always include it to have access to app methods.
  'app',

  //templates-loader: this loads templates async.
  'js/templates-loader',
  'backgrid',
  'modules/modal2',
  'moment',
  'backgrid/moment-cell'

],
function (app, T, Backgrid, Modal, moment) {

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

    Screen.Models.Main = Backbone.Epoxy.Model.extend({
        defaults: {
            equipmentTypes: {},
            equipmentTypeId: null,

            hasData: false,
            isLoading: false,
        },
        initialize: function () {
            this.fetchEquipmentTypesPicker();
        },
        fetchEquipmentTypesPicker: function () {
            var that = this;
            var qp = new Core.Database.QueryParameters();
            Core.Json.CallProcedure(
                app.DatabaseNames.MES + '.EAF.GetEquipmentTypesPicker',
                qp,
                {
                    onSuccess: function (resp) {
                        try {

                            if ((resp) && (resp.Table)) {
                                var records = resp.Table,
                                    newColl;
                                newColl = _.map(records, function (obj) {
                                    return {
                                        label: obj.Name,
                                        value: obj.Id,
                                    }
                                });
                                that.set('equipmentTypes', newColl);
                            }
                            else {
                                if ((resp) && (resp.Message))
                                    console.error(resp.Message);
                                else
                                    console.error('Server response not valid.');
                            }
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    Secured: true,
                    Async: false,
                },
                app.ConnectionStrings.app
            );

            return this;
        },
        
    });

    Screen.Models.Item = Backbone.Epoxy.Model.extend({
        parse: function (obj) {
            var result = {
                EquipmentId: obj.EquipmentId,
                EquipmentName: obj.EquipmentName,
                EquipmentTypeId: obj.EquipmentTypeId,
                EquipmentTypeName: obj.EquipmentTypeName,
                Status: obj.Status,
                LocationId: obj.LocationId,
            };
            return result;
        }
    })

    Screen.Collections.Items = Backbone.Collection.extend({
        model: Screen.Models.Item,
       
        fetch: function (params) {
            var that = this;
            var qp = new Core.Database.QueryParameters();
            qp.Add('@EquipmentTypeId', 'INT', params.equipmentTypeId == 'all' ? null : params.equipmentTypeId );
            Core.Json.CallProcedure(
                app.DatabaseNames.MES + '.EAF.GetEquipmentsByType',
                qp,
                {
                    onSuccess: function (resp) {
                        try {

                            if ((resp) && (resp.Table)) {
                                var records = resp.Table,
                                    newColl;
                                newColl = _.map(records, that.model.prototype.parse);
                                that.set(newColl).trigger('fetch', that, resp);
                            }
                            else {
                                if ((resp) && (resp.Message))
                                    console.error(resp.Message);
                                else
                                    console.error('Server response not valid.');
                            }
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    Secured: true,
                    Async: false,
                },
                app.ConnectionStrings.app
            );

            return this;
        },

        upsertEquipment: function (params,equipmentTypeId) {
            var that = this;
            var qp = new Core.Database.QueryParameters();
            qp.Add('@EquipmentName', 'VARCHAR(MAX)', params.newEquipmentName);
            qp.Add('@EquipmentId', 'INT', params.equipmentId);
            qp.Add('@EquipmentTypeId', 'INT', equipmentTypeId);
            qp.Add('@NewEquipment', 'BIT', params.newEquipment);

            Core.Json.CallProcedure(
                app.DatabaseNames.MES + '.EAF.UpsertEquipment',
                qp,
                {
                    onSuccess: function (resp) {
                        try {

                            if (resp) {
                            }
                            else {
                                if ((resp) && (resp.Message)) {
                                    app.views.topMessages.showMessage(resp.Message, { stay: 5000, });
                                    console.error(resp.Message);
                                } else {
                                    app.views.topMessages.showMessage(resp.Message, { stay: 5000, });
                                    console.error(resp.Message);
                                }
                            }
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    Secured: true,
                    Async: false,
                },
                app.ConnectionStrings.app
            );

            return this;
        },

        removeEquipment: function (params) {
            var that = this;
            var qp = new Core.Database.QueryParameters();
            qp.Add('@EquipmentId', 'INT', params.EquipmentId);
            Core.Json.CallProcedure(
                app.DatabaseNames.MES + '.EAF.RemoveEquipment',
                qp,
                {
                    onSuccess: function (resp) {
                        try {

                            if ((resp)) {
                            }
                            else {
                                if ((resp) && (resp.Message)) {
                                    app.views.topMessages.showMessage(resp.Message, { stay: 5000, });
                                    console.error(resp.Message);
                                } else {
                                    app.views.topMessages.showMessage(resp.Message, { stay: 5000, });
                                    console.error(resp.Message);
                                }
                            }
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    Secured: true,
                    Async: false,
                },
                app.ConnectionStrings.app
            );

            return this;
        },

    })

    Screen.Views.Main = Backbone.Epoxy.View.extend({
        template: 'eaf-spares-catalog',
        id: 'eaf-spares-catalog',
        title: 'EAF Spares Catalog',
        events: function () {
            return {
                'click #refreshBtn': this.refreshBtn_click,
                'click #addEquipment': this.addEquipmentBtn_click,
            };
        },
        bindings: 'data-bind',

        initialize: function () {
            this.options.state = app.view_states.loading;
            this.options.onappend = (_.isFunction(this.options.onappend)) ? this.options.onappend : function () { };

            this.model = new Screen.Models.Main();
            this.items = new Screen.Collections.Items();

            this.bus = _.extend({}, Backbone.Events);
            this.bus.on("modalAcceptBtn", this.onModalAcceptBtn, this);
            this.bindEvents();
        },
        
        bindEvents: function () {
            this.listenTo(this.items, 'fetch', this.items_fetched);
        
        },

        render: function (container, urlParams) {
            var that = this;
            var thatContainer = (this.options.container) ? this.options.container : container;
            this.options.container = thatContainer;

            var customPath = '/app/custom-screens/' + this.template + '/';

            T.render.call(
                this,
                this.template,
                function (tmp) {
                    if (!that.options.i18n) that.options.i18n = {};

                    app.getI18NJed(
                        that,
                        that.template,
                        function (i18nJED) {
                            that.options.i18n[that.template] = i18nJED;
                            that.$el.html(tmp());
                            that.applyBindings();

                            that.$el.find('.input-date').datepicker();
                            var columns = [
                                {
                                    name: 'EquipmentName',
                                    label: app.translate(that, 'item_EquipmentName_col_label'),
                                    cell: Backgrid.StringCell.extend({
                                        className: 'string-cell align-center-cell',
                                    }),
                                    editable: false,
                                },
                                {
                                    name: 'EquipmentTypeName',
                                    label: app.translate(that, 'item_EquipmentTypeName_col_label'),
                                    cell: Backgrid.StringCell.extend({
                                        className: 'string-cell align-center-cell',
                                    }),
                                    editable: false,
                                },

                                {
                                    name: 'Status',
                                    label: app.translate(that, 'item_Status_col_label'),
                                    cell: Backgrid.StringCell.extend({
                                        className: 'string-cell align-center-cell',
                                    }),
                                    editable: false,
                                },
                                {
                                    name: 'Actions',
                                    label: '',
                                    editable: false,
                                    sortable: false,
                                    cell: Backgrid.Cell.extend({
                                        template: Handlebars.compile(that.$el.find('#actions_cell_template').html()),
                                        className: 'actions-cell five-percent',
                                        events: {
                                            'click .btn-cell-action': 'cellActionClick'
                                        },

                                        initialize: function () {
                                            Backgrid.Cell.prototype.initialize.apply(this, arguments);
                                           
                                        },
                                        render: function () {
                                            this.$el.html(this.template());

                                            this.$el.find('[data-toggle="tooltip"]').tooltip();
                                            this.delegateEvents();
                                            if (this.model.get('Status') != 'Available') {
                                                var btnRemove = this.$el.find('.btn-remove');
                                                btnRemove.addClass('hide');
                                            }
                                            return this;
                                        },
                                        cellActionClick: function (e) {
                                            try {
                                                var target = $(e.target);
                                                var actionData = target.closest('[data-cell-action]').data('cell-action');
                                               
                                                if (actionData) {
                                                    that.actionOnRow(this.model,actionData);
                                                }
                                            }
                                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                                        },
                                    }),
                                },

                            ];

                            var grid = new Backgrid.Grid({
                                className: 'backgrid table table-hover table-condensed production-table',
                                collection: that.items,
                                columns: columns,
                            });

                            //container.append(grid.render().el);
                            that.$el.find('.items-grid-container').append(grid.render().el);

                                                       
                            //appending view to the main container
                            that.append(thatContainer, that.$el);

                            var fixedParams = _.extend({}, urlParams);
                            that.model.set(fixedParams);

                            that.refresh(); 
                                                       
                        },
                        true,
                        customPath
                    );
                },
                customPath
            );
        },

        onModalAcceptBtn: function (params) {
            this.items.upsertEquipment(params, this.model.get('equipmentTypeId'));
            this.refresh();
        },
        addEquipmentBtn_click: function () {
            var that = this;
            var model = {
                newEquipment: true,
            };
            var modal = new Screen.Views.DelaysModal({
                row: model,
                equipmentTypes: that.model.get('equipmentTypes'),
                equipmentTypeId: that.model.get('equipmentTypeId'),
                bus: that.bus,
            });
            modal.show();
        },
        actionOnRow: function (model,action) {
            try {
                var that = this;
                switch (action) {
                    case 'DELETE':
                        modal = new Modal.Views.Main({
                            focusOk: false,
                            focusSelector: '#btn-cancel',
                            title: app.translate([this, app], "delete_item_modal_confirm_title"),
                            message: app.translate([this, app], "delete_item_modal_confirm_message"),
                            buttons_type: "CONTINUE-CANCEL",
                        });

                        this.listenToOnce(modal, "continue", function (modal) {
                            try {
                                that.items.removeEquipment(model.toJSON());
                                that.refresh();
                            }
                            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        });
                        modal.show();
                        break;
                    case 'EDIT_DETAILS':
                        var modal = new Screen.Views.DelaysModal({
                            row: model.toJSON(),
                            bus: that.bus,
                        });
                        modal.show();
                        break;
                }
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }

        },

        refresh: function () {
            this.model.set({
                isLoading: true,
                hasData: false,
            });
            params = this.model.toJSON();
            this.items.fetch(params);

        },
        UpdateURL: function () {
            try {
                var params = this.model.toJSON();
                app.router.navigate(
                    app.router.resolveURL(
                        app.router.currentModule,
                        _.extend(
                            {},
                            params,
                            {
                                furnaceCode: params.furnaceCode,
                            }
                        ),
                        false
                    ),
                    { trigger: false, }
                );
            }
            catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
        },

        refreshBtn_click: function (e) {
            this.UpdateURL();
            this.refresh();
        },

        items_fetched: function () {
            try {
                var that = this;
                setTimeout(
                    function () {
                        that.model.set({
                            hasData: (that.items.length > 0),
                            isLoading: false,
                        });

                    },
                    100
                );
            }
            catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
        },

        append: function (container, el) {
            el = (el != null && el != undefined) ? el : this.$el;

            if (this.options.state == app.view_states.loading
                || this.options.state == app.view_states.shown) {
                //appending view to the main container and set state to shown

                this.options.state = app.view_states.shown;
                container.append(el);

                this.options.onappend(this);
            }

            if (this.options.state == app.view_states.hidden) {
                //append and remain hidden
                container.append(el);
            }

            if (this.options.state == app.view_states.closed) {
                //return without appending.
                return;
            }
        },
        bindViewScopedEvents: function () {
            var that = this;
        },
        unbindViewScopedEvents: function () {

        },
        close: function () {
            this.options.state = app.view_states.closed;
            
            this.closeSubviews();
            this.remove();
            this.unbindViewScopedEvents();
            this.unbind();
        },
        closeSubviews: function () {
            _.each(this.subviews, function (sview) {
                sview.close();
            });
        },
        show: function () {
            this.options.state = app.view_states.shown;

            this.showSubviews();
            this.bindEvents();
            this.$el.show();
        },
        showSubviews: function () {
            _.each(this.subviews, function (sview) {
                sview.show();
            });
        },
        hide: function () {
            this.options.state = app.view_states.hidden;

            this.hideSubviews();

            this.$el.hide();
            this.unbind();
            this.stopListening();
        },
        hideSubviews: function () {
            _.each(this.subviews, function (sview) {
                sview.hide();
            });
        },
        preRender: function () {
            app.models.subnavbar.set("subnavbar", false);
        },
        reRender: function (urlParams) {
            try {
                this.refresh(viewParams);
            } catch (Error) { }
        },

    });

    Screen.Models.DelaysModalMain = Backbone.Epoxy.Model.extend({
        defaults: {
            title: '',
            errorMsg: '',
            processing: false,
            newEquipmentName: '',
            equipmentTypeName: '',
            equipmentTypeId: null,
            equipmentName: '',
            equipmentId: null,
            status: '',
            locationId: null,
            newEquipment: false,
        },
        computeds: {
            hasNewEquipment: {
                deps: ['newEquipment'],
                get: function (value) {
                    return value;
                }
            },
        },

    });

    Screen.Views.DelaysModal = Backbone.Epoxy.View.extend({
        template: "eaf-spares-catalog",
        id: "delays-modal",
        className: "modal modal-delays hide fade",
        bindings: "data-bind",
        isCacheable: true,
        events: function () {
            return {
                "click #acceptBtn": this.acceptBtn_click,
                "click #cancelBtn": this.cancelBtn_click,
                "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,
            };
        },

        container: null,
        disposed: false,
        isRendered: false,
        preventDispose: false,
        visible: false,

        initialize: function (options) {
            _.extend(this, options);
            if (!this.model) {
                this.model = new Screen.Models.DelaysModalMain();
            }

            var currentEquipmentTypesObj = _.findWhere(options.equipmentTypes, { value: parseInt(options.equipmentTypeId) });
            currentEquipmentLocationName = currentEquipmentTypesObj ? currentEquipmentTypesObj.label : ''; 
            this.model.set({
                equipmentTypeName: options.row.EquipmentTypeName,
                equipmentTypeId: options.equipmentTypeId,
                equipmentName: options.row.EquipmentName,
                equipmentId: options.row.EquipmentId,
                status: options.row.newEquipment ? 'Available' : options.row.Status,
                locationId: options.row.LocationId,
                newEquipment: options.row.newEquipment ? options.row.newEquipment : false,
                title: 'New Equipment:' + ' ' + currentEquipmentLocationName,
            });

            this.bus = options.bus;

            this.bindEvents();

            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/custom-screens/' + this.template + '/';
            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, "delays_declare_modal");

        },
        show: function () {
            if (!this.isRendered) {
                this.render();
            }
            else {
                this.$el.modal({
                    keyboard: true,
                    backdrop: 'both',
                });
            }

            return this;
        },

        bindEvents: function () {
            this.listenToOnce(this, "render", this.view_render);
        },

        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 () {
            app.models.subnavbar.set("dateControl", false);
        },
        reRender: function () {
        },

        acceptBtn_click: function (e) {
            try {
                var params = this.model.toJSON();
                this.bus.trigger("modalAcceptBtn",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); }
        },
       
    });


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