//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().subtract(2, 'days').format('YYYY-MM-DD'),
                end: new moment().format('YYYY-MM-DD'),

                furnaceId: null,
                furnaces: [{ label: '1', value: 1 }, { label: '2', value: 2 }],

                eventId: null,
                events: [{ label: 'Add', value: 'A' }, { label: 'Slip', value: 'S' }, { label: 'Break', value: 'B' }],

                phaseId: null,
                phases: [{ label: 'A', value: 1 }, { label: 'B', value: 2 }, { label: 'C', value: 3 }],

                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, };
                    },
                },
                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: 'lf-electrode-events',
            id: 'lf-electrode-events',
            title: 'LF Electrode Events',
            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',
            bindingSources: null,
            grids: null,
            itemsColl: null,
            subviews: null,
            viewParams: null,

            columnDefs: [
                { field: 'HeatName', headerName: 'Heat', flex: 1, pinned: 'left', showFilter: true, cellClass: 'text-center', headerClass: 'ag-header-cell-center', cellRenderer: heatLinkRenderer },
                { field: 'DatetimeString', headerName: 'Datetime', flex: 1.2, showFilter: false, cellClass: 'text-center', headerClass: 'ag-header-cell-center' },
                { field: 'ElectrodeEventName', headerName: 'Electrode\nEvent', flex: 1, showFilter: true, cellClass: 'text-center', headerClass: 'ag-header-cell-center', cellStyle: electrodeEventCellStyle },
                { field: 'FurnaceName', headerName: 'Furnace', flex: 0.8, showFilter: true, cellClass: 'text-center', headerClass: 'ag-header-cell-center' },
                { field: 'PhaseName', headerName: 'Phase', flex: 0.8, showFilter: true, cellClass: 'text-center', headerClass: 'ag-header-cell-center' },
                { field: 'VendorName', headerName: 'Vendor', flex: 1, showFilter: true, cellClass: 'text-center', headerClass: 'ag-header-cell-center' },
                { field: 'ArcLengthName', headerName: 'Arc\nLength', flex: 1, showFilter: true, cellClass: 'text-center', headerClass: 'ag-header-cell-center' },
                { field: 'ControlModeName', headerName: 'Break Control\nMode', flex: 1.2, showFilter: true, cellClass: 'text-center', headerClass: 'ag-header-cell-center' },
                { field: 'BreakLocationName', headerName: 'Break\nLocation', flex: 1, showFilter: true, cellClass: 'text-center', headerClass: 'ag-header-cell-center' },
                { field: 'BreakReasonName', headerName: 'Break\nReason', flex: 1, showFilter: true, cellClass: 'text-center', headerClass: 'ag-header-cell-center' },
                { field: 'MWh', headerName: 'MWh', flex: 0.8, showFilter: false, cellClass: 'text-right', headerClass: 'ag-header-cell-center', valueFormatter: numberFormatter },
                { field: 'KwhTon', headerName: 'KwhTon', flex: 0.8, showFilter: false, cellClass: 'text-right', headerClass: 'ag-header-cell-center', valueFormatter: numberFormatter },
                { field: 'FurnaceOperator', headerName: 'Furnace\nOperator', flex: 1, showFilter: true, cellClass: 'text-center', headerClass: 'ag-header-cell-center' },
                { field: 'CraneOperator', headerName: 'Crane\nOperator', flex: 1, showFilter: true, cellClass: 'text-center', headerClass: 'ag-header-cell-center' },
                { field: 'TapNumber', headerName: 'Tap\nNumber', flex: 0.8, showFilter: false, cellClass: 'text-center', headerClass: 'ag-header-cell-center' },
            ],

            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.agGridModule = new AgGridModule({
                    columnDefs: this.columnDefs,
                    rowData: [],
                    fileName: 'lf-electrode-events',
                    screenTitle: this.title,
                    gridOptions: {
                        wrapHeaderText: true,
                        autoHeaderHeight: true,
                        onRowClicked: function (params) {
                            var heatName = params.data && params.data.HeatName;
                            if (heatName) {
                                app.router.navigate(
                                    app.router.resolveURL('lmf-heat-report', { heatName: heatName, treatmentNumber: '1' }, false),
                                    { trigger: true }
                                );
                            }
                        }
                    }
                });

                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(viewParams.start, 'YYYYMMDD').format('YYYY-MM-DD');
                if (viewParams.end)
                    fixedParams.end = new moment(viewParams.end, 'YYYYMMDD').format('YYYY-MM-DD');
                if (viewParams.casterCode)
                    fixedParams.casterCode = (viewParams.casterCode != '-' && viewParams.casterCode != null) ? parseInt(viewParams.casterCode, 10) : null;
                if (viewParams.crewId)
                    fixedParams.crewId = (viewParams.crewId != '-' && viewParams.crewId != null) ? viewParams.crewId : null;
                if (viewParams.shiftId)
                    fixedParams.shiftId = (viewParams.shiftId != '-' && viewParams.shiftId != null) ? parseInt(viewParams.shiftId, 10) : null;

                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;

                var customPath = '/app/pages/lmf/' + 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 (fixedParams.end)
                                    fixedParams.end = new moment(fixedParams.end, 'YYYYMMDD').format('YYYY-MM-DD');
                                if (viewParams.furnaceCode)
                                    fixedParams.furnaceId = (viewParams.furnaceCode != '-' && viewParams.furnaceCode != null) ? parseInt(viewParams.furnaceCode, 10) : null;
                                if (viewParams.eventCode)
                                    fixedParams.eventId = (viewParams.eventCode != '-' && viewParams.eventCode != null) ? viewParams.eventCode : null;
                                if (viewParams.phaseCode)
                                    fixedParams.phaseId = (viewParams.phaseCode != '-' && viewParams.phaseCode != null) ? parseInt(viewParams.phaseCode, 10) : null;

                                that.model.set(fixedParams);

                                var params = that.model.toJSON();
                                that._refresh({
                                    reset: true,
                                    params: _.extend({}, params, {}),
                                });
                            },
                            true,
                            customPath
                        );
                    },
                    customPath
                );
            },

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

            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.agGridModule.showLoadingOverlay();
                }

                this.itemsColl.fetch({
                    start: attrs.start,
                    end: attrs.end,
                    furnaceId: (attrs.furnaceId == "") ? null : attrs.furnaceId,
                    phaseId: (attrs.phaseId == "") ? null : attrs.phaseId,
                    eventId: (attrs.eventId == "") ? null : attrs.eventId,
                    refresh: true,
                });
            },

            calendarStartBtn_click: function () {
                this.$el.find('#dateStartTbx').datepicker('show');
            },
            calendarEndBtn_click: function () {
                this.$el.find('#dateEndTbx').datepicker('show');
            },

            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.furnaceId == "") ? null : attrs.furnaceId },
                    { Name: '@eventCode', Type: 'CHAR(1)', Value: (attrs.eventId == "") ? null : attrs.eventId },
                    { Name: '@phase', Type: 'INT', Value: (attrs.phaseId == "") ? null : attrs.phaseId },
                    { Name: '@TimeZoneCode', Type: 'CHAR', Value: app.models.user.get('timezoneCode'), },
                ];
                var QP = new QueryParameters();

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

                var data = {
                    Data: [],
                    ConnectionStringName: 'APP',
                    ExportMethod: 3,
                    FileName: 'LF-Electrode-Events',
                    TemplateFileFullPath: 'generic.xls',
                    SQLDataSources: [
                        {
                            Name: 'data',
                            DatabaseParameters: {
                                DBEngine: 'SQLSERVER',
                                Procedure: app.DatabaseNames.MES + '.LF.GetElectrodeEventsWeb',
                                QueryParameters: QP,
                            },
                        },
                    ]
                };

                data.Data.push({
                    SheetName: 'Data',
                    RowsData: [{
                        CellsData:
                            [
                                { Column: 'A', Value: 'HeatName', },
                                { Column: 'B', Value: 'DatetimeString', },
                                { Column: 'C', Value: 'ElectrodeEventName', },
                                { Column: 'D', Value: 'FurnaceName', },
                                { Column: 'E', Value: 'PhaseName', },
                                { Column: 'F', Value: 'VendorName', },
                                { Column: 'G', Value: 'ArcLengthName', },
                                { Column: 'H', Value: 'ControlModeName', },
                                { Column: 'I', Value: 'BreakLocationName', },
                                { Column: 'J', Value: 'BreakReasonName', },
                                { Column: 'K', Value: 'MWh', },
                                { Column: 'L', Value: 'KwhTon', },
                                { Column: 'M', Value: 'FurnaceOperator', },
                                { Column: 'N', Value: 'CraneOperator', },
                                { Column: 'O', Value: 'TapNumber', },
                            ],
                    }],
                    StartRowIndex: 1,
                });

                data.Data.push({
                    SheetName: 'Data',
                    RowsData: [],
                    StartRowIndex: 2,
                    DataSourceName: 'data',
                    DataSourceTableIndex: 0,
                    SQLCellsData:
                        [
                            { ExcelColumnName: 'A', SQLDataColumnName: 'HeatName', DataType: 'String' },
                            { ExcelColumnName: 'B', SQLDataColumnName: 'DatetimeString', DataType: 'String' },
                            { ExcelColumnName: 'C', SQLDataColumnName: 'ElectrodeEventName', DataType: 'String' },
                            { ExcelColumnName: 'D', SQLDataColumnName: 'FurnaceName', DataType: 'String' },
                            { ExcelColumnName: 'E', SQLDataColumnName: 'PhaseName', DataType: 'String' },
                            { ExcelColumnName: 'F', SQLDataColumnName: 'VendorName', DataType: 'String' },
                            { ExcelColumnName: 'G', SQLDataColumnName: 'ArcLengthName', DataType: 'String' },
                            { ExcelColumnName: 'H', SQLDataColumnName: 'ControlModeName', DataType: 'String' },
                            { ExcelColumnName: 'I', SQLDataColumnName: 'BreakLocationName', DataType: 'String' },
                            { ExcelColumnName: 'J', SQLDataColumnName: 'BreakReasonName', DataType: 'String' },
                            { ExcelColumnName: 'K', SQLDataColumnName: 'MWh', DataType: 'String' },
                            { ExcelColumnName: 'L', SQLDataColumnName: 'KwhTon', DataType: 'String' },
                            { ExcelColumnName: 'M', SQLDataColumnName: 'FurnaceOperator', DataType: 'String' },
                            { ExcelColumnName: 'N', SQLDataColumnName: 'CraneOperator', DataType: 'String' },
                            { ExcelColumnName: 'O', SQLDataColumnName: 'TapNumber', 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); }
                        if (that.model.setExportButtonExporting) that.model.setExportButtonExporting(false);
                    },
                    function (resp) {
                        if (that.model.refreshProcesses) that.model.refreshProcesses();
                        if (that.model.setExportButtonExporting) that.model.setExportButtonExporting(false);
                        console.error(resp);
                    }
                );
            },
            refreshBtn_click: function (e) {
                try {
                    var params = this.model.toJSON();
                    app.router.navigate(
                        app.router.resolveURL(
                            app.router.currentModule,
                            _.extend(
                                {},
                                params,
                                {
                                    start: new moment(params.start, 'YYYY-MM-DD').format('YYYYMMDD'),
                                    end: new moment(params.end, 'YYYY-MM-DD').format('YYYYMMDD'),
                                    phaseCode: (params.phaseId == null || params.phaseId == "") ? '-' : params.phaseId,
                                    eventCode: (params.eventId == null || params.eventId == "") ? '-' : params.eventId,
                                    furnaceCode: (params.furnaceId == null || params.furnaceId == "") ? '-' : params.furnaceId,
                                }
                            ),
                            false
                        ),
                        { trigger: false, }
                    );

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

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

            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 () {
                var that = this;
            },
            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 (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) { }
            },
        });

        function heatLinkRenderer(params) {
            if (!params.value) return '';
            return '<span class="heat-link" style="color: #007bff; cursor: pointer; text-decoration: underline;">' + params.value + '</span>';
        }

        function numberFormatter(params) {
            return params.value != null && params.value !== '' ? parseFloat(params.value).toFixed(2) : '';
        }

        function electrodeEventCellStyle(params) {
            if (!params.value) return {};
            var val = String(params.value).toUpperCase();
            if (val === 'BREAK') return { color: '#c0392b', fontWeight: '600' };
            if (val === 'ADD') return { color: '#27ae60', fontWeight: '600' };
            if (val === 'SLIP') return { color: '#2980b9', fontWeight: '600' };
            return {};
        }

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

            fixedParameters: [],

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

                    this.fixedParameters = [
                        { Name: '@Start', Type: 'DATETIME', Value: new moment(params.start, 'YYYY-MM-DD').format('YYYY-MM-DD'), },
                        { Name: '@End', Type: 'DATETIME', Value: new moment(params.end, 'YYYY-MM-DD').format('YYYY-MM-DD'), },
                        { Name: '@furnaceCode', Type: 'INT', Value: params.furnaceId },
                        { Name: '@eventCode', Type: 'CHAR(1)', Value: params.eventId },
                        { Name: '@phase', Type: 'INT', Value: params.phaseId },
                        { 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 + '.LF.GetElectrodeEventsWeb',
                    qp,
                    {
                        onSuccess: function (resp) {
                            try {

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

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

                                    that.isFetching = false;


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

        });

        return Screen;
    });
