//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',

    'chart',
    'moment',
    'chartjs-date-fns-adapter',

  'js/d3v4/d3.v4',

  'backgrid/moment-cell',
  'backgrid/grouped-columns',
  
  "js/jquery.floatThead/jquery.floatThead",
],
    function (app, T, Backgrid, ChartJS, moment, ChartJsDateFnsAdapter,d3) {

    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'),
            
            hasData: false,
            isLoading: false,

            casterCode: null,
            casters: [{ label: '1', value: '1' }, { label: '2', value: '2' }],
        },
        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: 'ladle-timing-report',
        id: 'ladle-timing-report',
        title: 'Ladle Timing Report',
        events: function () {
            return {
                'click #refreshBtn': this.refreshBtn_click,
                "click .btn-export-to-excel": this.exportToExcel,
            };
        },
        bindings: 'data-bind',
        bindingSources: null,
        grids: null,
        itemsColl: null,
        subviews: null,
        viewParams: null,
        chart: null,

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

            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();
        },
        bindEvents: function () {
            this.listenTo(this.itemsColl, 'fetch', this.processes_ready);

        },
        _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
                );
            }
        },
        refresh: function (viewParams) {

            var fixedParams = _.extend({}, Screen.Models.Main.prototype.defaults, viewParams);

            if (viewParams.start)
                fixedParams.start = new moment(fixedParams.start, 'YYYYMMDD').format('YYYY-MM-DD');
            if (viewParams.end)
                fixedParams.end = new moment(fixedParams.end, 'YYYYMMDD').format('YYYY-MM-DD');

            this.model.set(fixedParams);

            this._refresh({
                reset: true,
                params: _.extend(
                    {},
                    fixedParams,
                    {}
                ),
            });
        },
                
        
        render: function (container, viewParams) {
            var that = this;

            this.viewParams = viewParams;

            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/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) {
                            //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();
                            var grid = that.grids.production = new Backgrid.Grid({
                                className: 'backgrid table table-hover table-condensed production-table',
                                row: Backgrid.Row.extend({
                                    events: function () {
                                        return {
                                            'click': this.click,
                                        };
                                    },
                                    click: function (e) {
                                        try {
                                            this.model.trigger('backgrid:rowclick', this.model);
                                        }
                                        catch (Error) { console.error(Error.stack); }
                                    }
                                }),
                                columns: [
                                    {
                                        name: 'HeatName',
                                        label: app.translate([that, app], 'Heat'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell',
                                        }),
                                        editable: false,
                                    },
                                    {
                                        name: 'LadleNumber',
                                        label: app.translate([that, app], 'Ladle'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell',
                                        }),
                                        editable: false,
                                    },
                                    {
                                        name: 'Start',
                                        label: app.translate([that, app], 'Start'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell',
                                        }),
                                        editable: false,
                                    },
                                    {
                                        name: 'TapCar',
                                        label: app.translate([that, app], 'Tap Car'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell',
                                        }),
                                        editable: false,
                                    },
                                    {
                                        name: 'EAFTap',
                                        label: app.translate([that, app], 'EAF Tap'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell',
                                        }),
                                        editable: false,
                                    },
                                    {
                                        name: 'LDBay',
                                        label: app.translate([that, app], 'LD Bay'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell',
                                        }),
                                        editable: false,
                                    },
                                    {
                                        name: 'LMF',
                                        label: app.translate([that, app], 'LMF'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell',
                                        }),
                                        editable: false,
                                    },
                                    {
                                        name: 'Caster',
                                        label: app.translate([that, app], 'Caster'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell',
                                        }),
                                        editable: false,
                                    },
                                    {
                                        name: 'LDTap',
                                        label: app.translate([that, app], 'LD Tap'),
                                        cell: Backgrid.StringCell.extend({
                                            className: 'string-cell align-center-cell',
                                        }),
                                        editable: false,
                                    },
                                    //{
                                    //    name: 'End',
                                    //    label: app.translate([that, app], 'End'),
                                    //    cell: Backgrid.StringCell.extend({
                                    //        className: 'string-cell align-center-cell',
                                    //    }),
                                    //    editable: false,
                                    //},                                 
                                  
                                ],
                                collection: that.itemsColl,
                               
                            });

                            //container.append(grid.render().el);
                            that.$el.find('.processes-grid-container').append(grid.render().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');                         
                           
                            that.model.set(fixedParams);

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

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


                        },
                        true,
                        customPath
                    );
                },
                customPath
            );
        },
        
        buildChart: function (all) {    
            if (this.chart) {
                this.chart.destroy();
            };       

            var ctx = document.getElementById("myChart").getContext("2d");

            const colors = {
                green: {
                    fill: '#e0eadf',
                    stroke: '#5eb84d',
                },
                lightBlue: {
                    stroke: '#6fccdd',
                    fill:'#9dd2ea',
                },
                darkBlue: {
                    fill: '#92bed2',
                    stroke: '#3282bf',
                },
                purple: {
                    fill: '#8fa8c8',
                    stroke: '#75539e',
                },

                red: {
                    stroke: '#c4274c',
                    fill: '#de7d7d',
                },
            };

            const times = all.Table;


            const TapCar =  []; 
            const EAFTap =  []; 
            const LDBay =   []; 
            const LMF =     []; 
            const Caster =  []; 
            const HeatsArray = [];


            _.each(times, function (obj) {
                HeatsArray.push(obj.HeatName);
            });
            let time = {};

            for (let i = 0; i < HeatsArray.length; i++) {               
                time = _.where(times, { HeatName: HeatsArray[i] });

                if (time && time[0] && time[0].TapCar) TapCar.push(time[0].TapCar);
                else TapCar.push(0);

                if (time && time[0] && time[0].EAFTap) EAFTap.push(time[0].EAFTap);
                else EAFTap.push(0);


                if (time && time[0] && time[0].LDBay) LDBay.push(time[0].LDBay);
                else LDBay.push(0);

                if (time && time[0] && time[0].LMF) LMF.push(time[0].LMF);
                else LMF.push(0);

                if (time && time[0] && time[0].Caster) Caster.push(time[0].Caster);
                else Caster.push(0);
               
            }

        
            const data = {
                labels: HeatsArray,
                datasets: [
                    {
                        label: "Tap Car",
                        fill: true,
                        backgroundColor: colors.green.fill,
                        pointBackgroundColor: colors.green.stroke,
                        borderColor: colors.green.stroke,
                        pointHighlightStroke: colors.green.stroke,
                        data: TapCar,
                    },
                    {
                        label: "EAF Tap",
                        fill: true,
                        backgroundColor: colors.lightBlue.fill,
                        pointBackgroundColor: colors.lightBlue.stroke,
                        borderColor: colors.lightBlue.stroke,
                        pointHighlightStroke: colors.lightBlue.stroke,
                        borderCapStyle: 'butt',
                        data: EAFTap,
                    },
                    {
                        label: "LD Bay",
                        fill: true,
                        backgroundColor: colors.darkBlue.fill,
                        pointBackgroundColor: colors.darkBlue.stroke,
                        borderColor: colors.darkBlue.stroke,
                        pointHighlightStroke: colors.darkBlue.stroke,
                        borderCapStyle: 'butt',
                        data: LDBay,
                    },
                    {
                        label: "LMF",
                        fill: true,
                        backgroundColor: colors.purple.fill,
                        pointBackgroundColor: colors.purple.stroke,
                        borderColor: colors.purple.stroke,
                        pointHighlightStroke: colors.purple.stroke,
                        borderCapStyle: 'butt',
                        data: LMF,

                    }, 
                    {
                        label: "Caster",
                        fill: true,
                        backgroundColor: colors.red.fill,
                        pointBackgroundColor: colors.red.stroke,
                        borderColor: colors.red.stroke,
                        pointHighlightStroke: colors.red.stroke,
                        borderCapStyle: 'butt',
                        data: Caster,
                    },             
               
                ]
            };

            this.chart = new Chart(ctx, {
                type: 'line',
                data: data,
                options: {
                    responsive: true,
                    plugins: {
                        title: {
                            display: true,
                        },
                        tooltip: {
                            mode: 'index'
                        },
                    },
                    interaction: {
                        mode: 'nearest',
                        axis: 'x',
                        intersect: false
                    },
                    scales: {
                        x: {
                            title: {
                                display: true,
                                text: 'Heat'
                            }
                        },
                        y: {
                            stacked: true,
                            title: {
                                display: true,
                                text: 'Minutes'
                            }
                        }
                    },
                    animation: {
                        duration: 750,
                    },
                }
            });


            
        },

        processes_ready: function (all) {
            try {
                var that = this;
                setTimeout(
                    function () {
                        that.model.set({
                            hasData: (that.itemsColl.length > 0),
                            isLoading: false,
                        });                        
                        that.buildChart(all);
                    },
                    100
                );
            }
            catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
        },
        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);

       
            this.itemsColl.fetch({
                start: attrs.start,
                end: attrs.end,
                casterCode: attrs.casterCode,
                refresh: true,
            });





        },
        refreshBtn_click: function (e) {
            try {
                var params = this.model.toJSON();
                

            if (this.$el.find('#stacked_chart'))
                this.$el.find('#stacked_chart').html('');
                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'),                             
                            }
                        ),
                        false
                    ),
                    { trigger: false, }
                );

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

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

        exportToExcel: function () {
            var that = this,
                params = this.model.toJSON();

            var params = [
                { Name: '@start', Type: 'DATETIME', Value: params.start, },
                { Name: '@end', Type: 'DATETIME', Value: params.end, },
               
            ];
            var QP = new QueryParameters();

            _.each(params, function (qpParams) {
                QP.Add(qpParams.Name, qpParams.Type, qpParams.Value);
            });


            var data = {
                Data: [],
                ConnectionStringName: 'APP',
                ExportMethod: 3,
                FileName: 'Ladle Timing Report',
                TemplateFileFullPath: 'generic.xls',
                SQLDataSources: [
                    {
                        Name: 'data',
                        DatabaseParameters: {
                            DBEngine: 'SQLSERVER',
                            Procedure: app.DatabaseNames.MES + '.LAD.GetLadleTimingReport',
                            QueryParameters: QP,
                        },
                    },
                ]
            };
            
            
            
            
            
            
            
            
            
            
                              
        /* -------------------------------------------------------- 1st Table ------------------------------------------------------------ */
            data.Data.push({
                SheetName: 'Data',
                RowsData: [{
                    CellsData: 
                        [
                            { Column: 'A', Value: 'HeatName'},
                            { Column: 'B', Value: 'LadleNumber'},
                            { Column: 'C', Value: 'Start'},
                            { Column: 'D', Value: 'TapCar'},		
                            { Column: 'E', Value: 'EAFTap'},
                            { Column: 'F', Value: 'LDBay'},
                            { Column: 'G', Value: 'LMF'},
                            { Column: 'H', Value: 'Caster'},						
                            { Column: 'I', Value: 'LDTap'},			
                            { Column: 'J', Value: 'End'},	
                            
                        ],
                }],
                StartRowIndex: 1,
            });

            data.Data.push({
                SheetName: 'Data',
                RowsData: [],
                StartRowIndex: 2,
                DataSourceName: 'data',
                DataSourceTableIndex: 0,
                SQLCellsData: 
                    [
                        { ExcelColumnName: 'A', SQLDataColumnName: 'HeatName', DataType: 'String'},       
                        { ExcelColumnName: 'B', SQLDataColumnName: 'LadleNumber', DataType: 'String'},    
                        { ExcelColumnName: 'C', SQLDataColumnName: 'Start', DataType: 'String'},          
                        { ExcelColumnName: 'D', SQLDataColumnName: 'TapCar', DataType: 'String'},	      
                        { ExcelColumnName: 'E', SQLDataColumnName: 'EAFTap', DataType: 'String'},         
                        { ExcelColumnName: 'F', SQLDataColumnName: 'LDBay', DataType: 'String'},          
                        { ExcelColumnName: 'G', SQLDataColumnName: 'LMF', DataType: 'String'},            
                        { ExcelColumnName: 'H', SQLDataColumnName: 'Caster', DataType: 'String'},	      
                        { ExcelColumnName: 'I', SQLDataColumnName: 'LDTap', DataType: 'String'},		  
                        { ExcelColumnName: 'J', SQLDataColumnName: 'End', DataType: 'String'},	          
                    ],
            });
                       
            Core.Export.Excel(
                data,
                function (resp) {
                    try {
                        if ((resp) && (resp.Success == true) && (resp.Data)) {
                            location.href = app.foldersRoot + '/excel/' + resp.Data;
                            
                        }
                        else {
                            if ((resp) && (resp.Message))
                                console.error(resp.Message);
                            else
                                console.error('Server response not valid.');
                        }
                    }
                    catch (Error) { console.error(Error); }
                    that.model.setExportButtonExporting(false);
                },
                function (resp) {
                    that.model.refreshProcesses();
                    that.model.setExportButtonExporting(false);
                    console.error(resp);
                }
            );
        },
      
        //Common functions
        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 (viewParams) {
            try {
                this.refresh(viewParams);
            } catch (Error) { }
        },
    });

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

        fixedParameters: [],

        fetch: function (params) {
            var that = this,
                qp = new Core.Database.QueryParameters(),
                options = params ? _.clone(params) : {};
            if (options.refresh) {
                this.fixedParameters = [
                    { Name: '@Start', Type: 'DATETIME', Value: params.start, },
                    { Name: '@End', Type: 'DATETIME', Value: params.end, },
                    { Name: '@CasterCode', Type: 'INT', Value: params.casterCode ? parseInt(params.casterCode) : null, },                       
                    { Name: '@TimeZoneCode', Type: 'CHAR', Value: app.models.user.get('timezoneCode'), },
                ];
            }
            this.isFetching = true;
            _.each(this.fixedParameters, function (qpParams) {
                qp.Add(qpParams.Name, qpParams.Type, qpParams.Value);
            });

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

                            if ((resp) && (resp.Table)) {
                                //var newColl = _.map(resp.Table, that.model.prototype.parse);
                                newColl = resp.Table;
                                var method = (options.refresh) ? 'set' : 'add';

                                that[method](newColl);
                                that.trigger('fetch', resp);

                                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;
        },

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