//SCREEN-BOILERPLATE
//this boilerplate builds screens that are gonna be shown in the <div class='content'> tag of our main HTML.
//do not build app components with this boilerplate, only screens (reports)

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

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


    'modules/modal2',
    'modules/modal-sulpher-print/modal-sulpher-print',

    'components/ag-grid/ag-grid-module',
    'backgrid/infinator',
    'backgrid/moment-cell',
    'backgrid/grouped-columns',

    "js/jquery.floatThead/jquery.floatThead",
    'js/jquery.contextMenu/jquery.contextMenu'
],
    function (app, T, Backgrid, moment, Modal, SulpherPrintModal, AgGridModule) {

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

        Screen.Models.Main = Backbone.Epoxy.Model.extend({
            defaults: {
                start: new moment().subtract(2, 'days').format('YYYY-MM-DD'),
                end: new moment().format('YYYY-MM-DD'),

                furnaceCode: '-',
                furnaces: [{ label: '1', value: 1 }, { label: '2', value: 2 }],

                crewId: '-',
                crews: [{ label: 'A', value: 'A' }, { label: 'B', value: 'B' }, { label: 'C', value: 'C' }, { label: 'D', value: 'D' }],

                shiftId: '-',
                shifts: [{ label: 'D', value: 1 }, { label: 'N', value: 2 }],

                hasData: false,
                isLoading: false,
                isExcelExporting:false,
                grid: [],
                searchText: '',
                isPageLoading : false,
                renderCompleted: false,
            },
            computeds: {
                start$: {
                    deps: ['start'],
                    get: function (value) {
                        return value;
                    },
                    set: function (value) {
                        return { start: (value) ? new moment(value, app.translate(app, 'MM/DD/YYYY')).format('YYYY-MM-DD') : value, };
                    },
                },
                end$: {
                    deps: ['end'],
                    get: function (value) {
                        return value;
                    },
                    set: function (value) {
                        return { end: (value) ? new moment(value, app.translate(app, 'MM/DD/YYYY')).format('YYYY-MM-DD') : value, };
                    },
                },
            },
            
           
        });


        Screen.Views.Main = Backbone.Epoxy.View.extend({
            template: 'eaf-production',
            id: 'eaf-production',
            title: 'EAF Production Report',
            events: function () {
                return {
                    'click #refreshBtn': this.refreshBtn_click,
                    "click #exportExcelBtn": this.exportToExcel,
                    'click #calendarStartBtn': this.calendarStartBtn_click,
                    'click #calendarEndBtn': this.calendarEndBtn_click

                };
            },
            bindings: 'data-bind',
            bindingSources: null,
            grids: null,
            itemsColl: null,
            subviews: null,
            viewParams: null,
            columns : [
                { field: 'Heat', headerName: 'Heat', flex: 1, showFilter: true, width: 94, pinned:'left' },
                { field: 'Start', headerName: 'Start', flex: 1, showFilter: false, minWidth:115, fieldType: 'Datetime', format: 'MM/DD HH:mm'},
                { field: 'End', headerName: 'End', flex: 1, showFilter: false, minWidth:115, fieldType: 'Datetime', format: 'MM/DD HH:mm'},
                { field: 'Shift', headerName: 'Shift', flex: 1, minWidth:109, showFilter: true},
                { field: 'Crew', headerName: 'Crew', flex: 1, showFilter: true, minWidth: 109 },
                { field: 'FurnaceCode', headerName: 'EAF', flex: 1, minWidth:109, showFilter: true },
                { field: 'Ladle', headerName: 'Ladle', flex: 1, showFilter: false, minWidth: 70 },
                { field: 'Grade', headerName: 'Grade', flex: 1, showFilter: true, minWidth: 120 },
                { field: 'ScrapRecipe', headerName: 'Scrap Recipe', flex: 1, showFilter: false, minWidth: 142 },
                { field: 'Charges', headerName: 'Charges', flex: 1, showFilter: false, minWidth: 85, fieldType: 'Integer' },
                { field: 'ScrapWeight', headerName: 'Scrap Weight', flex: 1, showFilter: false, minWidth: 110, fieldType: 'Integer' },
                { field: 'SteelWeight', headerName: 'Steel Weight', flex: 1, showFilter: false, minWidth: 110, fieldType: 'Float', decimals: 1 },
                { field: 'HiCal', headerName: 'HiCal', flex: 1, showFilter: false, minWidth: 80, fieldType: 'Integer' },
                { field: 'Dolo', headerName: 'Dolo', flex: 1, showFilter: false, minWidth: 80, fieldType: 'Integer' },
                { field: 'Carbon', headerName: 'Carbon', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Integer' },
                { field: 'Yield', headerName: 'Yield', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Float', decimals: 1 },
                { field: 'PwrProg', headerName: 'Pwr Prog', flex: 1, showFilter: true, minWidth: 110 },
                { field: 'TTT', headerName: 'TTT', flex: 1, showFilter: false, minWidth: 85, fieldType: 'Seconds' },
                { field: 'On', headerName: 'On', flex: 1, showFilter: false, minWidth: 80, fieldType: 'Seconds' },
                { field: 'Off', headerName: 'Off', flex: 1, showFilter: false, minWidth: 80, fieldType: 'Seconds' },
                { field: 'MWH', headerName: 'MWH', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Float', decimals: 2 },
                { field: 'KWHtn', headerName: 'KWH/tn', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Float', decimals: 2 },
                { field: 'MWHmin', headerName: 'MWH/min', flex: 1, showFilter: false, minWidth: 120, fieldType: 'Float', decimals: 2 },
                { field: 'BurnP', headerName: 'Burn Prog', flex: 1, showFilter: true, minWidth: 120 },
                { field: 'NatGas', headerName: 'Nat Gas', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Integer' },
                { field: 'O2', headerName: 'O2', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Integer' },
                { field: 'O2SS', headerName: 'O2SS', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Integer' },
                { field: 'SouthInjectedCarbon', headerName: 'South Inj C', flex: 1, showFilter: false, minWidth: 110, fieldType: 'Integer' },
                { field: 'NorthInjectedCarbon', headerName: 'North Inj C', flex: 1, showFilter: false, minWidth: 110, fieldType: 'Integer' },
                { field: 'InjectedDolo', headerName: 'Dolo Inj', flex: 1, showFilter: false, minWidth: 110, fieldType: 'Integer' },
                { field: 'LastT', headerName: 'Last T', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Integer' },
                { field: 'LastO2', headerName: 'Last O2', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Integer' },
                { field: 'LastBathCeloxLvl', headerName: 'Celox Bath Lvl', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Float', decimals: 2 },
                { field: 'TotalProbes', headerName: 'Tot. Probes', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Integer' },
                { field: 'Argon', headerName: 'Argon', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Float', decimals: 1 },
                { field: 'CO2', headerName: 'CO2', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Float', decimals: 1 },
                { field: 'Ncc1', headerName: 'Ncc1', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Integer' },
                { field: 'Ncc2', headerName: 'Ncc2', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Integer' },
                { field: 'Ncc3', headerName: 'Ncc3', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Integer' },
                { field: 'CaveIn1', headerName: 'CaveIn1', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Integer' },
                { field: 'CaveIn2', headerName: 'CaveIn2', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Integer' },
                { field: 'CaveIn3', headerName: 'CaveIn3', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Integer' },
                { field: 'SlagIndex', headerName: 'Slag Index', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Integer' },
                { field: 'SlagWeight', headerName: 'Slag Weight', flex: 1, showFilter: false, minWidth: 110, fieldType: 'Float' ,decimals: 1},
                { field: 'PourbackHeatName', headerName: 'Pourback', flex: 1, showFilter: false, minWidth: 90 },
                { field: 'BypassBreakerUtilization', headerName: 'Bypass Util', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Integer' },
                { field: 'ConditionsBypassBreakerMaintained', headerName: 'Bypass Maint', flex: 1, showFilter: false, minWidth: 90, fieldType: 'Integer' },

              

            ],
            initialize: function () {
                this.options.state = app.view_states.loading;
                this.options.onappend = (_.isFunction(this.options.onappend)) ? this.options.onappend : function () { };
             
                // Init AgGridModule:
                this.agGridModule = new AgGridModule({
                    columnDefs: this.columns,
                    rowData: [],
                    onChange: this.handleGridChange.bind(this),
                    onRemove: this.handleGridRemove.bind(this),
                    fileName:'eaf-production'
                });


                var that = this;

                if (!this.model)
                    this.model = new Screen.Models.Main();

                this.grids = {};

                this.itemsColl = new Screen.Collections.Items();

                this.bindingSources = {};

                this.subviews = {};
                this.autoRefresh = {
                    enabled: null
                    , toid: null
                    , every: 5 * 1000
                };


                this.bindEvents();
                this.bus = _.extend({}, Backbone.Events);
                this.bus.on("modalAcceptBtn", this.onModalAcceptBtn, this);
            },

            handleGridChange: function (event) {
                // This function will be called when a cell value changes
                // You can update your model or perform any other actions here
            },

            handleGridRemove: function () {
                // This function will be called when the grid is being removed/destroyed
                // Perform any cleanup or additional actions here
            },
            calendarStartBtn_click: function () {
                $('#dateStartTbx').datepicker('show');
            },
            calendarEndBtn_click: function () {
                $('#dateEndTbx').datepicker('show');
            },

            onModalAcceptBtn: function () {
                this.refreshBtn_click();
            },
            bindEvents: function () {
                this.listenTo(this.itemsColl, 'backgrid:rowclick', this.processes_backgrid_rowclick)
                    .listenTo(this.itemsColl, 'fetch', this.processes_ready)
                    .listenTo(this.model, 'triggerFetch', this.refreshBtn_click);


            },
            removeHighlightRow: function () {
                var previousIndex = this.model.get('index');
                var rowsView = this.model.get('grid').body.rows;


                if (rowsView && rowsView[previousIndex] && rowsView[previousIndex].$el)
                    rowsView[previousIndex].$el.removeClass("onRightClickSelectedRow");


            },
            _refresh: function (opt) {
                this.itemsColl.reset();
                this.model.set({
                    hasData: false,
                    //isLoading: true,
                });

                if (this.autoRefresh.toid != null) {
                    clearTimeout(this.autoRefresh.toid);
                    this.autoRefresh.toid = null;
                }

                this.refreshProcesses(opt);

                if (this.autoRefresh.enabled == true) {
                    var that = this;

                    this.autoRefresh.toid = setTimeout(
                        function () { that._refresh(); },
                        this.autoRefresh.every
                    );
                }
            },
            render: function (container, viewParams) {
                var that = this;

                this.viewParams = viewParams;

                // Initialize the loading state
                that.model.set({isPageLoading:true});
                
                var thatContainer = (this.options.container) ? this.options.container : container;
                this.options.container = thatContainer;

                //the screens have a custompath, so it has to be specified in the customPath variable that is
                //then sent to the template loader.
                var customPath = '/app/pages/eaf/' + this.template + '/';

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

                        app.getI18NJed(
                            that,
                            that.template,
                            function (i18nJED) {
                                //storing internationalization data
                                that.options.i18n[that.template] = i18nJED;

                                //loading the view and appeding it to the views's $el.
                                that.$el.html(tmp());

                                that.applyBindings();

                                //start: the view was already loaded an is on a div element, but not appended to the main container
                                //here you can perform anything you want DOM related, by getting the dom element via that.$el.find('#id')
                                //or this.$('#id')

                                that.$el.find('.input-date').datepicker();                          

                                // Render the AgGridModule and append it to the container
                                that.agGridModule.render();
                                that.$el.find('.processes-grid-container').append(that.agGridModule.$el);

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

                                //Set model with view params here to prevent changes on the model when the view bindings are applied.
                                var fixedParams = _.extend({}, viewParams);
                                if (fixedParams.start)
                                    fixedParams.start = new moment(fixedParams.start, 'YYYYMMDD').format('YYYY-MM-DD');
                                if (fixedParams.end)
                                    fixedParams.end = new moment(fixedParams.end, 'YYYYMMDD').format('YYYY-MM-DD');
                                if (viewParams.furnaceCode)
                                    fixedParams.furnaceCode = (viewParams.furnaceCode != '-' && viewParams.furnaceCode != null) ? parseInt(viewParams.furnaceCode) : '-';
                                if (viewParams.crewId)
                                    fixedParams.crewId = (viewParams.crewId != '-' && viewParams.crewId != null) ? viewParams.crewId : '-';
                                if (viewParams.shiftId)
                                    fixedParams.shiftId = (viewParams.shiftId != '-' && viewParams.shiftId != null) ? parseInt(viewParams.shiftId) : '-';
                                if (viewParams.strandId)
                                    fixedParams.strandId = (viewParams.strandId != '-' && viewParams.strandId != null) ? parseInt(viewParams.strandId) : '-';
                           
                                
                                that.model.set(fixedParams);

                                //Call first refresh.
                                var params = that.model.toJSON();

                                that._refresh({
                                    reset: true,
                                    params: _.extend(
                                        {},
                                        params,
                                        {
                                        }
                                    ),
                                });

                                // Set loading state to false when everything is ready
                                that.model.set({isPageLoading:false});


                            },
                            true,
                            customPath
                        );
                    },
                    customPath
                );
            },
            processes_ready: function () {
                try {
                    var that = this;
                    const collectionData = that.itemsColl;
                    setTimeout(
                        function () {
                            that.agGridModule.setRowDataAsCollection(collectionData);
                            that.agGridModule.hideOverlay(); 
                            that.model.set({
                                hasData: (that.itemsColl.length > 0),
                                isLoading: false,
                            });                      
                        },
                        100
                    );
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
                     
            search_keypress: function (e) {
                if (e.keyCode === 13) {
                    $('#search').blur();
                    this.refreshBtn_click();
                }
            },
            refreshProcesses: function (options) {
                var that = this,
                    attrs = this.model.toJSON(),
                    opt = _.extend({}, options, { params: {}, });

                if ((opt.refresh == true) || (opt.reset == true)) {
                    this.model.set('isLoading', true);
                    that.agGridModule.showLoadingOverlay();  // Show loading overlay
                }
                
                this.itemsColl.fetch({
                    ...attrs,
                    refresh: true,
                });





            },
            refreshBtn_click: function (e) {
                try {
                    var params = this.model.toJSON();
                    app.router.navigate(
                        app.router.resolveURL(
                            app.router.currentModule,
                            _.extend(
                                {},
                                params,
                                {
                                    start: new moment(params.start, 'YYYY-MM-DD').format('YYYYMMDD'),
                                    end: new moment(params.end, 'YYYY-MM-DD').format('YYYYMMDD'),
                                    furnaceCode: (params.furnaceCode == null || params.furnaceCode == "") ? '-' : params.furnaceCode,
                                    crewId: (params.crewId == null || params.crewId == "") ? '-' : params.crewId,
                                    shiftId: (params.shiftId == null || params.shiftId == "") ? '-' : params.shiftId,
                                }
                            ),
                            false
                        ),
                        { trigger: false, }
                    );

                    this._refresh({
                        reset: true,
                        params: _.extend(
                            {},
                            params,
                            {}
                        ),
                    });

                    window.scrollTo(0, 0);
                }
                catch (Error) { console.error(Error.stack); }
            },

            //Common functions
            append: function (container, el) {
                var that = this;
                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);

                    setTimeout(function() {
                        that.model.set({renderCompleted: true});
                    }, 1000);  
                }

                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 (viewParams) {
                try {
                    this.refresh(viewParams);
                } catch (Error) { }
            },
        });

        Screen.Collections.Items = Backbone.Collection.extend({
            isFetching: false,
            currentPage: 1,
            pageSize: 100,

            fixedParameters: [],

            fetch: function (params) {
                var that = this,
                    qp = new Core.Database.QueryParameters(),
                    options = params ? _.clone(params) : {};

                if (options.refresh) {
                    this.resetPagination(true);
                    this.fixedParameters = [
                        { Name: '@Start', Type: 'DATETIME', Value: params.start, },
                        { Name: '@End', Type: 'DATETIME', Value: params.end, },
                        { Name: '@FurnaceCode', Type: 'INT', Value: params.furnaceCode != '-' ? params.furnaceCode : null, },
                        { Name: '@ShiftId', Type: 'INT', Value: params.shiftId != '-' ? params.shiftId : null },
                        { Name: '@CrewId', Type: 'CHAR', Value: params.crewId != '-' ? params.crewId : null },
                       
                    ];
                }
                this.isFetching = true;

                _.each(this.fixedParameters, function (qpParams) {
                    qp.Add(qpParams.Name, qpParams.Type, qpParams.Value);
                });


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

                                if ((resp) && (resp.Table)) {
                                    newColl = resp.Table;
                                    var method = (options.refresh) ? 'set' : 'add';
                                    that[method](newColl);
                                    that.trigger('fetch', that, newColl);

                                    if (newColl.length == 0 && method == 'add')
                                        that.currentPage--;

                                    that.isFetching = false;


                                }
                                else {
                                    if ((resp) && (resp.Message)) {
                                        console.error(new Error(resp.Message).stack);
                                        app.views.topMessages.showMessage('CALL TO DATABASE FAILED', { stay: 5000, });
                                    }
                                    else {
                                        app.views.topMessages.showMessage('SERVER RESPONSE NOT VALID', { stay: 5000, });
                                        console.error(new Error('SERVER_RESPONSE_NOT_VALID').stack);
                                    }
                                }
                            }
                            catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                        },
                        onFailure: function (resp) {
                            console.error(resp);
                        },
                        Secured: true,
                        Async: true,
                    },
                    app.ConnectionStrings.app
                );
                return this;
            },
            getNextPage: function (options) {
                if (!this.isFetching) {
                    this.currentPage++;
                    options = (_.isObject(options)) ? options : {};
                    this.fetch(options);
                }
            },
            resetPagination: function (force) {
                if (!this.isFetching || force == true) {
                    this.currentPage = 1;
                } else {
                    _.delay(this.resetPagination, 100);
                }
            },

        });

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