//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',
    'chart',
],
    function (app, T, moment, AgGridModule, Chart) {

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

        // ---------------------------------------------------------------
        // Phase metadata — colors and labels are reused by KPIs and chart
        // ---------------------------------------------------------------
        var PHASES = [
            { key: 'A', xIndex: 1, color: 'rgba(223, 23, 23, 0.7)',  avgColor: 'rgba(223, 23, 23, 1)' },
            { key: 'B', xIndex: 2, color: 'rgba(23, 168, 58, 0.7)',  avgColor: 'rgba(23, 168, 58, 1)' },
            { key: 'C', xIndex: 3, color: 'rgba(31, 111, 223, 0.7)', avgColor: 'rgba(31, 111, 223, 1)' },
        ];

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

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

                hasData: false,
                isLoading: false,

                // KPI strings (formatted for display)
                phaseAAvg: '-', phaseBAvg: '-', phaseCAvg: '-',
                phaseAEnergy: '-', phaseBEnergy: '-', phaseCEnergy: '-',
                phaseACount: '0 heats', phaseBCount: '0 heats', phaseCCount: '0 heats',
            },
            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, };
                    },
                },
            },
        });

        // ---------------------------------------------------------------
        // Shared column definitions for the 3 phase grids
        // ---------------------------------------------------------------
        function buildColumnDefs() {
            return [
                {
                    field: 'ProductionDate', headerName: 'Date', flex: 1.1, minWidth: 110,
                    fieldType: 'Datetime', format: 'ddd MM/DD',
                    cellClass: 'text-center', headerClass: 'ag-header-cell-center',
                },
                {
                    field: 'ShiftId', headerName: 'Shift', width: 60,
                    cellClass: 'text-center', headerClass: 'ag-header-cell-center',
                },
                {
                    field: 'CrewId', headerName: 'Crew', width: 60,
                    cellClass: 'text-center', headerClass: 'ag-header-cell-center',
                },
                {
                    field: 'HeatId', headerName: 'Heat', flex: 1, minWidth: 90,
                    cellClass: 'text-center', headerClass: 'ag-header-cell-center',
                    cellRenderer: heatLinkRenderer,
                },
                {
                    field: 'HeatsBetweenChanges', headerName: 'HBC', flex: 0.8, minWidth: 60,
                    fieldType: 'Integer',
                    cellClass: 'text-right', headerClass: 'ag-header-cell-center',
                    cellStyle: { fontWeight: '600' },
                },
                {
                    field: 'Energy', headerName: 'MWh', flex: 0.9, minWidth: 70,
                    fieldType: 'Float', decimals: 1,
                    cellClass: 'text-right', headerClass: 'ag-header-cell-center',
                },
                {
                    field: 'PowerOn', headerName: 'Power On', flex: 0.9, minWidth: 70,
                    fieldType: 'Float', decimals: 1,
                    cellClass: 'text-right', headerClass: 'ag-header-cell-center',
                },
            ];
        }

        Screen.Views.Main = Backbone.Epoxy.View.extend({
            template: 'eaf-electrodes-summary',
            id: 'eaf-electrodes-summary',
            title: 'EAF Electrodes Summary',
            events: function () {
                return {
                    'click #refreshBtn': this.refreshBtn_click,
                    'click .btn-export-to-excel': this.exportToExcel,
                    'click #calendarStartBtn': this.calendarStartBtn_click,
                    'click #calendarEndBtn': this.calendarEndBtn_click,
                };
            },
            bindings: 'data-bind',
            grids: null,
            chart: null,
            viewParams: null,

            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.grids = {};
                this.subviews = {};

                var sharedColumnDefs = buildColumnDefs();
                var phaseGridOptions = {
                    wrapHeaderText: true,
                    autoHeaderHeight: true,
                    onRowClicked: function (params) {
                        // Skip the pinned average row
                        if (params.node && params.node.rowPinned) return;
                        var heatName = params.data && params.data.HeatId;
                        if (heatName) {
                            app.router.navigate(
                                app.router.resolveURL('eaf-heat-report', { heatName: heatName }, false),
                                { trigger: true }
                            );
                        }
                    },
                };

                // Three independent AG Grid wrappers — one per electrode phase
                this.grids.A = new AgGridModule({
                    columnDefs: sharedColumnDefs,
                    rowData: [],
                    fileName: 'eaf-electrodes-summary-phase-a',
                    screenTitle: this.title + ' (Phase A)',
                    pagination: 'hidden',
                    allowMultipleSelection: false,
                    suppressRowClickSelection: true,
                    gridOptions: phaseGridOptions,
                });
                this.grids.B = new AgGridModule({
                    columnDefs: sharedColumnDefs,
                    rowData: [],
                    fileName: 'eaf-electrodes-summary-phase-b',
                    screenTitle: this.title + ' (Phase B)',
                    pagination: 'hidden',
                    allowMultipleSelection: false,
                    suppressRowClickSelection: true,
                    gridOptions: phaseGridOptions,
                });
                this.grids.C = new AgGridModule({
                    columnDefs: sharedColumnDefs,
                    rowData: [],
                    fileName: 'eaf-electrodes-summary-phase-c',
                    screenTitle: this.title + ' (Phase C)',
                    pagination: 'hidden',
                    allowMultipleSelection: false,
                    suppressRowClickSelection: true,
                    gridOptions: phaseGridOptions,
                });
            },

            // -------------------------------------------------------------
            // Render: build template, attach grids and chart, kick off fetch
            // -------------------------------------------------------------
            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();

                                // Mount the three AG Grid wrappers into their containers
                                that.grids.A.render();
                                that.$el.find('#grid-phase-a').append(that.grids.A.$el);
                                that.grids.B.render();
                                that.$el.find('#grid-phase-b').append(that.grids.B.$el);
                                that.grids.C.render();
                                that.$el.find('#grid-phase-c').append(that.grids.C.$el);

                                // Build the Chart.js scatter chart
                                that.createChart();

                                // Append the screen, then apply URL params
                                that.append(thatContainer, that.$el);

                                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, 10) : 1;

                                that.model.set(fixedParams);

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

            // -------------------------------------------------------------
            // Data fetch — single SP call returning 3 result sets
            // -------------------------------------------------------------
            _refresh: function () {
                var that = this,
                    attrs = this.model.toJSON();

                this.model.set('isLoading', true);
                _.invoke([this.grids.A, this.grids.B, this.grids.C], 'showLoadingOverlay');

                var qp = new Core.Database.QueryParameters();
                qp.Add('@start', 'DATETIME', attrs.start);
                qp.Add('@end', 'DATETIME', attrs.end);
                qp.Add('@furnaceCode', 'INT', attrs.furnaceCode);

                Core.Json.CallProcedure(
                    app.DatabaseNames.MES + '.EAF.GetElectrodesReportWeb',
                    qp,
                    {
                        onSuccess: function (resp) {
                            try {
                                if (resp && resp.Table && resp.Table1 && resp.Table2) {
                                    that.processResults({
                                        A: resp.Table || [],
                                        B: resp.Table1 || [],
                                        C: resp.Table2 || [],
                                    });
                                } else {
                                    that.processResults({ A: [], B: [], C: [] });
                                    if (resp && resp.Message) console.error(resp.Message);
                                }
                            } catch (e) {
                                console.error((e.stack) ? e.stack : new Error(e).stack);
                            } finally {
                                that.model.set('isLoading', false);
                            }
                        },
                        onFailure: function (resp) {
                            console.error(resp);
                            that.model.set('isLoading', false);
                            _.invoke([that.grids.A, that.grids.B, that.grids.C], 'hideOverlay');
                        },
                        Secured: true,
                        Async: true,
                    },
                    app.ConnectionStrings.app
                );
            },

            // -------------------------------------------------------------
            // Process the 3 result sets — split data rows from the rollup
            // "Average" row, push to grids/KPIs/chart
            // -------------------------------------------------------------
            processResults: function (sets) {
                var that = this,
                    modelUpdate = {},
                    chartData = { A: { data: [], avg: null }, B: { data: [], avg: null }, C: { data: [], avg: null } };

                _.each(PHASES, function (phase) {
                    var rows = sets[phase.key] || [];
                    var dataRows = [], avgRow = null;

                    _.each(rows, function (r) {
                        if (r && (r.HeatId === 'Average' || r.HeatId === null || r.HeatId === undefined)) {
                            avgRow = r;
                        } else {
                            dataRows.push(r);
                        }
                    });

                    var grid = that.grids[phase.key];
                    grid.setRowData(dataRows);

                    // Pin the average row at the bottom (yellow row, bold).
                    // Pre-round numeric fields — pinnedBottomRowData bypasses the
                    // wrapper's setRowData formatter, so we do it here. We pass real
                    // numbers (not strings via toFixed) so AG Grid's numeric handling
                    // doesn't show "Invalid Number". HBC is an integer in the SP.
                    var formattedAvg = avgRow ? _.extend({}, avgRow, {
                        HeatId: 'Average',
                        HeatsBetweenChanges: (avgRow.HeatsBetweenChanges != null) ? Math.round(Number(avgRow.HeatsBetweenChanges))            : null,
                        Energy:              (avgRow.Energy              != null) ? Math.round(Number(avgRow.Energy)              * 10) / 10 : null,
                        PowerOn:             (avgRow.PowerOn             != null) ? Math.round(Number(avgRow.PowerOn)             * 10) / 10 : null,
                    }) : null;

                    grid.gridReadyPromise.then(function () {
                        if (formattedAvg && grid.gridApi) {
                            grid.gridApi.setGridOption('pinnedBottomRowData', [formattedAvg]);
                        } else if (grid.gridApi) {
                            grid.gridApi.setGridOption('pinnedBottomRowData', []);
                        }
                    }).catch(function () {});

                    // KPI tiles
                    var avgHbc    = (avgRow && avgRow.HeatsBetweenChanges != null) ? Number(avgRow.HeatsBetweenChanges).toFixed(1) : '-';
                    var avgEnergy = (avgRow && avgRow.Energy != null) ? Number(avgRow.Energy).toFixed(1) : '-';

                    modelUpdate['phase' + phase.key + 'Avg']    = avgHbc;
                    modelUpdate['phase' + phase.key + 'Energy'] = avgEnergy;
                    modelUpdate['phase' + phase.key + 'Count']  = dataRows.length + ' heats';

                    // Chart data — scatter (x = phase index, y = HBC) plus avg marker
                    chartData[phase.key].data = _.map(dataRows, function (r, i) {
                        // Add a tiny horizontal jitter so points don't all overlap on the same X line
                        var jitter = ((i % 11) - 5) * 0.03;
                        return { x: phase.xIndex + jitter, y: Number(r.HeatsBetweenChanges) || 0 };
                    });
                    chartData[phase.key].avg = (avgRow && avgRow.HeatsBetweenChanges != null)
                        ? { x: phase.xIndex, y: Number(avgRow.HeatsBetweenChanges) }
                        : null;
                });

                modelUpdate.hasData = true;
                this.model.set(modelUpdate);

                this.refreshChart(chartData);

                _.invoke([this.grids.A, this.grids.B, this.grids.C], 'hideOverlay');
            },

            // -------------------------------------------------------------
            // Chart.js scatter chart — 3 phases + 3 averages
            // -------------------------------------------------------------
            createChart: function () {
                var canvas = this.$el.find('#hbcChart')[0];
                if (!canvas) return;
                var ctx = canvas.getContext('2d');

                this.chart = new Chart(ctx, {
                    type: 'scatter',
                    data: {
                        datasets: [
                            { label: 'Phase A',     data: [], backgroundColor: PHASES[0].color,    pointRadius: 4, pointHoverRadius: 6 },
                            { label: 'Phase B',     data: [], backgroundColor: PHASES[1].color,    pointRadius: 4, pointHoverRadius: 6 },
                            { label: 'Phase C',     data: [], backgroundColor: PHASES[2].color,    pointRadius: 4, pointHoverRadius: 6 },
                            { label: 'Avg A',       data: [], backgroundColor: PHASES[0].avgColor, pointRadius: 9, pointHoverRadius: 11, pointStyle: 'rectRot' },
                            { label: 'Avg B',       data: [], backgroundColor: PHASES[1].avgColor, pointRadius: 9, pointHoverRadius: 11, pointStyle: 'rectRot' },
                            { label: 'Avg C',       data: [], backgroundColor: PHASES[2].avgColor, pointRadius: 9, pointHoverRadius: 11, pointStyle: 'rectRot' },
                        ],
                    },
                    options: {
                        responsive: true,
                        maintainAspectRatio: false,
                        plugins: {
                            legend: { position: 'bottom', labels: { boxWidth: 12, font: { size: 11 } } },
                            tooltip: {
                                callbacks: {
                                    label: function (ctx) {
                                        return ctx.dataset.label + ': ' + (Math.round(ctx.parsed.y * 10) / 10) + ' heats';
                                    }
                                }
                            }
                        },
                        scales: {
                            x: {
                                type: 'linear',
                                min: 0.5, max: 3.5,
                                ticks: {
                                    stepSize: 1,
                                    callback: function (value) {
                                        if (value === 1) return 'Phase A';
                                        if (value === 2) return 'Phase B';
                                        if (value === 3) return 'Phase C';
                                        return '';
                                    }
                                },
                                grid: { display: false }
                            },
                            y: {
                                title: { display: true, text: 'Heats Between Changes' },
                                beginAtZero: true,
                            }
                        }
                    }
                });
            },

            refreshChart: function (chartData) {
                if (!this.chart) return;
                this.chart.data.datasets[0].data = chartData.A.data;
                this.chart.data.datasets[1].data = chartData.B.data;
                this.chart.data.datasets[2].data = chartData.C.data;
                this.chart.data.datasets[3].data = chartData.A.avg ? [chartData.A.avg] : [];
                this.chart.data.datasets[4].data = chartData.B.avg ? [chartData.B.avg] : [];
                this.chart.data.datasets[5].data = chartData.C.avg ? [chartData.C.avg] : [];
                this.chart.update();
            },

            // -------------------------------------------------------------
            // Excel export — preserve the legacy 3-sheet format
            // -------------------------------------------------------------
            exportToExcel: function () {
                var that = this,
                    attrs = this.model.toJSON();

                var params = [
                    { Name: '@start',       Type: 'DATETIME', Value: new moment(attrs.start, 'YYYY-MM-DD').format('YYYY-MM-DD') },
                    { Name: '@end',         Type: 'DATETIME', Value: new moment(attrs.end,   'YYYY-MM-DD').format('YYYY-MM-DD') },
                    { Name: '@furnaceCode', Type: 'INT',      Value: attrs.furnaceCode },
                ];
                var QP = new QueryParameters();
                _.each(params, function (p) { QP.Add(p.Name, p.Type, p.Value); });

                var cellsData = [
                    { Column: 'A', Value: 'ProductionDate' },
                    { Column: 'B', Value: 'Shift' },
                    { Column: 'C', Value: 'Crew' },
                    { Column: 'D', Value: 'Heat' },
                    { Column: 'E', Value: 'HeatsBetweenChanges' },
                    { Column: 'F', Value: 'Energy (MWh)' },
                    { Column: 'G', Value: 'PowerOn' },
                ];

                var SQLCellsData = [
                    { ExcelColumnName: 'A', SQLDataColumnName: 'ProductionDate',      DataType: 'String' },
                    { ExcelColumnName: 'B', SQLDataColumnName: 'ShiftId',             DataType: 'String' },
                    { ExcelColumnName: 'C', SQLDataColumnName: 'CrewId',              DataType: 'String' },
                    { ExcelColumnName: 'D', SQLDataColumnName: 'HeatId',              DataType: 'String' },
                    { ExcelColumnName: 'E', SQLDataColumnName: 'HeatsBetweenChanges', DataType: 'String' },
                    { ExcelColumnName: 'F', SQLDataColumnName: 'Energy',              DataType: 'String' },
                    { ExcelColumnName: 'G', SQLDataColumnName: 'PowerOn',             DataType: 'String' },
                ];

                var data = {
                    Data: [
                        { SheetName: 'Phase A', RowsData: [{ CellsData: cellsData }], StartRowIndex: 1 },
                        { SheetName: 'Phase A', RowsData: [], StartRowIndex: 2, DataSourceName: 'data', DataSourceTableIndex: 0, SQLCellsData: SQLCellsData },
                        { SheetName: 'Phase B', RowsData: [{ CellsData: cellsData }], StartRowIndex: 1 },
                        { SheetName: 'Phase B', RowsData: [], StartRowIndex: 2, DataSourceName: 'data', DataSourceTableIndex: 1, SQLCellsData: SQLCellsData },
                        { SheetName: 'Phase C', RowsData: [{ CellsData: cellsData }], StartRowIndex: 1 },
                        { SheetName: 'Phase C', RowsData: [], StartRowIndex: 2, DataSourceName: 'data', DataSourceTableIndex: 2, SQLCellsData: SQLCellsData },
                    ],
                    ConnectionStringName: 'APP',
                    ExportMethod: 3,
                    FileName: 'EAF-Electrodes-Summary',
                    TemplateFileFullPath: 'generic.xls',
                    SQLDataSources: [
                        {
                            Name: 'data',
                            DatabaseParameters: {
                                DBEngine: 'SQLSERVER',
                                Procedure: app.DatabaseNames.MES + '.EAF.GetElectrodesReportWeb',
                                QueryParameters: QP,
                            },
                        },
                    ],
                };

                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); }
                    },
                    function (resp) { console.error(resp); }
                );
            },

            // -------------------------------------------------------------
            // Filter / lifecycle handlers
            // -------------------------------------------------------------
            calendarStartBtn_click: function () { this.$el.find('#dateStartTbx').datepicker('show'); },
            calendarEndBtn_click:   function () { this.$el.find('#dateEndTbx').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'),
                                end:   new moment(params.end,   '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); }
            },

            // -------------------------------------------------------------
            // 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.chart && this.chart.destroy) { try { this.chart.destroy(); } catch (e) {} }
                _.each(this.grids, function (g) { if (g && g.destroy) g.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.$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) { }
            },
        });

        // -------------------------------------------------------------
        // Cell renderer: Heat link → eaf-heat-report (matches eaf-electrode-events)
        // -------------------------------------------------------------
        function heatLinkRenderer(params) {
            if (!params.value) return '';
            if (params.node && params.node.rowPinned) {
                // Average row — show plain bold text, no link
                return '<span style="font-weight:700;">' + params.value + '</span>';
            }
            return '<span class="heat-link">' + params.value + '</span>';
        }

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