﻿//SCREEN-BOILERPLATE
//this boilerplate builds screens that are gonna be shown in the <div class='content'> tag of our main HTML.
//do not build app components with this boilerplate, only screens (reports)

define([
    // Application variable, always include it to have access to app methods.
    'app',

    //templates-loader: this loads templates async.
    'js/templates-loader',
    'backgrid',
    'moment',


    'modules/modal2',
    'modules/modal-sulpher-print/modal-sulpher-print',

    'components/ag-grid/ag-grid-module',
    'backgrid/infinator',
    'backgrid/moment-cell',
    'backgrid/grouped-columns',

    "js/jquery.floatThead/jquery.floatThead",
    'js/jquery.contextMenu/jquery.contextMenu'
],
    function (app, T, Backgrid, moment, Modal, SulpherPrintModal, 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'),

                printerCode: null,
                printers: [{ label: 'All', value: null }, { label: '1', value: 1 }, { label: '2', value: 2 }],

                crewId: null,
                crews: [{ label: 'A', value: 'A' }, { label: 'B', value: 'B' }, { label: 'C', value: 'C' }, { label: 'D', value: 'D' }],

                shiftId: null,
                shifts: [{ label: 'D', value: 1 }, { label: 'N', value: 2 }],


                strandId: null,
                //strands: [{ label: '1', value: 1 }, { label: '2', value: 2 }, { label: '3', value: 3 }, { label: '4', value: 4 }],

                hasData: false,
                isLoading: false,
                isExcelExporting:false,
                grid: [],
                searchText: '',
                isPageLoading : false,
                printLengthMode: 'hot'
            },
            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, };
                    },
                },
            },
            
           
        });

        var CustomAgGridModule = AgGridModule.extend({
            initialize: function (options) {
                this.bus = options.bus;
                this.itemsColl = options.itemsColl;
                this.columnDefs = [
                    { field: 'HeatNumber', headerName: 'Heat', flex: 1, showFilter: true },
                    { field: 'StrandNumber', headerName: 'Strand', flex: 1, showFilter: false },
                    { field: 'ProductNumber', headerName: 'Product', flex: 1, showFilter: true },
                    { field: 'TaggingCommandTypeCode', headerName: 'Command', flex: 1, showFilter: true },
                    { field: 'HeatGrade', headerName: 'Grade', flex: 1,minWidth: 150, showFilter: true },
                    { field: 'Length', headerName: 'Length', flex: 1, showFilter: false },
                    { field: 'Weight', headerName: 'Weight', flex: 1, showFilter: false },
                    { field: 'MoldType', headerName: 'Mold', flex: 1, showFilter: false },
                    { field: 'TaggingCommandStatusCode', headerName: 'Status', flex: 1, showFilter: true },
                    { field: 'Printer', headerName: 'Printer', flex: 1, showFilter: true },
                    { field: 'Timestamp', headerName: 'Timestamp', flex: 1,minWidth: 150, showFilter: true , fieldType: 'Datetime', format:'MM/DD HH:mm'},
                    { field: 'User', headerName: 'User', flex: 1, showFilter: false },
                    { field: 'Comments', headerName: 'Comments', flex: 1, showFilter: false },
                    { field: 'Employee', headerName: 'Employee', flex: 1, showFilter: false },
                    { field: 'Reason', headerName: 'Reason', flex: 2, showFilter: false },
                    {
                        field: 'PrintedLength',
                        headerName: 'Printed Length',
                        flex: 1,
                        showFilter: false,
                        cellRenderer: this.printedLengthPillRenderer.bind(this),
                        cellStyle: { display: 'flex', justifyContent: 'center', alignItems: 'center' }
                    },

                    // Column for Declare and Split buttons
                    // {
                    //     headerName: 'Actions',
                    //     field: null,  // If you don't need a field for this column
                    //     cellRenderer: this.optionsCellRenderer.bind(this),  // Bind the method to `this`
                    //     minWidth: 50
                    // }
                ];

                // Pass the columns to the options
                options.columnDefs = this.columnDefs;

                // Initialize ag-Grid
                AgGridModule.prototype.initialize.call(this, options);
            },
            // optionsCellRenderer: function (params) {
            //     // Create the Justify button
            //     const optionsBtn = document.createElement('button');
            //     optionsBtn.className = 'MuiButtonBase-root MuiIconButton-root';
            //     optionsBtn.setAttribute('title', 'Options');
            //     optionsBtn.style.display = 'inline-block';  // Ensure buttons are visible
            //     optionsBtn.style.minWidth = '30px';  // Ensure the button has enough width
            //     optionsBtn.style.minHeight = '24px'; // Ensure the button has enough height
            //     optionsBtn.style.marginRight = '10px';
            //     optionsBtn.innerHTML = `
            //         <span class="MuiIconButton-label">
            //             <svg class="MuiSvgIcon-root text-blue-500 MuiSvgIcon-fontSizeInherit" focusable="false" viewBox="0 0 24 24" aria-hidden="true" style="cursor: pointer;">
            //                 <path d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z"></path>
            //             </svg>
            //         </span>`;

            //     // Create the Split button with the updated icon
               
            //     optionsBtn.style.zIndex = '1000';  // Ensure it's above other elements

            //     // Create a container for the buttons
            //     const container = document.createElement('div');
            //     container.className = 'flex justify-center';
            //     container.style.display = 'inline-block';  // Ensure container is visible
            //     container.style.minWidth = '40px';   // Ensure container width
            //     container.style.minHeight = '24px';  // Ensure container height
            //     container.appendChild(optionsBtn);

            //     const rowData = params.data;

            //     optionsBtn.addEventListener('click', (event) => this.showContextMenu(event, params));

            //     // optionsBtn.addEventListener('click', function () {


            //     //     var that = this;
            //     //     this.showContextMenu();
            //     //    console.log(rowData);
            //     // }.bind(this));

            //     // Return the container to be rendered
            //     return container;
            // },
            // showContextMenu: function (event, params) {
            
            //     event.preventDefault();
            
            //     // Remove any existing context menu
            //     const existingMenu = document.querySelector('.context-menu');
            //     if (existingMenu) {
            //         existingMenu.remove();
            //     }
            
            //     // Create the context menu element
            //     const menu = document.createElement('div');
            //     menu.classList.add('context-menu');
            //     menu.innerHTML = `
            //     <ul style="list-style-type: none; padding: 0; margin: 0;">
            //         <li data-action="sendToL3" style="display: flex; align-items: center; padding: 8px; cursor: pointer;">
            //             <i class="fa fa-share-square" style="margin-right: 8px;"></i> Send To L3
            //         </li>
            //         <hr style="margin: 4px 0;">
            //         <li data-action="printTag" style="display: flex; align-items: center; padding: 8px; cursor: pointer;">
            //             <i class="fa fa-tag" style="margin-right: 8px;"></i> Print Tag
            //         </li>
            //         <hr style="margin: 4px 0;">
            //         <li data-action="editSulfurRating" style="display: flex; align-items: center; padding: 8px; cursor: pointer;">
            //             <i class="fa fa-pencil" style="margin-right: 8px;"></i> Edit Sulfur Rating
            //         </li>
            //     </ul>
            // `;
            
            //     // Set position and add to the document
            //     menu.style.position = 'absolute';
            //     menu.style.top = `${event.clientY}px`;
            //     menu.style.left = `${event.clientX}px`;
            //     document.body.appendChild(menu);
            //     setTimeout(() => {
            //         const closeMenu = (e) => {
            //             if (!menu.contains(e.target)) {  // Check if the click was outside the menu
            //                 menu.remove();  // Remove the menu from the DOM
            //                 document.removeEventListener('click', closeMenu);  // Remove the event listener
            //             }
            //         };
            //         document.addEventListener('click', closeMenu);
            //     }, 0);

            //     menu.querySelector('[data-action="sendToL3"]').addEventListener('click', () => {
            //         this.handleSendToL3(params);
            //         menu.remove();  // Close the menu after action
            //     });
            //     menu.querySelector('[data-action="printTag"]').addEventListener('click', () => {
            //         this.handlePrintTag(params);
            //         menu.remove();  // Close the menu after action
            //     });
            //     menu.querySelector('[data-action="editSulfurRating"]').addEventListener('click', () => {
            //         this.handleEditSulfurRating(params);
            //         menu.remove();  // Close the menu after action
            //     });

            // },
            printedLengthPillRenderer: function(params) {
                // Accept a variety of possible values coming from DB: 'H'/'HOT'/0 or 'C'/'COLD'/1
                var raw = params.value;
                if (raw == null || raw === '') return '';

                var v = (typeof raw === 'string') ? raw.trim().toUpperCase() : raw;
                var isCold =
                    v === 'C' || v === 'COLD' || v === 1 || v === '1' || v === true;

                var span = document.createElement('span');
                span.className = 'pill ' + (isCold ? 'pill-cold' : 'pill-hot');
                span.textContent = isCold ? 'COLD' : 'HOT';
                span.title = isCold ? 'COLD' : 'HOT';
                return span;
                }


        });


        Screen.Views.Main = Backbone.Epoxy.View.extend({
            template: 'caster-tag-report',
            id: 'caster-tag-report',
            title: 'Caster Tag Report',
            events: function () {
                return {
                    'click #refreshBtn': this.refreshBtn_click,
                    "click #exportExcelBtn": this.exportToExcel,
                    'click #calendarStartBtn': this.calendarStartBtn_click,
                    'click #calendarEndBtn': this.calendarEndBtn_click,
                    'change input[name="printLengthMode"]': this.onPrintLengthModeChange,

                };
            },
            bindings: 'data-bind',
            bindingSources: null,
            grids: null,
            itemsColl: null,
            subviews: null,
            viewParams: null,
                      
            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();

                // Init AgGridModule:
               
                this.agGridModule = new CustomAgGridModule({
                    itemsColl: this.itemsColl,
                    bus: this.bus,
                    rowData: [],
                    onChange: this.handleGridChange.bind(this),
                    onRemove: this.handleGridRemove.bind(this),
                    fileName:'caster-tagging-report',
                    screenTitle: 'Caster Tagging Report',
                    isPageLoading: that.model.get('isPageLoading'),
                });
                this.grids = {};


                this.itemsColl = new Screen.Collections.Items();

                this.bindingSources = {};

                this.subviews = {};
                this.autoRefresh = {
                    enabled: null
                    , toid: null
                    , every: 5 * 1000
                };

                this.prevPrintLengthMode = 'hot'


                this.bindEvents();
                this.bus = _.extend({}, Backbone.Events);
                this.bus.on("modalAcceptBtn", this.onModalAcceptBtn, this);
            },
            fetchColdLengthPrintSetting: function() {
  var that = this;
  var qp = new Core.Database.QueryParameters();

  Core.Json.CallProcedure(
    app.DatabaseNames.MES + '.CAS.GetColdLengthPrint',
    qp,
    {
      onSuccess: function(resp) {
        if (resp && resp.Table && resp.Table.length > 0) {
          var dbValue = resp.Table[0].ColdLengthEnabled; // 0 or 1
          var mode = (dbValue == 1) ? 'cold' : 'hot';

          that.model.set('printLengthMode', mode);
          that.$('input[name="printLengthMode"][value="' + mode + '"]').prop('checked', true);
          that.updatePrintLengthToggleUI(mode);
          that.prevPrintLengthMode = mode;
        }
       
      },
      onFailure: function(resp) {
        console.error("Failed to fetch ColdLengthPrint setting", resp);
      },
      Secured: true,
      Async: true
    },
    app.ConnectionStrings.app
  );
},


            onPrintLengthModeChange: function (e) {
  var newMode = this.$('input[name="printLengthMode"]:checked').val(); // "cold" | "hot"
  var that = this;

  if (newMode === this.prevPrintLengthMode) return;

  this.confirmToggleModal(newMode).then(function(confirmed) {
    if (confirmed) {
      that.model.set('printLengthMode', newMode);
      that.updatePrintLengthToggleUI(newMode);
      that.prevPrintLengthMode = newMode;

      // === CALL STORED PROCEDURE HERE ===
      var qp = new Core.Database.QueryParameters();
      var value = (newMode === 'cold') ? 1 : 0;   // 1 = Cold, 0 = Hot
      qp.Add('@ColdLengthEnabled', 'BIT', value);

      Core.Json.CallProcedure(
        app.DatabaseNames.MES + '.CAS.UpdateColdLengthPrint', // name of your SP
        qp,
        {
          onSuccess: function(resp) {
             app.views.topMessages.showMessage('Print changed to '+newMode+ ' length' , { stay: 5000, });
          },
          onFailure: function(resp) {
            console.error("Failed to update ColdLengthPrint setting", resp);
          },
          Secured: true,
          Async: true
        },
        app.ConnectionStrings.app
      );
      // ================================

    } else {
      // Revert if canceled
      that.$('input[name="printLengthMode"][value="' + that.prevPrintLengthMode + '"]').prop('checked', true);
      that.updatePrintLengthToggleUI(that.prevPrintLengthMode);
    }
  });
},


 confirmToggleModal: function(mode) {
  var title = 'Confirm';
  var body = 'Are you sure you want to enable ' + (mode === 'cold' ? 'COLD' : 'HOT') + ' Length?';

  // Modal HTML with backdrop
  var $overlay = $(
    '<div class="fixed inset-0 z-50 flex items-center justify-center">' +
      // BACKDROP
      '<div class="fixed inset-0 bg-black bg-opacity-40"></div>' +
      // MODAL
      '<div class="relative bg-white rounded-lg shadow-xl w-full max-w-md mx-2">' +
        '<div class="px-4 py-3 border-b border-gray-200">' +
          '<h3 class="text-base font-semibold text-gray-900">' + _.escape(title) + '</h3>' +
        '</div>' +
        '<div class="px-4 py-4 text-sm text-gray-700">' + _.escape(body) + '</div>' +
        '<div class="px-4 py-3 border-t border-gray-200 flex justify-end space-x-2">' +
          '<button class="btn-cancel bg-white border border-gray-300 text-gray-700 hover:bg-gray-50 rounded px-3 py-2 text-sm">Cancel</button>' +
          '<button class="btn-ok bg-blue-600 hover:bg-blue-700 text-white rounded px-3 py-2 text-sm">Enable</button>' +
        '</div>' +
      '</div>' +
    '</div>'
  );

  $('body').append($overlay);

  function cleanup() { $overlay.remove(); }

  return new Promise(function(resolve) {
    $overlay.find('.btn-cancel').on('click', function() { cleanup(); resolve(false); });
    $overlay.find('.btn-ok').on('click', function() { cleanup(); resolve(true); });

    // click backdrop (outer wrapper)
    $overlay.on('click', function(ev) {
      if (ev.target === $overlay[0]) { cleanup(); resolve(false); }
    });
  });
},



            updatePrintLengthToggleUI: function (mode) {
  var coldLabel = this.$('label[for="printModeCold"]');
  var hotLabel  = this.$('label[for="printModeHot"]');

  // reset both
  coldLabel.removeClass('ring-2 ring-offset-1 ring-blue-500 font-semibold opacity-60');
  hotLabel.removeClass('ring-2 ring-offset-1 ring-red-500 font-semibold opacity-60');

  // dim the inactive one
  if (mode === 'cold') {
    hotLabel.addClass('opacity-60');
    coldLabel.addClass('ring-2 ring-offset-1 ring-blue-500 font-semibold');
  } else {
    coldLabel.addClass('opacity-60');
    hotLabel.addClass('ring-2 ring-offset-1 ring-red-500 font-semibold');
  }
},

            handleGridChange: function (event) {
                // This function will be called when a cell value changes
                // You can update your model or perform any other actions here
            },

            handleGridRemove: function () {
                // This function will be called when the grid is being removed/destroyed
                // Perform any cleanup or additional actions here
            },
            calendarStartBtn_click: function () {
                $('#dateStartTbx').datepicker('show');
            },
            calendarEndBtn_click: function () {
                $('#dateEndTbx').datepicker('show');
            },

            onModalAcceptBtn: function () {
                this.refreshBtn_click();
            },
            bindEvents: function () {
                this.listenTo(this.itemsColl, 'backgrid:rowclick', this.processes_backgrid_rowclick)
                    .listenTo(this.itemsColl, 'fetch', this.processes_ready)
                    .listenTo(this.model, 'triggerFetch', this.refreshBtn_click);


            },
            removeHighlightRow: function () {
                var previousIndex = this.model.get('index');
                var rowsView = this.model.get('grid').body.rows;


                if (rowsView && rowsView[previousIndex] && rowsView[previousIndex].$el)
                    rowsView[previousIndex].$el.removeClass("onRightClickSelectedRow");


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

                this.model.set(fixedParams);

                this._refresh({
                    reset: true,
                    params: _.extend(
                        {},
                        fixedParams,
                        {}
                    ),
                });
            },
            render: function (container, viewParams) {
                var that = this;

                this.viewParams = viewParams;

                // Initialize the loading state
                that.model.set({isPageLoading:true});
                
                var thatContainer = (this.options.container) ? this.options.container : container;
                this.options.container = thatContainer;

                //the screens have a custompath, so it has to be specified in the customPath variable that is
                //then sent to the template loader.
                var customPath = '/app/pages/caster/' + this.template + '/';

                T.render.call(
                    this,
                    this.template,
                    function (tmp) {
                        if (!that.options.i18n) that.options.i18n = {};

                        app.getI18NJed(
                            that,
                            that.template,
                            function (i18nJED) {
                                //storing internationalization data
                                that.options.i18n[that.template] = i18nJED;

                                //loading the view and appeding it to the views's $el.
                                that.$el.html(tmp());

                                that.applyBindings();
                                that.fetchColdLengthPrintSetting();

                                var initialMode = that.model.get('printLengthMode') || 'cold';
                                that.$('input[name="printLengthMode"][value="' + initialMode + '"]').prop('checked', true);
                                that.updatePrintLengthToggleUI(initialMode);
                                that.prevPrintLengthMode = initialMode; 

                                //start: the view was already loaded an is on a div element, but not appended to the main container
                                //here you can perform anything you want DOM related, by getting the dom element via that.$el.find('#id')
                                //or this.$('#id')

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


                                // Render the AgGridModule and append it to the container
                                that.agGridModule.render();
                                that.$el.find('.processes-grid-container').append(that.agGridModule.$el);
                                
                                                               
                                //appending view to the main container
                                that.append(thatContainer, that.$el);

                                //Set model with view params here to prevent changes on the model when the view bindings are applied.
                                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.printerCode)
                                    fixedParams.printerCode = (viewParams.printerCode != '-' && viewParams.printerCode != null) ? parseInt(viewParams.printerCode, 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;
                                if (viewParams.strandId)
                                    fixedParams.strandId = (viewParams.strandId != '-' && viewParams.strandId != null) ? parseInt(viewParams.strandId, 10) : null;

                                that.model.set(fixedParams);

                                //Call first refresh.
                                var params = that.model.toJSON();

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

                                // Set loading state to false when everything is ready
                                that.model.set({isPageLoading:false});


                            },
                            true,
                            customPath
                        );
                    },
                    customPath
                );
            },
            processes_ready: function () {
                try {
                    var that = this;
                    const collectionData = that.itemsColl;
                    setTimeout(
                        function () {
                            that.agGridModule.setRowDataAsCollection(collectionData);
                            that.agGridModule.hideOverlay();  // Hide loading overlay
                            //that.agGridModule.setLoading(false);  // Hide loading overlay
                            that.model.set({
                                hasData: (that.itemsColl.length > 0),
                                isLoading: false,
                            });                      
                        },
                        100
                    );
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
                     
            search_keypress: function (e) {
                if (e.keyCode === 13) {
                    $('#search').blur();
                    this.refreshBtn_click();
                }
            },
            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);
                    that.agGridModule.showLoadingOverlay();  // Show loading overlay
                }

                this.itemsColl.fetch({
                    start: attrs.start,
                    end: attrs.end,
                    //crewId: (attrs.crewId == "") ? null : attrs.crewId,
                   // shiftId: (attrs.shiftId == "") ? null : attrs.shiftId,
                    //strandId: (attrs.strandId == "") ? null : attrs.strandId,
                    printerCode: attrs.printerCode === "1" || attrs.printerCode === "2" ? attrs.printerCode : null,
                    searchText: attrs.searchText,
                    refresh: true,
                });





            },

            exportToExcel: function () {
                var that = this,
                    params = this.model.toJSON();

                that.set({
                    isExcelExporting: true
                });
                var params = [
                    { Name: '@start', Type: 'DATETIME', Value: params.start, },
                    { Name: '@end', Type: 'DATETIME', Value: params.end, },
                    { Name: '@printer', Type: 'INT', Value: params.printerCode == "" ? null : params.printerCode, },
                ];
                var QP = new QueryParameters();

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


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

                /* -------------------------------------------------------- 1st Table ------------------------------------------------------------ */
                data.Data.push({
                    SheetName: 'Data',
                    RowsData: [{
                        CellsData:
                            [
                                { Column: 'A', Value: 'Command Type' },
                                { Column: 'B', Value: 'Heat Number' },
                                { Column: 'C', Value: 'Strand' },
                                { Column: 'D', Value: 'Product' },
                                { Column: 'E', Value: 'Grade' },
                                { Column: 'F', Value: 'Length' },
                                { Column: 'G', Value: 'Weight' },
                                { Column: 'H', Value: 'Mold Type' },
                                { Column: 'I', Value: 'Command Status' },
                                { Column: 'J', Value: 'Printer' },
                                { Column: 'K', Value: 'Timestamp' },
                                { Column: 'L', Value: 'User' },
                                { Column: 'M', Value: 'Comments' },
                                { Column: 'N', Value: 'Employee' },
                                { Column: 'O', Value: 'Reason' },

                            ],
                    }],
                    StartRowIndex: 1,
                });

                data.Data.push({
                    SheetName: 'Data',
                    RowsData: [],
                    StartRowIndex: 2,
                    DataSourceName: 'data',
                    DataSourceTableIndex: 0,
                    SQLCellsData:
                        [
                            { ExcelColumnName: 'A', SQLDataColumnName: 'TaggingCommandTypeCode', DataType: 'String' },
                            { ExcelColumnName: 'B', SQLDataColumnName: 'HeatNumber', DataType: 'String' },
                            { ExcelColumnName: 'C', SQLDataColumnName: 'StrandNumber', DataType: 'String' },
                            { ExcelColumnName: 'D', SQLDataColumnName: 'ProductNumber', DataType: 'String' },
                            { ExcelColumnName: 'E', SQLDataColumnName: 'HeatGrade', DataType: 'String' },
                            { ExcelColumnName: 'F', SQLDataColumnName: 'Length', DataType: 'String' },
                            { ExcelColumnName: 'G', SQLDataColumnName: 'Weight', DataType: 'String' },
                            { ExcelColumnName: 'H', SQLDataColumnName: 'MoldType', DataType: 'String' },
                            { ExcelColumnName: 'I', SQLDataColumnName: 'TaggingCommandStatusCode', DataType: 'String' },
                            { ExcelColumnName: 'J', SQLDataColumnName: 'Printer', DataType: 'Integer' },
                            { ExcelColumnName: 'K', SQLDataColumnName: 'Timestamp', DataType: 'String' },
                            { ExcelColumnName: 'L', SQLDataColumnName: 'User', DataType: 'String' },
                            { ExcelColumnName: 'M', SQLDataColumnName: 'Comments', DataType: 'String' },
                            { ExcelColumnName: 'N', SQLDataColumnName: 'Employee', DataType: 'String' },
                            { ExcelColumnName: 'O', SQLDataColumnName: 'Reason', 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) {                             
                            that.set({
                                isExcelExporting: true
                            });
                            console.error(Error); 
                        }
                        that.set({
                            isExcelExporting: true
                        });
                    },
                    function (resp) {
                        that.model.refreshProcesses();
                        that.set({
                            isExcelExporting: true
                        });
                        // that.model.setExportButtonExporting(false);
                        console.error(resp);
                    }
                );
            },
            processes_backgrid_rowclick: function (model) {
                try {
                    //app.router.navigate(
                    //    app.router.resolveURL(
                    //        'eaf-heat-report',
                    //        {
                    //            heatName: model.get('heatName'),
                    //        },
                    //        false
                    //    ),
                    //    { trigger: true, }
                    //);
                }
                catch (Error) { console.error(Error.stack); }
            },
            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'),
                                    printerCode: (params.printerCode == null || params.printerCode == "") ? '-' : params.printerCode,
                                    //crewId: (params.crewId == null || params.crewId == "") ? '-' : params.crewId,
                                    //shiftId: (params.shiftId == null || params.shiftId == "") ? '-' : params.shiftId,
                                    //strandId: (params.strandId == null || params.strandId == "") ? '-' : params.strandId,
                                }
                            ),
                            false
                        ),
                        { trigger: false, }
                    );

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

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

            //Common functions
            append: function (container, el) {
                el = (el != null && el != undefined) ? el : this.$el;

                if (this.options.state == app.view_states.loading
                    || this.options.state == app.view_states.shown) {
                    //appending view to the main container and set state to shown

                    this.options.state = app.view_states.shown;
                    container.append(el);

                    this.options.onappend(this);
                }

                if (this.options.state == app.view_states.hidden) {
                    //append and remain hidden
                    container.append(el);
                }

                if (this.options.state == app.view_states.closed) {
                    //return without appending.
                    return;
                }
            },
            bindViewScopedEvents: function () {
                var that = this;
            },
            unbindViewScopedEvents: function () {

            },
            close: function () {
                this.options.state = app.view_states.closed;

                this.closeSubviews();
                this.remove();
                this.unbindViewScopedEvents();
                this.unbind();
            },
            closeSubviews: function () {
                _.each(this.subviews, function (sview) {
                    sview.close();
                });
            },
            show: function () {
                this.options.state = app.view_states.shown;

                this.showSubviews();
                this.bindEvents();
                this.$el.show();
            },
            showSubviews: function () {
                _.each(this.subviews, function (sview) {
                    sview.show();
                });
            },
            hide: function () {
                this.options.state = app.view_states.hidden;

                this.hideSubviews();

                this.$el.hide();
                this.unbind();
                this.stopListening();
            },
            hideSubviews: function () {
                _.each(this.subviews, function (sview) {
                    sview.hide();
                });
            },
            preRender: function () {
                app.models.subnavbar.set("subnavbar", false);
            },
            reRender: function (viewParams) {
                try {
                    this.refresh(viewParams);
                } catch (Error) { }
            },
        });

        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: params.start, },
                        { Name: '@End', Type: 'DATETIME', Value: params.end, },
                        //{ Name: '@CrewId', Type: 'CHAR', Value: params.crewId != '-' ? params.crewId : null, },
                        //{ Name: '@ShiftId', Type: 'INT', Value: params.shiftId != '-' ? params.shiftId : null, },
                        //{ Name: '@StrandId', Type: 'INT', Value: params.strandId != '-' ? params.strandId : null, },
                        //{ Name: '@TimeZoneCode', Type: 'CHAR', Value: app.models.user.get('timezoneCode'), },
                        { Name: '@printer', Type: 'INT', Value: params.printerCode, },
                        //{ Name: '@SearchText', Type: 'VARCHAR', Value: params.searchText != '' ? params.searchText : null, },
                    ];
                }
                this.isFetching = true;

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

                //if (!options.refresh) {
                //    qp.Add('@fromRow', 'INT', (this.currentPage - 1) * this.pageSize + 1);
                //    qp.Add('@rowsToFetch', 'INT', this.pageSize - 1);
                //} else {
                //    qp.Add('@fromRow', 'INT', 0);
                //    qp.Add('@toRow', 'INT', this.currentPage * this.pageSize);
                //    qp.Add('@rowsToFetch', 'INT', this.pageSize);
                //}


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

                                if ((resp) && (resp.Table)) {
                                    //var newColl = _.map(resp.Table, that.model.prototype.parse);
                                    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);
                }
            },

        });


        //-------------------------------//
        //------ Print Tag Confirmation -------//
        //------------------------------//
        Screen.Models.PrintTagConfirmation = Backbone.Epoxy.Model.extend({
            defaults: {
                productNumber: null,
                printerId: 1,
                comments: '',
                rowModel: null,
                printers: [{ value: 1, label: 1 }, { value: 2, label: 2 }],
                reasonPhrases: null,
                employeeNumber: null,
                reasonPhraseId: 1
            },
            initialize: function () {
                var reasonPhrases =  this.fetchReasonPhrases();
                this.set('reasonPhrases', reasonPhrases);

            },
            fetchReasonPhrases: function () {
                var reasonPhrases = [];
                var qp = new Core.Database.QueryParameters();
                Core.Json.CallProcedure(
                    app.DatabaseNames.MES + '.CAS.GetTagPrintReasonPhrases',
                    qp,
                    {
                        onSuccess: function (resp) {
                            try {

                                if (resp.Table) {
                                    reasonPhrases = resp.Table.map(item => {
                                        return {
                                            value: item.ReasonPhraseId,
                                            label: item.Name
                                        };
                                    });
                                }
                                else {
                                    if ((resp) && (resp.Message)) {
                                        app.views.topMessages.showMessage(resp.Message, { stay: 5000, });
                                        console.error(resp.Message);
                                        that.set({
                                            hasData: false,
                                            isLoading: false,

                                        });

                                    }
                                    else {
                                        app.views.topMessages.showMessage("Server response not valid.", { stay: 5000, });
                                        console.error("Server response not valid.");
                                        that.set({
                                            hasData: false,
                                            isLoading: false,
                                        });
                                    }

                                }


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

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