//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',
    'modules/navigation-buttons/navigation-buttons',
    'backgrid/moment-cell',
    'backgrid/grouped-columns',
    'js/multiselect/virtual-select.min',

],
    function (app, T, Backgrid, ChartJS, moment, ChartJsDateFnsAdapter, NavigationButton) {

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

    Screen.Models.Main = Backbone.Epoxy.Model.extend({
        defaults: {
            hasData: true,
            isLoading: false,
            
            heatId: null,
            direction: null,

            heatName: null,
            heatNames: [],
        },
        initialize: function () {
            this.itemsColl = new Screen.Collections.ItemsColl();
            this.mainInfoColl = new Screen.Collections.ItemsColl();           
        },
        fetchNavigateHeat: function (params) {
            var qp = new Core.Database.QueryParameters();
            var that = this;
            qp.Add('@heatName', 'VARCHAR(10)', that.get('heatName'));
            qp.Add('@direction', 'SMALLINT', params.direction);
            qp.Add('@Asset', 'CHAR(3)', 'EAF');

            Core.Json.CallProcedure(
                app.DatabaseNames.MES + '.MES.GetNavigatedHeat',
                qp,
                {
                    onSuccess: function (resp) {
                        try {
                            if (resp && resp.Table && resp.Table[0] && resp.Table[0].HeatName && resp.Table[0].HeatName !== '') {                    
                                that.set({
                                    heatName: resp.Table[0].HeatName,
                                    heatNames: [{
                                        value: resp.Table[0].HeatName,
                                        label: resp.Table[0].HeatName
                                    }],
                                });
                                that.trigger('heat-name-changed');
                            }
                            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); }
                    },
                    Secured: true,
                    Async: false,
                },
                app.ConnectionStrings.app
            );
        },
        fetchCatalogs: function () {
            var that = this;
            var qp = new Core.Database.QueryParameters();
            qp.Add('@HeatName', 'VARCHAR(10)', that.get('heatName'));
            qp.Add('@Asset', 'CHAR(3)', 'EAF');

            Core.Json.CallProcedure(
                app.DatabaseNames.MES + '.MES.GetAutocompleteHeats',
                qp,
                {
                    onSuccess: function (resp) {
                        try {
                            if (resp && resp.Table) {
                                that.set({
                                    heatNames: resp.Table,
                                    heatName: resp.Table[0] && resp.Table[0].value ? resp.Table[0].value : '',
                                });
                                that.trigger('catalogs-fetched');
                            }
                            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); }
                    },
                    Secured: true,
                    Async: false,
                },
                app.ConnectionStrings.app
            );
        },
        fetch: function (params) {
            var that = this;
            var qp = new Core.Database.QueryParameters();
            qp.Add('@heatName', 'VARCHAR', that.get('heatName'));
            qp.Add('@timeZoneCode', 'CHAR(10)', app.models.user.get('timezoneCode'));

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

                            if (resp && resp.Table) {           
                                that.itemsColl.setDataColl(resp.Table);
                                that.mainInfoColl.setDataColl(resp.Table1);
                                if (resp.Table2) that.trigger('fetch-nav-buttons', resp.Table2);
                                
                            }
                            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); }
                    },
                    Secured: true,
                },
                app.ConnectionStrings.app
            );

            return this;

        },
    });

    Screen.generateID = function (viewParams) {
        try {
            //if the viewparams change the view id, then evaluate the viewparams here
            //and return the appropiate id.refreshbtn
            return 'thermal-profile';
        } catch (Error) { }
    }

        Screen.Views.Main = Backbone.Epoxy.View.extend({
            template: 'thermal-profile',
            id: 'thermal-profile',
            title: 'Thermal Profile',
            isCacheable: false,
            events: function () {
                return {
                    'click #refreshBtn': this.refreshBtn_click,
                    'click #printBtn': this.printBtn_click,
                    'click #backNavBtn': this.heatNavigationBtn_click,
                    'click #forwardNavBtn': this.heatNavigationBtn_click,
                };
            },
            bindings: 'data-bind',
            subviews: null,
            viewParams: null,

            NavigationButtonView: null,

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

                var that = this;
                this.model = new Screen.Models.Main();

                this.NavigationButtonView = new NavigationButton.Views.Main();

             

                this.bindEvents();

            },
            bindEvents: function () {
                this.listenTo(this.model.mainInfoColl, 'fetch', this.process_fetched);
               
                this.listenTo(this.model, 'fetch-nav-buttons', this.fetchnavbuttons);              
                this.listenTo(this.model, 'heat-name-changed', this.heatNameChanged);
                this.listenTo(this.model, 'catalogs-fetched', this.catalogsFetched);
                this.listenTo(this.model, 'fetch-nav-buttons', this.fetchnavbuttons);

                this.listenTo(this.model, 'chart-data-ready', this.buildChart);
            },
            catalogsFetched: function () {
                this.UpdateURL();
            },

            fetchnavbuttons: function (resp) {
                this.NavigationButtonView.setDataColl(resp);
            },
            heatNameChanged: function () {
                const value = this.model.get('heatName');
                const options = this.model.get('heatNames');
                document.querySelector('#heat-picker-multi-select').setOptions(options);
                document.querySelector('#heat-picker-multi-select').setValue(value);
                this.UpdateURL();
                this.refresh();
            },
            printBtn_click: function () {
                window.print();
                return false;
            },
            heatNavigationBtn_click: function (e) {
                const { id } = e.target;
                const direction = id === 'backNavBtn' ? -1 : 1;
                this.model.fetchNavigateHeat({
                    direction
                });

            },

            buildChart: function (names, all) {
                var ctx = document.getElementById('ThermalProfileChart').getContext('2d');
                var datasets = [];
                var scales = {};
                var position = 'left';
                var radius = 1;
                var type = 'line';
                var pointStyle = 'circle';
                var displayLegend = true;
                var displayLegendByType = true;
                if (this.chart) {
                    this.chart.destroy();
                };
                _.each(names, function (obj, i) {
                    if (obj.isEvent == true) {
                        radius = 5
                        type = 'bubble';
                        displayLegendByType = false;
                        pointStyle = 'triangle';
                    }
                    else {
                        radius = 1;
                        type = 'line';
                        displayLegendByType = true;
                        pointStyle = 'circle';
                    }
                    displayLegend = names[i].ShowYAxis != null ? names[i].ShowYAxis : displayLegendByType;
                    datasets.push({
                        label: obj.Name,
                        data: _.where(all, { Name: obj.Name }),
                        fill: false,
                        yAxisID: 'y' + i,
                        borderColor: obj.Color,
                        backgroundColor: obj.FillColor,
                        tension: 0.1,
                        borderWidth: 1,
                        radius: radius,
                        type: type,
                        pointStyle: pointStyle,

                    })
                    //position = i % 2 == 0 ? 'left' : 'right';
                    position = names[i].YAxisPosition ? names[i].YAxisPosition.replaceAll(/\s/g, '') : 'left';
                    if (i === 0) {
                        scales['x'] = {
                            type: 'time',
                            ticks: {
                                maxTicksLimit: 16,
                                autoSkip: true,
                                maxRotation: 0,
                                minRotation: 0
                            },
                        };
                        scales['y' + i] = {
                            type: 'linear',
                            position: position,
                            min: names[i].MinValue,
                            max: names[i].MaxValue,
                            display: true,
                            ticks: {
                                color: names[i].Color,
                                callback: function (value, index, values) {
                                    if (obj.UnitName) {
                                        return value + ' ' + obj.UnitName
                                    } else
                                        return value;
                                },

                            }
                        };

                    } else {
                        scales['y' + i] = {
                            type: 'linear',
                            position: position,
                            min: names[i].MinValue,
                            max: names[i].MaxValue,
                            display: displayLegend,
                            ticks: {
                                color: names[i].Color,
                                callback: function (value, index, values) {
                                    if (obj.UnitName) {
                                        return value + ' ' + obj.UnitName
                                    } else
                                        return value;
                                },
                            },
                            grid: {
                                drawOnChartArea: false, // only want the grid lines for one axis to show up
                            },

                        };
                    }
                });
                var pluginLabels = {
                    id: 'plugin_labels',
                    afterDatasetsDraw: (chart, args, options) => {
                        var { ctx } = chart;
                        ctx.save();
                        ctx.font = '12px sans-serif';
                        for (let x = 0; x < chart.config.data.datasets.length; x++) {
                            if (chart.config.data.datasets[x].type === 'bubble') {

                                for (let i = 0; i < chart.config.data.datasets[x].data.length; i++) {
                                    if (chart.config.data.datasets[x].data[i].isEvent === true) {
                                        let textWidth = ctx.measureText(chart.config.data.datasets[x].data[i].EventDescription).width;
                                        let text = chart.config.data.datasets[x].data[i].EventDescription;
                                        ctx.fillText(text, chart.getDatasetMeta(x).data[i].x - (textWidth / 2), chart.getDatasetMeta(x).data[i].y - 10);
                                    }
                                }
                            }

                        }
                        ctx.restore();
                    },

                }
                this.chart = new Chart(ctx, {
                    type: 'line',
                    data: {
                        datasets: datasets
                    },
                    options: {
                        responsive: true,
                        spanGaps: true,
                        plugins: {
                            title: {
                                display: true,
                            },
                        },
                        scales: scales,

                    },
                    plugins: [pluginLabels],
                });



            },

            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());


                                var gridMainInfo = new Backgrid.Grid({
                                    className: 'backgrid table table-hover table-condensed',
                                    columns: [

                                        {
                                            name: 'HeatName',
                                            editable: false,
                                            label: 'Heat Name',
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell ',
                                            }),
                                        },

                                        {
                                            name: 'Liquidus',
                                            editable: false,
                                            label: 'Liquidus',
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell ',
                                            }),
                                        },     
                                        {
                                            name: 'LadleClose',
                                            editable: false,
                                            label: 'Ladle Close',
                                            cell: Backgrid.Extension.MomentCell.extend({
                                                className: 'momment-cell align-center-cell timestamp',
                                                modelFormat: 'YYYY-MM-DD HH:mm:ss',
                                                displayFormat: 'HH:mm',
                                            }),
                                        },
                                        {
                                            name: 'StartTap',
                                            editable: false,
                                            label: 'Start Tap',
                                            cell: Backgrid.Extension.MomentCell.extend({
                                                className: 'momment-cell align-center-cell timestamp',
                                                modelFormat: 'YYYY-MM-DD HH:mm:ss',
                                                displayFormat: 'HH:mm',
                                            }),
                                        },
                                        {
                                            name: 'Heats',
                                            editable: false,
                                            label: 'Heats',
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell ',
                                            }),
                                        },
                                        {
                                            name: 'Contact',
                                            editable: false,
                                            label: 'Contact Hours',
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell ',
                                            }),
                                        },
                                        {
                                            name: 'MWH',
                                            editable: false,
                                            label: 'MWH',
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell ',
                                            }),
                                        },        

                                    ],
                                    header: Backgrid.Extension.GroupedHeader.extend({
                                        columnLayout:
                                            [
                                                {
                                                    name: 'Ladle', children:
                                                        [

                                                            {
                                                                name: 'Heat Info', children: [
                                                                    { name: 'HeatName' }
                                                                    , { name: 'Liquidus' }
                                                                ]
                                                            },
                                                            {
                                                                name: 'Time Since', children: [
                                                                     { name: 'LadleClose' }
                                                                    , { name: 'StartTap' }
                                                                ]
                                                            },
                                                            {
                                                                name: 'Since Reline', children: [
                                                                    { name: 'Heats' }
                                                                    , { name: 'Contact' }
                                                                    , { name: 'MWH' }
                                                                ]
                                                            }
                                                        ]

                                                },
                                            ],
                                        initialize: function (options) {
                                            Backgrid.Extension.GroupedHeader.prototype.initialize.apply(this, arguments);
                                        },
                                        render: function () {
                                            var that = this;
                                            Backgrid.Extension.GroupedHeader.prototype.render.apply(this, arguments);
                                            return this;
                                        },
                                    }),
                                    collection: that.model.mainInfoColl,
                                });
                                that.$el.find('.main-info-grid-container').append(gridMainInfo.render().el);






                                var grid = new Backgrid.Grid({
                                    className: 'backgrid table table-hover table-condensed',
                                    columns: [
                                        {
                                            name: 'Timestamp',
                                            editable: false,
                                            label: 'Time',
                                            cell: Backgrid.Extension.MomentCell.extend({
                                                className: 'momment-cell align-center-cell timestamp',
                                                modelFormat: 'YYYY-MM-DD HH:mm:ss',
                                                displayFormat: 'HH:mm',
                                            }),
                                        },
                                        {
                                            name: 'Area',
                                            editable: false,
                                            label: 'Area',
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell ',
                                            }),
                                        },
                                        {
                                            name: 'Temperature',
                                            editable: false,
                                            label: 'Temp',
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell ',
                                            }),
                                        },
                                        {
                                            name: 'TempDiff',
                                            editable: false,
                                            label: 'Temp Diff',
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell ',
                                            }),
                                        },
                                        {
                                            name: 'TimeDiff',
                                            editable: false,
                                            label: 'Time Diff min',
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell ',
                                            }),
                                        },
                                        {
                                            name: 'Slope',
                                            editable: false,
                                            label: 'Slope deg/min',
                                            cell: Backgrid.StringCell.extend({
                                                className: 'string-cell align-center-cell ',
                                            }),
                                        },
                                       
                                    ],
                                    collection: that.model.itemsColl,
                                });
                                that.$el.find('.grid-container').append(grid.render().el);


                                that.applyBindings();
                        
                                //rendering Navigation Buttons
                                that.NavigationButtonView.render(that.$el.find(".navigation-buttons"), null);

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

                                var fixedParams = _.extend({}, urlParams);
                                if (fixedParams && fixedParams.heatName && fixedParams.heatName.length === 7) {
                                    that.model.set(fixedParams);
                                } else {
                                    that.UpdateURL();
                                }
                                that.model.fetchCatalogs();

                                that.renderMultipicker();


                                that.refresh();

                            },
                            true,
                            customPath
                        );
                    },
                    customPath
                );
            },

            renderMultipicker: function () {
                var that = this;
                var heatNamesPicker = new VirtualSelect.init({
                    ele: '#heat-picker-multi-select',
                    options: that.model.get('heatNames'),
                    multiple: false,
                    search: true,
                    placeholder: 'Select Heat',
                    hasOptionDescription: false,
                    showSelectedOptionsFirst: true,
                    hideClearButton: true,
                    onServerSearch: that.onSampleSelectServerSearch,
                });
                var heat = that.model.get('heatName');
                document.querySelector('#heat-picker-multi-select').setOptions(that.model.get('heatNames'));
                document.querySelector('#heat-picker-multi-select').setValue(heat);
                document.querySelector('#heat-picker-multi-select').addEventListener('change', function () {
                    $('.vscomp-search-clear').click();
                    if (this.value === that.model.get('heatName')) {
                        return 0;
                    }
                    else {
                        var newHeatName = this.value;
                        if (newHeatName && newHeatName != '') {
                            that.model.set({
                                heatName: newHeatName
                            });
                            that.refresh();
                            that.UpdateURL();
                        }
                    }
                });

            },

            onSampleSelectServerSearch: function (searchValue, virtualSelect) {
                var qp = new Core.Database.QueryParameters();
                qp.Add('@HeatName', 'VARCHAR(10)', searchValue);
                qp.Add('@SelectedHeatName', 'VARCHAR(10)', this.selectedValues[0]);
                qp.Add('@Asset', 'CHAR(3)', 'EAF');    

                Core.Json.CallProcedure(
                    app.DatabaseNames.MES + '.MES.GetAutocompleteHeats',
                    qp,
                    {
                        onSuccess: function (resp) {
                            try {
                                virtualSelect.setServerOptions(resp.Table);

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

            refresh: function () {
                this.model.set({
                    isLoading: true,
                    hasData: false,  
                });

                this.model.fetch();



            },

            fetchnavbuttons: function (resp) {
                this.NavigationButtonView.setDataColl(resp);
            },
            process_fetched: function (mainInfoColl) {
                try {
                    var that = this;
                    var coll = mainInfoColl.toJSON();
                    setTimeout(
                        function () {
                            that.model.set({
                                hasData: true,
                                isLoading: false,
                                heatName: that.model.get('heatName'),
                            });

                        },
                        100
                    );
                    let ladle = document.querySelector('.Ladle');
                    let ladleId = coll[0].LadleId;
                    //ladle.style.fontSize = "20px";
                    ladle.innerHTML = 'Ladle : ' + ladleId;

                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
         
            UpdateURL: function () {
                try {
                    var params = this.model.toJSON();

                    app.router.navigate(
                        app.router.resolveURL(
                            app.router.currentModule,
                            _.extend(
                                {},
                                params,
                                {
                                    heatName: params.heatName,
                                }
                            ),
                            false
                        ),
                        { trigger: false, }
                    );
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
        },

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

        },
        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.Collections.ItemsColl = Backbone.Collection.extend({
        setDataColl: function (data) {
            var newColl,
                that = this;
            newColl = data;
            that.set(newColl).trigger('fetch', that, data);
        },
    });


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