//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',
    'backbone',
    'moment',
    'modules/modal2',
    'components/ag-grid/ag-grid-module',
    'backgrid',
],
    function (app, T, Backbone, moment, Modal, AgGridModule, Backgrid) {

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

        Screen.Models.Main = Backbone.Epoxy.Model.extend({
            defaults: {
                meltOrderName: null,
                gradeName: null,
                materialSizeSearch: null,

                hasData: false,
                isLoading: false,
                canDragDrop: false,
            },
        });

        // -----------------------------------------------------------------
        // Column definitions
        // -----------------------------------------------------------------
        function getColumnDefs(that, canDragDrop) {
            var t = function (key) { return app.translate([that, app], key); };

            var columns = [];

            columns.push(
                { field: 'MeltOrderNumber', headerName: t('meltOrderNumber_col_label'), flex: 1.2, minWidth: 120, rowDrag: canDragDrop },
                { field: 'GradeName', headerName: t('gradeName_col_label'), flex: 1.2, minWidth: 120 },
                { headerName: t('heats_col_header'), children: [
                    { field: 'HeatsOrdered', headerName: t('heatsOrdered_col_label'), flex: 0.8, minWidth: 80, fieldType: 'Integer' },
                    { field: 'HeatsAssigned', headerName: t('heatsAssigned_col_label'), flex: 0.8, minWidth: 80, fieldType: 'Integer' },
                    { field: 'HeatsLeft', headerName: t('heatsLeft_col_label'), flex: 0.8, minWidth: 80, fieldType: 'Integer' },
                ]},
                { field: 'HeatSize', headerName: t('heatSize_col_label'), flex: 0.8, minWidth: 80, fieldType: 'Integer' },
                { field: 'MaterialSize', headerName: t('materialSize_col_label'), flex: 1, minWidth: 100 },
                { colId: 'actions', headerName: 'Actions', pinned: 'right', width: 80, resizable: false, sortable: false, filter: false, suppressMenu: true, suppressCellSelection: true,
                    cellRenderer: function () { return '<div style="text-align:center;"><button class="btn btn-small" style="font-size:12px;" title="Details"><i class="fa fa-info-circle"></i></button></div>'; }
                }
            );

            return columns;
        }

        // -----------------------------------------------------------------
        // Custom AG Grid module with context menu and row drag
        // -----------------------------------------------------------------
        var CustomAgGridModule = AgGridModule.extend({
            initialize: function (options) {
                this.mainView = options.mainView;
                this.columnDefs = options.columnDefs || [];
                options.columnDefs = this.columnDefs;

                var gridOpts = options.gridOptions || {};
                gridOpts.getContextMenuItems = this.getContextMenuItems.bind(this);

                if (options.enableRowDrag) {
                    gridOpts.rowDragManaged = true;
                    gridOpts.animateRows = true;
                    gridOpts.pagination = false;
                    gridOpts.onRowDragEnd = this.onRowDragEnd.bind(this);
                    options.pagination = 'hidden';
                }

                options.gridOptions = gridOpts;
                AgGridModule.prototype.initialize.call(this, options);
            },

            onCellClicked: function (params) {
                if (params.column && params.column.colDef.colId === 'actions' && params.data && this.mainView) {
                    this.mainView.showMeltOrderDetails(params.data);
                }
                AgGridModule.prototype.onCellClicked.call(this, params);
            },

            onRowDragEnd: function (event) {
                var draggedData = event.node ? event.node.data : null;
                var overData = event.overNode ? event.overNode.data : null;

                if (this.mainView && draggedData) {
                    this.mainView.onRowDragEnd(draggedData, overData);
                }
            },

            getContextMenuItems: function (params) {
                var self = this;
                var mainView = this.mainView;

                if (!mainView || !params || !params.node) {
                    return AgGridModule.prototype.getContextMenuItems.call(this, params);
                }

                return [
                    {
                        name: 'View Details',
                        icon: '<i class="fa fa-info-circle"></i>',
                        action: function () {
                            mainView.showMeltOrderDetails(params.node.data);
                        },
                    },
                    'separator',
                    'copy',
                    {
                        name: 'Copy Selected with Headers',
                        action: function () { self.copySelectedToClipboard(true); },
                    },
                    'separator',
                    {
                        name: 'Export All to Excel',
                        action: function () { self.exportToExcel(false); },
                    },
                    {
                        name: 'Export Selected to Excel',
                        action: function () { self.exportToExcel(true); },
                    },
                ];
            },
        });

        // -----------------------------------------------------------------
        // Main collection — fetches melt orders from SP
        // -----------------------------------------------------------------
        Screen.Collections.Items = Backbone.Collection.extend({
            isFetching: false,
            transaction_timestamp: null,

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

                qp.Add('@PartialMeltOrder', 'VARCHAR', params.PartialMeltOrder);
                qp.Add('@PartialGradeName', 'VARCHAR', params.PartialGradeName);
                qp.Add('@MaterialSize', 'VARCHAR', params.MaterialSize);
                qp.Add('@fromRow', 'INT', 0);
                qp.Add('@rowsToFetch', 'INT', 99999);

                this.isFetching = true;

                Core.Json.CallProcedure(
                    app.DatabaseNames.MES + '.LAD.GetMeltOrders',
                    qp,
                    {
                        onSuccess: function (resp) {
                            try {
                                if (ttimestamp != that.transaction_timestamp) return;

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

        // -----------------------------------------------------------------
        // Detail table model + collection (for Details modal — Backgrid)
        // -----------------------------------------------------------------
        Screen.Models.DetailTable = Backbone.Epoxy.Model.extend({
            defaults: {
                meltOrderSequence: null,
                heatNumber: null,
                ladle: null,
                ladlePosition: null,
            },
            parse: function (obj) {
                return {
                    meltOrderSequence: obj.MeltOrderSequence,
                    heatNumber: obj.HeatNumber,
                    ladle: obj.Ladle,
                    ladlePosition: obj.LadlePosition,
                };
            },
        });

        Screen.Collections.DetailsTable = Backbone.Collection.extend({
            model: Screen.Models.DetailTable,
            isFetching: false,
            transaction_timestamp: null,

            fetch: function (opt) {
                var that = this,
                    qp = new Core.Database.QueryParameters(),
                    ttimestamp = this.transaction_timestamp = new Date().getTime(),
                    options = opt ? _.clone(opt) : {};

                this.isFetching = true;

                this.fixedParameters = [
                    { Name: '@MeltOrderNumber', Type: 'VARCHAR', Value: options.params.meltOrderNumber },
                ];

                _.each(this.fixedParameters, function (qpParams) {
                    qp.Add(qpParams.Name, qpParams.Type, qpParams.Value);
                });

                Core.Json.CallProcedure(
                    app.DatabaseNames.MES + '.LAD.GetMeltOrderDetails',
                    qp,
                    {
                        onSuccess: function (resp) {
                            try {
                                if (ttimestamp != that.transaction_timestamp) return;

                                if (resp && resp.Table && resp.Table1) {
                                    var records = resp.Table1;
                                    var newColl = _.map(records, that.model.prototype.parse);
                                    that.set(newColl);
                                    that.trigger('fetch', that, records);
                                    that.isFetching = false;
                                } else {
                                    if (resp && resp.Message) console.error(resp.Message);
                                    else console.error('Server response not valid.');
                                }
                            } catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                        },
                        Async: true,
                        Secured: true,
                    },
                    app.ConnectionStrings.app
                );

                return this;
            },
        });

        // -----------------------------------------------------------------
        // Details modal model + view (Backgrid inside SimpleModal — kept from legacy)
        // -----------------------------------------------------------------
        Screen.Models.MeltOrderDetails = Backbone.Epoxy.Model.extend({
            defaults: {
                meltOrderNumber: null,
                gradeName: null,
                heatSize: null,
                materialSize: null,
                hasTWI: null,
                meltSequence: null,

                errorMsg: '',
                processing: false,
            },
        });

        Screen.Views.MeltOrderDetails = Modal.Views.SimpleModal.extend({
            className: Modal.Views.SimpleModal.prototype.className + ' melt-order-details',
            i18n: null,
            detailsTable: null,
            detailsGrid: null,
            initialize: function (options) {
                _.extend(this, options);

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

                this.detailsTable = new Screen.Collections.DetailsTable();
                this.detailsTable.fetch({
                    params: {
                        meltOrderNumber: this.model.get('meltOrderNumber'),
                    },
                });
                this.bindEvents();

                return this;
            },
            bindEvents: function () {
                Modal.Views.SimpleModal.prototype.bindEvents.apply(this, arguments);
            },
            render: function () {
                Modal.Views.SimpleModal.prototype.render.apply(this, arguments);

                var that = this;
                var detailsGrid = this.detailsGrid = new Backgrid.Grid({
                    className: 'backgrid table table-hover',
                    columns: [
                        {
                            name: 'meltOrderSequence',
                            label: app.translate([this, app], 'melt_sequence_col_label'),
                            editable: false,
                            sortable: false,
                            cell: Backgrid.StringCell.extend({
                                orderSeparator: '',
                                className: 'string-cell align-center-cell',
                            }),
                        },
                        {
                            name: 'heatNumber',
                            label: app.translate([this, app], 'heat_number_col_label'),
                            editable: false,
                            sortable: false,
                            cell: Backgrid.StringCell.extend({
                                orderSeparator: '',
                                className: 'string-cell align-center-cell',
                            }),
                        },
                        {
                            name: 'ladle',
                            label: app.translate([this, app], 'ladle_col_label'),
                            editable: false,
                            sortable: false,
                            cell: Backgrid.StringCell.extend({
                                orderSeparator: '',
                                className: 'string-cell align-center-cell',
                            }),
                        },
                        {
                            name: 'ladlePosition',
                            label: app.translate([this, app], 'ladle_position_col_label'),
                            editable: false,
                            sortable: false,
                            cell: Backgrid.StringCell.extend({
                                orderSeparator: '',
                                className: 'string-cell align-center-cell',
                            }),
                        },
                    ],
                    collection: this.detailsTable,
                });

                this.$el.find('.details-grid-container').append(detailsGrid.render().el);
            },
            show: function () {
                if (!this.isRendered) {
                    this.render();
                } else {
                    this.$el.modal({
                        keyboard: false,
                        backdrop: 'static',
                    });
                }
                return this;
            },
            hide: function () {
                return Modal.Views.SimpleModal.prototype.hide.apply(this, arguments);
            },
            closeBtn_click: function () {
                try {
                    this.hide();
                } catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
        });

        // -----------------------------------------------------------------
        // generateID
        // -----------------------------------------------------------------
        Screen.generateID = function (viewParams) {
            try { return 'melt-orders'; } catch (Error) { }
        };

        // -----------------------------------------------------------------
        // Main View
        // -----------------------------------------------------------------
        Screen.Views.Main = Backbone.Epoxy.View.extend({
            template: 'melt-orders',
            id: 'melt-orders',
            title: 'Melt Orders',
            isCacheable: false,
            events: function () {
                return {
                    'click #refreshBtn': this.refreshBtn_click,
                    'click .btn-export-to-excel': this.exportToExcel,
                };
            },
            bindings: 'data-bind',
            bindingSources: null,
            grids: null,
            itemsColl: null,
            subviews: null,
            currentModal: null,
            templates: 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.itemsColl = new Screen.Collections.Items();
                this.bindingSources = {};
                this.subviews = {};
                this.templates = {};

                this.bindEvents();
            },

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

            // -----------------------------------------------------------------
            // 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/mes/' + 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();

                                var canDragDrop = $.inArray('lad_meltorders_readWrite', app.models.user.get('roles')) !== -1;

                                that.agGridModule = new CustomAgGridModule({
                                    columnDefs: getColumnDefs(that, canDragDrop),
                                    mainView: that,
                                    rowData: [],
                                    fileName: 'LAD-MeltOrders',
                                    enableRowDrag: canDragDrop,
                                });
                                that.agGridModule.render();
                                that.$el.find('.melt-orders-grid-container').empty().append(that.agGridModule.$el);

                                that.templates.meltOrderDetails = Handlebars.compile(
                                    that.$el.find('#melt_order_details_modal_template').html()
                                );

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

                                that.agGridModule.gridReadyPromise.then(function () {
                                    that._refresh({ reset: true });
                                });
                            },
                            true,
                            customPath
                        );
                    },
                    customPath
                );
            },

            // -----------------------------------------------------------------
            // Data handling
            // -----------------------------------------------------------------
            items_ready: function () {
                try {
                    var that = this;
                    setTimeout(function () {
                        if (that.agGridModule) {
                            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); }
            },

            _refresh: function (opt) {
                this.itemsColl.reset();

                this.model.set({
                    hasData: false,
                    isLoading: true,
                });
                if (this.agGridModule && this.agGridModule.showLoadingOverlay) {
                    this.agGridModule.showLoadingOverlay();
                }

                this.refreshItemsColl(opt);
            },

            refreshItemsColl: function (options) {
                try {
                    var modelAttrs = this.model.toJSON();

                    this.itemsColl.fetch({
                        PartialMeltOrder: modelAttrs.meltOrderName,
                        PartialGradeName: modelAttrs.gradeName,
                        MaterialSize: modelAttrs.materialSizeSearch,
                    });
                } catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
            },

            // -----------------------------------------------------------------
            // Row drag-and-drop handler
            // -----------------------------------------------------------------
            onRowDragEnd: function (draggedData, overData) {
                var that = this;
                var MeltOrderNumberToMove = draggedData ? draggedData.MeltOrderNumber : null;
                var MeltOrderNumberReplaced = overData ? overData.MeltOrderNumber : null;

                if (!MeltOrderNumberToMove) return;

                var qp = new Core.Database.QueryParameters();
                qp.Add('@MeltOrderNumberToMove', 'VARCHAR', MeltOrderNumberToMove);
                qp.Add('@MeltOrderNumberReplaced', 'VARCHAR', MeltOrderNumberReplaced);

                Core.Json.CallProcedure(
                    app.DatabaseNames.MES + '.LAD.MoveMeltOrderPriority',
                    qp,
                    {
                        onSuccess: function (resp) {
                            try {
                                app.views.topMessages.showMessage(
                                    app.translate([that, app], 'MELT_ORDER_PRIORITY_CHANGED'),
                                    { stay: 5000 }
                                );
                                that._refresh({ refresh: true });
                            } catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                        },
                        onFailure: function (resp) {
                            console.error(resp);
                            app.views.topMessages.showMessage(
                                app.translate([that, app], 'MELT_ORDER_PRIORITY_ERROR'),
                                { stay: 5000 }
                            );
                            that._refresh({ refresh: true });
                        },
                        Secured: true,
                        Async: true,
                    },
                    app.ConnectionStrings.app
                );
            },

            // -----------------------------------------------------------------
            // Details modal
            // -----------------------------------------------------------------
            showMeltOrderDetails: function (rowData) {
                try {
                    this.currentModal = new Screen.Views.MeltOrderDetails({
                        model: new Screen.Models.MeltOrderDetails({
                            meltOrderNumber: rowData.MeltOrderNumber,
                            gradeName: rowData.GradeName,
                            heatSize: rowData.HeatSize,
                            materialSize: rowData.MaterialSize,
                            hasTWI: rowData.HasTWI,
                            meltSequence: rowData.MeltSequence,
                        }),
                        template: this.templates.meltOrderDetails,
                        i18n: this.options.i18n[this.template],
                    });

                    this.currentModal.show();
                } catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
            },

            // -----------------------------------------------------------------
            // Excel export (AG Grid built-in)
            // -----------------------------------------------------------------
            exportToExcel: function () {
                if (this.agGridModule) {
                    this.agGridModule.exportToExcel(false);
                }
            },

            // -----------------------------------------------------------------
            // Refresh button
            // -----------------------------------------------------------------
            refreshBtn_click: function () {
                try {
                    this._refresh({ reset: true });
                    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;
                }
            },
            close: function () {
                this.options.state = app.view_states.closed;

                if (this.currentModal) {
                    this.currentModal.hide();
                    this.currentModal = null;
                }

                if (this.agGridModule && this.agGridModule.destroy) {
                    this.agGridModule.destroy();
                }

                this.closeSubviews();
                this.remove();
                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({ reset: true });
                } catch (Error) { }
            },
        });

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