//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([
    'app',
    'js/templates-loader',
    'moment',
    'components/ag-grid/ag-grid-module',
],
    function (app, T, moment, AgGridModule) {

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

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

                furnaceCode: null,
                furnaces: [{ label: 'A', value: 1 }, { label: 'B', value: 2 }],

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

        Screen.Collections.Items = Backbone.Collection.extend({
            isFetching: false,

            fetch: function (params) {
                var that = this,
                    qp = new Core.Database.QueryParameters();

                this.isFetching = true;

                qp.Add('@start', 'DATETIME', new moment(params.start, 'YYYYMMDD').format('YYYY-MM-DD'));
                qp.Add('@furnaceCode', 'INT', params.furnaceCode);
                qp.Add('@timezoneCode', 'CHAR', app.models.user.get('timezoneCode'));

                Core.Json.CallProcedure(
                    app.DatabaseNames.MES + '.EAF.GetComponentsHistoryWeb',
                    qp,
                    {
                        onSuccess: function (resp) {
                            try {
                                if ((resp) && (resp.Table)) {
                                    // SP returns one row per (heat, equipment-location). Pivot client-side
                                    // into one row per heat with one column per LocationName.
                                    // Single _.groupBy pass keeps this O(N); the legacy custom-screen
                                    // version did O(N^2) with a _.where per unique heat.
                                    var byHeat = _.groupBy(resp.Table, 'HeatId');
                                    var pivoted = _.map(byHeat, function (rows, heatId) {
                                        return that.pivotHeat(heatId, rows);
                                    });

                                    that.set(pivoted);
                                    that.trigger('fetch', that, pivoted);
                                    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);
                                    }
                                    that.isFetching = false;
                                }
                            }
                            catch (e) {
                                console.error((e.stack) ? e.stack : new Error(e).stack);
                                that.isFetching = false;
                            }
                        },
                        onFailure: function (resp) {
                            console.error(resp);
                            that.isFetching = false;
                        },
                        Secured: true,
                        Async: true,
                    },
                    app.ConnectionStrings.app
                );
                return this;
            },

            // Collapse N rows-per-heat into a single row keyed by LocationName.
            pivotHeat: function (heatId, rows) {
                var result = { HeatId: heatId };
                _.each(rows, function (r, i) {
                    result[r.LocationName] = r.Counter;
                    if (i === 0) {
                        result.TapTime = r.TapTime;
                        result.ProductionDate = r.ProductionDate;
                        result.Shift = r.Shift;
                        result.TapTemperature = r.TapTemperature;
                        result.TapChanges = r.TapChanges;
                    }
                });
                return result;
            },
        });


        Screen.Views.Main = Backbone.Epoxy.View.extend({
            template: 'eaf-components-history',
            id: 'eaf-components-history',
            title: 'EAF Components History',
            events: function () {
                return {
                    'click #refreshBtn': this.refreshBtn_click,
                    'click #excelBtn': this.exportToExcel,
                    'click #calendarStartBtn': this.calendarStartBtn_click,
                };
            },
            bindings: 'data-bind',
            bindingSources: null,
            itemsColl: null,
            subviews: null,
            viewParams: null,

            // ----------------------------------------------------------------
            // Column defs — only Heat is pinned. All other columns are flexible
            // and get auto-sized to fit their widest content after each fetch
            // (see autoSizeAfterRender below). minWidth values act as floors
            // so very short numeric values can't collapse the column under the
            // header text. Grouped sections: Burner 1..5 and Phase Electrode
            // Arm A/B/C, matching the legacy layout.
            // ----------------------------------------------------------------
            columnDefs: [
                { field: 'HeatId', headerName: 'Heat', minWidth: 80, pinned: 'left', cellClass: 'text-center', headerClass: 'ag-header-cell-center' },
                { field: 'ProductionDate', headerName: 'Production\nDate', minWidth: 90, headerClass: 'header-two-lines ag-header-cell-center', cellClass: 'text-center', fieldType: 'Datetime', format: 'MM/DD/YY' },
                { field: 'Shift', headerName: 'Shift', minWidth: 50, cellClass: 'text-center', headerClass: 'ag-header-cell-center' },
                { field: 'TapTime', headerName: 'Tap Time', minWidth: 110, cellClass: 'text-center', headerClass: 'ag-header-cell-center', fieldType: 'Datetime', format: 'MM/DD/YY HH:mm' },
                { field: 'TapTemperature', headerName: 'Tap\nTemp', minWidth: 55, cellClass: 'text-right', headerClass: 'header-two-lines ag-header-cell-center' },

                { field: 'Breast Electrode', headerName: 'Breast\nElectrode', minWidth: 70, cellClass: 'text-right', headerClass: 'header-two-lines ag-header-cell-center' },
                { field: 'Bottom Inspected', headerName: 'Bottom\nInspected', minWidth: 70, cellClass: 'text-right', headerClass: 'header-two-lines ag-header-cell-center' },
                { field: 'Brick', headerName: 'Brick', minWidth: 55, cellClass: 'text-right', headerClass: 'ag-header-cell-center' },

                {
                    headerName: 'Burner', headerClass: 'ag-header-group-cell-center', children: [
                        { field: 'Burner 1', headerName: '1', minWidth: 40, cellClass: 'text-right', headerClass: 'ag-header-cell-center' },
                        { field: 'Burner 2', headerName: '2', minWidth: 40, cellClass: 'text-right', headerClass: 'ag-header-cell-center' },
                        { field: 'Burner 3', headerName: '3', minWidth: 40, cellClass: 'text-right', headerClass: 'ag-header-cell-center' },
                        { field: 'Burner 4', headerName: '4', minWidth: 40, cellClass: 'text-right', headerClass: 'ag-header-cell-center' },
                        { field: 'Burner 5', headerName: '5', minWidth: 40, cellClass: 'text-right', headerClass: 'ag-header-cell-center' },
                    ]
                },

                { field: 'Combustion Chamber', headerName: 'Combustion\nChamber', minWidth: 80, cellClass: 'text-right', headerClass: 'header-two-lines ag-header-cell-center' },
                { field: 'Delta', headerName: 'Delta', minWidth: 55, cellClass: 'text-right', headerClass: 'ag-header-cell-center' },

                {
                    headerName: 'Phase Electrode Arm', headerClass: 'ag-header-group-cell-center', children: [
                        // SQL location names include a trailing space — keep as-is to match the SP output.
                        { field: 'A Phase Electrode Arm ', headerName: 'A', minWidth: 40, cellClass: 'text-right', headerClass: 'ag-header-cell-center' },
                        { field: 'B Phase Electrode Arm ', headerName: 'B', minWidth: 40, cellClass: 'text-right', headerClass: 'ag-header-cell-center' },
                        { field: 'C Phase Electrode Arm ', headerName: 'C', minWidth: 40, cellClass: 'text-right', headerClass: 'ag-header-cell-center' },
                    ]
                },

                { field: 'Lance', headerName: 'Lance', minWidth: 55, cellClass: 'text-right', headerClass: 'ag-header-cell-center' },
                { field: 'MOD', headerName: 'MOD\nOperations', minWidth: 80, cellClass: 'text-right', headerClass: 'header-two-lines ag-header-cell-center' },
                // Trailing space matches the legacy field/location name from SQL.
                { field: 'Roof ', headerName: 'Roof', minWidth: 55, cellClass: 'text-right', headerClass: 'ag-header-cell-center' },
                { field: 'Shell ', headerName: 'Shell', minWidth: 55, cellClass: 'text-right', headerClass: 'ag-header-cell-center' },
                { field: 'PACS', headerName: 'Switch\nOperations', minWidth: 80, cellClass: 'text-right', headerClass: 'header-two-lines ag-header-cell-center' },
                { field: 'TapChanges', headerName: 'Tap\nChanges', minWidth: 65, cellClass: 'text-right', headerClass: 'header-two-lines ag-header-cell-center' },
                { field: 'Tap Hole', headerName: 'Tap\nHole', minWidth: 65, cellClass: 'text-right', headerClass: 'header-two-lines ag-header-cell-center' },
            ],

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

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

                this.itemsColl = new Screen.Collections.Items();
                this.bindingSources = {};
                this.subviews = {};

                this.agGridModule = new AgGridModule({
                    columnDefs: this.columnDefs,
                    rowData: [],
                    fileName: 'eaf-components-history',
                    screenTitle: this.title,
                    gridOptions: {
                        wrapHeaderText: true,
                        autoHeaderHeight: true,
                    },
                });

                this.bindEvents();
            },
            bindEvents: function () {
                this.listenTo(this.itemsColl, 'fetch', this.processes_ready);
            },

            // ----------------------------------------------------------------
            // Data loading
            // ----------------------------------------------------------------
            _refresh: function () {
                var that = this;
                this.itemsColl.reset();
                this.model.set({ hasData: false, isLoading: true });

                // Wait for the grid to actually exist before showing the
                // overlay AND before kicking off the fetch. On the first load
                // the gridApi is created asynchronously inside the AG Grid
                // module (setTimeout(0) in createGrid), so a naive showLoading
                // call here would silently no-op and the user wouldn't see any
                // loading indicator inside the grid until the SP returns.
                // On subsequent refreshes the promise is already resolved, so
                // this is effectively a microtask hop.
                this.agGridModule.gridReadyPromise.then(function () {
                    that.agGridModule.showLoadingOverlay();
                    var attrs = that.model.toJSON();
                    that.itemsColl.fetch({
                        start: new moment(attrs.start, 'YYYY-MM-DD').format('YYYYMMDD'),
                        furnaceCode: (attrs.furnaceCode === '' || attrs.furnaceCode === '-') ? null : attrs.furnaceCode,
                    });
                });
            },

            processes_ready: function () {
                var that = this;
                try {
                    setTimeout(function () {
                        that.agGridModule.setRowDataAsCollection(that.itemsColl);
                        that.agGridModule.hideOverlay();
                        that.model.set({
                            hasData: (that.itemsColl.length > 0),
                            isLoading: false,
                        });
                        that.adjustColumns();
                    }, 100);
                }
                catch (e) {
                    console.error((e.stack) ? e.stack : new Error(e).stack);
                    this.model.set({ isLoading: false });
                    if (this.agGridModule && this.agGridModule.hideOverlay) this.agGridModule.hideOverlay();
                }
            },

            // Resize columns to suit the current data:
            //  - With data: auto-size each column to its widest rendered cell.
            //    skipHeader=true so wide group headers like "Phase Electrode Arm"
            //    don't inflate the narrow leaf columns A/B/C under them.
            //  - Without data: stretch columns to fill the viewport so the
            //    "No Rows To Show" overlay sits over a properly-laid-out grid
            //    instead of compressed columns bunched to the left edge.
            // Wrapped in a setTimeout so the grid has actually painted before
            // we measure widths.
            adjustColumns: function () {
                var that = this;
                setTimeout(function () {
                    var api = that.agGridModule && that.agGridModule.gridApi;
                    if (!api) return;
                    if (that.itemsColl.length > 0 && api.autoSizeAllColumns) {
                        api.autoSizeAllColumns(true);
                    } else if (api.sizeColumnsToFit) {
                        api.sizeColumnsToFit();
                    }
                }, 50);
            },

            // ----------------------------------------------------------------
            // Toolbar handlers
            // ----------------------------------------------------------------
            exportToExcel: function () {
                if (this.agGridModule && this.agGridModule.exportToExcel) {
                    this.agGridModule.exportToExcel(false);
                }
            },
            calendarStartBtn_click: function () {
                this.$el.find('#dateStartTbx').datepicker('show');
            },
            refreshBtn_click: function () {
                try {
                    var params = this.model.toJSON();
                    app.router.navigate(
                        app.router.resolveURL(
                            app.router.currentModule,
                            {
                                start: new moment(params.start, 'YYYY-MM-DD').format('YYYYMMDD'),
                                furnaceCode: (params.furnaceCode == null || params.furnaceCode === '') ? '-' : params.furnaceCode,
                            },
                            false
                        ),
                        { trigger: false }
                    );

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

            // ----------------------------------------------------------------
            // Render
            // ----------------------------------------------------------------
            render: function (container, viewParams) {
                var that = this;

                this.viewParams = viewParams;

                var thatContainer = (this.options.container) ? this.options.container : container;
                this.options.container = thatContainer;

                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) {
                                that.options.i18n[that.template] = i18nJED;
                                that.$el.html(tmp());
                                that.applyBindings();

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

                                that.agGridModule.render();
                                that.$el.find('.processes-grid-container').append(that.agGridModule.$el);

                                that.append(thatContainer, that.$el);

                                var fixedParams = _.extend({}, viewParams);
                                if (fixedParams.start)
                                    fixedParams.start = new moment(fixedParams.start, 'YYYYMMDD').format('YYYY-MM-DD');
                                if (viewParams.furnaceCode)
                                    fixedParams.furnaceCode = (viewParams.furnaceCode !== '-' && viewParams.furnaceCode != null) ? parseInt(viewParams.furnaceCode, 10) : null;

                                that.model.set(fixedParams);

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

            // ----------------------------------------------------------------
            // View boilerplate
            // ----------------------------------------------------------------
            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) {
                    this.options.state = app.view_states.shown;
                    container.append(el);
                    this.options.onappend(this);
                }
                if (this.options.state == app.view_states.hidden) container.append(el);
                if (this.options.state == app.view_states.closed) return;
            },
            bindViewScopedEvents: function () { },
            unbindViewScopedEvents: function () { },
            close: function () {
                this.options.state = app.view_states.closed;
                if (this.agGridModule && this.agGridModule.destroy) this.agGridModule.destroy();
                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 (s) { s.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 (s) { s.hide(); }); },
            preRender: function () { app.models.subnavbar.set('subnavbar', false); },
            reRender: function (viewParams) {
                try { this._refresh(); } catch (Error) { }
            },
        });

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