//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',

    '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, 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'),

                heatNumber: null,
                casterCode: null,
                casters: [{ label: 'All', value: null }, { label: 'Caster 1', value: 1 }, { label: 'Caster 2', value: 2 }],

                hasData: false,
                isLoading: false,
                grid: [],
                searchText: '',
                isPageLoading: 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.Collections.Items = Backbone.Collection.extend({
            currentPage: 1,
            pageSize: 1000,
            isFetching: false,

            fetch: function (options) {
                options = options || {};
                var that = this;
                that.isFetching = true;

                var qp = new Core.Database.QueryParameters();
                if (options.start) {
                    qp.Add('@start', 'DATETIME', new moment(options.start, 'YYYY-MM-DD').utc().format('YYYY-MM-DDTHH:mm:ss') + 'Z');
                }
                if (options.end) {
                    qp.Add('@end', 'DATETIME', new moment(options.end, 'YYYY-MM-DD').utc().format('YYYY-MM-DDTHH:mm:ss') + 'Z');
                }
                if (options.heatNumber) {
                    qp.Add('@heatNumber', 'VARCHAR', options.heatNumber);
                }
                if (options.casterCode) {
                    qp.Add('@casterCode', 'INT', options.casterCode);
                }

                Core.Json.CallProcedure(
                    app.DatabaseNames.MES + '.CAS.GetUpdatedProductLengthsReport',
                    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);
                                    }
                                    that.isFetching = false;
                                }
                            }
                            catch (e) {
                                console.error((e.stack) ? e.stack : new Error(e).stack);
                                that.isFetching = false;
                            }
                        },
                        onFailure: function (resp) {
                            console.error(resp);
                            that.isFetching = false;
                        },
                        Secured: true,
                        Async: true
                    },
                    app.ConnectionStrings.app
                );
            }
        });

        var CustomAgGridModule = AgGridModule.extend({
            initialize: function (options) {
                this.bus = options.bus;
                this.itemsColl = options.itemsColl;
                this.columnDefs = [
                    { field: 'ProductIdentifier', headerName: 'Product Number', flex: 1.5, showFilter: true, cellClass: 'text-center', headerClass: 'text-center' },
                    { 
                        field: 'HeatNumber', 
                        headerName: 'Heat', 
                        flex: 1, 
                        showFilter: true, 
                        cellClass: 'text-center', 
                        headerClass: 'text-center',
                        cellRenderer: function(params) {
                            if (!params.value) return '';
                            return '<span class="heat-link" style="color: #007bff; cursor: pointer; text-decoration: underline;">' + params.value + '</span>';
                        }
                    },
                    { field: 'StrandNumber', headerName: 'Strand', flex: 0.8, showFilter: false, cellClass: 'text-center', headerClass: 'text-center' },
                    { field: 'ProductNumber', headerName: 'Product', flex: 0.8, showFilter: true, cellClass: 'text-center', headerClass: 'text-center' },
                    { 
                        field: 'OriginalLen', 
                        headerName: 'Original Length', 
                        flex: 1, 
                        showFilter: false,
                        cellClass: 'text-right',
                        headerClass: 'text-right',
                        valueFormatter: function(params) {
                            return params.value != null ? parseFloat(params.value).toFixed(2) : '';
                        }
                    },
                    { 
                        field: 'FinalLen', 
                        headerName: 'Final Length', 
                        flex: 1, 
                        showFilter: false,
                        cellClass: 'text-right',
                        headerClass: 'text-right',
                        valueFormatter: function(params) {
                            return params.value != null ? parseFloat(params.value).toFixed(2) : '';
                        }
                    },
                    { 
                        field: 'LengthDifference', 
                        headerName: 'Difference', 
                        flex: 1, 
                        showFilter: false,
                        cellClass: 'text-right',
                        headerClass: 'text-right',
                        valueFormatter: function(params) {
                            return params.value != null ? parseFloat(params.value).toFixed(2) : '';
                        },
                        cellStyle: function(params) {
                            if (params.value == null) return { textAlign: 'right' };
                            var diff = parseFloat(params.value);
                            if (diff > 0) {
                                return { color: 'green', fontWeight: 'bold', textAlign: 'right' };
                            } else if (diff < 0) {
                                return { color: 'red', fontWeight: 'bold', textAlign: 'right' };
                            }
                            return { textAlign: 'right' };
                        }
                    },
                    { 
                        field: 'LastModified', 
                        headerName: 'Last Modified', 
                        flex: 1.5, 
                        minWidth: 150, 
                        showFilter: true, 
                        fieldType: 'Datetime', 
                        format: 'MM/DD/YYYY HH:mm',
                        cellClass: 'text-center',
                        headerClass: 'text-center'
                    },
                    { 
                        field: 'TagPrinted', 
                        headerName: 'Tag Printed', 
                        flex: 0.9, 
                        showFilter: true, 
                        cellClass: 'text-center', 
                        headerClass: 'text-center',
                        cellRenderer: function(params) {
                            if (!params.value) return '';
                            var isYes = params.value === 'Yes';
                            var icon = isYes ? '<span class="tag-print-details-icon" title="View tag print details" style="cursor: pointer; margin-left: 4px; vertical-align: middle;">' +
                                '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 20 20" fill="currentColor"><path d="M10 12a2 2 0 100-4 2 2 0 000 4z"/><path fill-rule="evenodd" d="M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z" clip-rule="evenodd"/></svg></span>' : '';
                            return '<span class="tag-printed-cell">' + params.value + icon + '</span>';
                        }
                    },
                    { field: 'ModifyUser', headerName: 'Modified By', flex: 1, showFilter: true, cellClass: 'text-center', headerClass: 'text-center' },
                ];

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

                // Initialize ag-Grid
                AgGridModule.prototype.initialize.call(this, options);
            },
            onCellClicked: function(params) {
                // Handle click on HeatNumber column
                if (params.column && params.column.colDef.field === 'HeatNumber' && params.value) {
                    var heatNumber = params.value;
                    Backbone.history.navigate('!/caster-heat-report/' + heatNumber, { trigger: true });
                    return;
                }
                // Handle click on Tag Printed column (when Yes) - open details modal
                if (params.column && params.column.colDef.field === 'TagPrinted' && params.value === 'Yes' && params.data) {
                    if (this.bus) {
                        this.bus.trigger('tagPrintDetailsClick', params.data);
                    }
                    return;
                }
                
                // Call parent onCellClicked for other columns
                AgGridModule.prototype.onCellClicked.call(this, params);
            }
        });

        Screen.Views.Main = Backbone.Epoxy.View.extend({
            template: 'product-length-report',
            id: 'product-length-report',
            title: 'Product Length Report',
            events: function () {
                return {
                    'click #refreshBtn': this.refreshBtn_click,
                    'click #calendarStartBtn': this.calendarStartBtn_click,
                    'click #calendarEndBtn': this.calendarEndBtn_click,
                };
            },
            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();

                this.bus = _.extend({}, Backbone.Events);
                this.itemsColl = new Screen.Collections.Items();
                this.bindingSources = {};
                this.subviews = {};
                this.grids = {};

                // Init AgGridModule (bus must exist so grid can trigger tagPrintDetailsClick)
                this.agGridModule = new CustomAgGridModule({
                    itemsColl: this.itemsColl,
                    bus: this.bus,
                    rowData: [],
                    onChange: this.handleGridChange.bind(this),
                    onRemove: this.handleGridRemove.bind(this),
                    fileName: 'product-length-report',
                    screenTitle: 'Product Length Report',
                    isPageLoading: that.model.get('isPageLoading'),
                });

                this.bindEvents();
            },
            handleGridChange: function (event) {
                // This function will be called when a cell value changes
            },
            handleGridRemove: function () {
                // This function will be called when the grid is being removed/destroyed
            },
            calendarStartBtn_click: function () {
                $('#dateStartTbx').datepicker('show');
            },
            calendarEndBtn_click: function () {
                $('#dateEndTbx').datepicker('show');
            },
            bindEvents: function () {
                this.listenTo(this.itemsColl, 'fetch', this.processes_ready)
                    .listenTo(this.model, 'triggerFetch', this.refreshBtn_click);
                if (this.bus) {
                    this.listenTo(this.bus, 'tagPrintDetailsClick', this.showTagPrintDetailsModal);
                }
            },
            showTagPrintDetailsModal: function (data) {
                if (!data) return;
                this.$el.find('#tagDetailHeatNumber').text(data.TagHeatNumber != null ? data.TagHeatNumber : '');
                this.$el.find('#tagDetailReason').text(data.TagPrintReason != null ? data.TagPrintReason : '');
                this.$el.find('#tagDetailEmployee').text(data.TagEmployee != null ? String(data.TagEmployee) : '');
                var timestampText = '';
                if (data.TagTimestamp != null) {
                    var raw = data.TagTimestamp;
                    var dateMatch = typeof raw === 'string' && raw.match(/\/Date\((\d+)\)\//);
                    if (dateMatch) {
                        timestampText = moment(parseInt(dateMatch[1], 10)).format('MM/DD/YYYY HH:mm');
                    } else {
                        timestampText = raw;
                    }
                }
                this.$el.find('#tagDetailTimestamp').text(timestampText);
                var comments = data.TagComments != null ? String(data.TagComments).trim() : '';
                if (comments) {
                    this.$el.find('#tagDetailComments').text(comments).show();
                    this.$el.find('#tagDetailCommentsLabel').show();
                } else {
                    this.$el.find('#tagDetailComments').text('').hide();
                    this.$el.find('#tagDetailCommentsLabel').hide();
                }
                this.$el.find('#tagPrintDetailsModal').modal('show');
            },
            _refresh: function (opt) {
                this.itemsColl.reset();
                this.model.set({
                    hasData: false,
                });

                this.refreshProcesses(opt);
            },
            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.heatNumber)
                    fixedParams.heatNumber = viewParams.heatNumber;
                if (viewParams.casterCode)
                    fixedParams.casterCode = (viewParams.casterCode != '-' && viewParams.casterCode != null) ? parseInt(viewParams.casterCode, 10) : null;

                this.model.set(fixedParams);

                this._refresh({
                    refresh: true
                });
            },
            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();
                }

                this.itemsColl.fetch({
                    start: attrs.start,
                    end: attrs.end,
                    heatNumber: attrs.heatNumber || null,
                    casterCode: attrs.casterCode || null,
                    searchText: attrs.searchText,
                    refresh: true,
                });
            },
            processes_ready: function (collection, data) {
                var that = this;
                try {
                    const collectionData = that.itemsColl;
                    setTimeout(
                        function () {
                            that.agGridModule.setRowDataAsCollection(collectionData);
                            that.agGridModule.hideOverlay();  // 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);
                    this.model.set({
                        isLoading: false,
                    });
                    if (that.agGridModule && that.agGridModule.hideOverlay) {
                        that.agGridModule.hideOverlay();
                    }
                }
            },
            refreshBtn_click: function (e) {
                try {
                    var params = this.model.toJSON();
                    var urlParams = {
                        start: new moment(params.start, 'YYYY-MM-DD').format('YYYYMMDD'),
                        end: new moment(params.end, 'YYYY-MM-DD').format('YYYYMMDD'),
                    };
                    if (params.heatNumber) {
                        urlParams.heatNumber = params.heatNumber;
                    }
                    if (params.casterCode) {
                        urlParams.casterCode = params.casterCode;
                    }
                    app.router.navigate(
                        app.router.resolveURL(
                            app.router.currentModule,
                            _.extend({}, urlParams),
                            false
                        ),
                        { trigger: false, replace: true }
                    );

                    this._refresh({
                        reset: true
                    });

                    window.scrollTo(0, 0);
                }
                catch (Error) {
                    console.error(Error.stack);
                }
            },
            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/product-length-report/';

                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();

                                //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 (fixedParams.heatNumber)
                                    fixedParams.heatNumber = fixedParams.heatNumber;
                                if (fixedParams.casterCode)
                                    fixedParams.casterCode = (fixedParams.casterCode != '-' && fixedParams.casterCode != null) ? parseInt(fixedParams.casterCode, 10) : null;

                                that.model.set(fixedParams);

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

                                // Initial load
                                that.refreshProcesses({ refresh: true });
                            },
                            true,
                            customPath
                        );
                    },
                    customPath
                );
            },
            append: function (container, el) {
                el = 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);
                } else if (this.options.state == app.view_states.hidden) {
                    container.append(el);
                } else if (this.options.state == app.view_states.closed) {
                    return;
                }
            },
            onShow: function () {
                // This method is called after the view is shown
                // Most initialization is done in render()
            },
            onRemove: function () {
                if (this.agGridModule) {
                    this.agGridModule.destroy();
                }
            },
            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) { }
            }
        });

        return Screen;
    });


