/// <reference path="http://localhost/IHBOX/IndustrialDashboard/Scripts/IndustrialDashboard-debug.js" />
define([
  // Application.
    "app",

    "moment", 

  //templates-loader
  "js/templates-loader"

],

function (app, moment, T) {

    var IHDataSourcesDropdown = { Models: {}, Views: {}, Collections: {} }

    IHDataSourcesDropdown.init = function (ctx, module, app) {
        //app.models.ihDataSources = new module.Models.Main();

        //Used timeout to prevent extended delay when the first screen is loaded
        //Unknown issue cause
        //setTimeout(function () { app.models.ihDataSources.start(); }, 1000);
    }; 

    IHDataSourcesDropdown.Models.IHDataSource = Backbone.Epoxy.Model.extend({
        default: {
            id: null,
            name: null,
            isLocal: false,
            default: false,
            lastDataReceived: null,
        }, 
        computeds: {
            label: {
                deps: ["name"],
                get: function (name) {
                    return name; 
                }
            }, 
            value: {
                deps: ["id"],
                get: function (id) {
                    return id;
                }
            }, 
        }, 
    }); 

    IHDataSourcesDropdown.Collections.IHDataSources = Backbone.Collection.extend({
        model: IHDataSourcesDropdown.Models.IHDataSource,
        fetch: function (opt) {
            var that = this;
            var QP = new Core.Database.QueryParameters();

            opt = _.extend({
                async: true, 
            }, opt); 

            if (app.models.user.get("timezoneIsAutomatic")) {
                QP.Add("TimeZone", "CHAR", app.models.user.get("timezoneCode"));
            }
            //QP.Add("Timezone", "VARCHAR", app.models.user.get("timezoneCode"));

            Core.Json.CallProcedure(app.DatabaseNames.System + ".FrontEnd.GetIHDataSources", QP, {
                onSuccess: function (data) {
                    if (data && data.Table) {
                        var items = data.Table;

                        that.set(_.map(items, function (m) {
                            return {
                                id: m.Id,
                                name: m.Name,
                                isLocal: m.IsLocal,
                                default: m.Default,
                                lastDataReceived: m.LastDataReceived,
                            };
                        }), { from: "fetch" }); 

                        if (opt && opt.callback && _.isFunction(opt.callback))
                            opt.callback.call(that, that, data);
                    }
                },
                onError: function () {
                    if (e && e.callback && _.isFunction(e.callback))
                        e.callback.call(that, that, "error");
                },
                Async: opt.async,
                Secured: false,
            }, app.ConnectionStrings.app);
        }
    }); 

    IHDataSourcesDropdown.Models.Main = Backbone.Epoxy.Model.extend({
        defaults: {
            id: null,
            localId: null, 
            ihDataSourcesNoLocal: [], 
            hasDataSources: false,  
            isOutdated: false, 
            lastTimeFetched: null, 
        },

        //outdated settings
        outdatedWhenDataOlderThanSeconds: 60 * 15, //120, 

        i18n: { global: null, },
        toid: null,
        delay: 3 * 1000,
        refreshing: false,
        firstLoad: true, 
        ihDataSources: null,

        computeds: {
            allowDataInput: {
                deps: ["isLocal"], 
                get: function (isLocal) {
                    return isLocal ? true : false; 
                }
            },
            isLocal: {
                deps: ["id", "localId"],
                get: function (id, localId) {
                    return (id == localId);
                },
            },
            //localId: {
            //    deps: ["ihDataSources"],
            //    get: function (ihDataSources) {
            //        var ds = _.findWhere(ihDataSources, { isLocal: true, });

            //        return (ds != null)
            //                ? ds.id
            //                : null;
            //    },
            //},
            //ihDataSourcesNoLocal: {
            //    deps: ["ihDataSources"],
            //    get: function (items) {
            //        return _.where(items, { isLocal: false, })
            //    },
            //}, 
            //hasDataSources: {
            //    deps: ["ihDataSources"], 
            //    get: function (items) {
            //        return _.isArray(items) && items.length > 0; 
            //    }, 
            //}, 
        },
        initialize: function () {
            this.firstLoad = true;
            this.ihDataSources = new IHDataSourcesDropdown.Collections.IHDataSources(); 

            this.bindEvents(); 
        },
        _computeLocalId: function (ihDataSources) {
            var localId = null;
            var ihds = ihDataSources.findWhere({ isLocal: true });

            if (ihds != null && ihds != undefined && ihds.get) { localId = ihds.get("id"); }
            return localId; 
        }, 
        _computeHasDataSources: function (ihDataSources) {
            return ihDataSources != null && ihDataSources.length > 0; 
        },
        _computeIHDataSourcesNoLocal: function (ihDataSources) {
            return ihDataSources.where({ isLocal: false, }).map(function(t){
                return { label: t.get("name"), value: t.get("id") }
            }); 
        },
        _computeIsOutdated: function () {
            var isOutdated = false; 
            var ihdss = this.ihDataSources; 
            var id = this.get("id");

            var ihds = ihdss.findWhere({ id: id });
            if (_.isObject(ihds) && ihds.get) {
                var ldr = ihds.get("lastDataReceived"); 
                if (ldr != null) {
                    var now = app.models.navBarClock.get("date"); 
                    if (!now) {
                        app.models.navBarClock.syncWithServer({ async: false });
                        now = app.models.navBarClock.get("date");
                    }
                    now = new moment(now); 
                    var ldrm = new moment(ldr);
                    isOutdated = (now.diff(ldrm, "seconds") > this.outdatedWhenDataOlderThanSeconds); 
                }
            }

            return isOutdated; 
        }, 
        ihDataSourcesChanged: _.debounce(function(a, b, c) {
            var ihDataSources = this.ihDataSources; 
            this.set({
                localId: this._computeLocalId(ihDataSources),
                hasDataSources: this._computeHasDataSources(ihDataSources),
                ihDataSourcesNoLocal: this._computeIHDataSourcesNoLocal(ihDataSources),
                isOutdated: this._computeIsOutdated(), 
            })
        }, 1), 
        idChanged: function (a, b, c, d) {
            var fromDefault = (_.isObject(c) && _.isBoolean(c.fromDefault)) ? c.fromDefault : false; 

            //saving id selected
            if (!fromDefault){
                localStorage.setItem("ihdatasources-dropdown-id-selected", this.get('id'));
            }
        }, 
        bindEvents: function () {
            var that = this; 

            this.listenTo(this.ihDataSources, "change", _.bind(this.ihDataSourcesChanged, this)); 
            this.listenTo(this.ihDataSources, "add", _.bind(this.ihDataSourcesChanged, this)); 
            this.listenTo(this.ihDataSources, "remove", _.bind(this.ihDataSourcesChanged, this)); 
            this.listenTo(this.ihDataSources, "reset", _.bind(this.ihDataSourcesChanged, this));
            this.listenTo(this, "change:id change:lastTimeFetched", _.debounce(function () { that.set({ isOutdated: that._computeIsOutdated() }); }, 50)); 
            this.listenTo(this, "change:id", _.bind(this.idChanged, this)); 
        }, 
        fetch: function (opt) {
            try {
                var that = this;

                this.ihDataSources.fetch({
                    async: (this.firstLoad) ? false : true,
                    callback: function (ctx, data) {
                        that.set({ lastTimeFetched: new Date().getTime() }); 

                        if (that.firstLoad) {
                            that.checkDefault();
                            that.firstLoad = false;
                        }

                        if (opt && opt.callback && _.isFunction(opt.callback))
                            opt.callback.call(that, that, data);
                    }
                }); 
            }
            catch (Error) { console.error(Error); }
            finally {
            }

            return this;
        },
        checkDefault: function () {
            var dflt = null; 
            try{
                var idSelected_ls = localStorage.getItem('ihdatasources-dropdown-id-selected');
                if (idSelected_ls != null && idSelected_ls != undefined && _.isString(idSelected_ls)) {
                    var parsedId = null;
                    try { parsedId = parseInt(idSelected_ls); } catch (e) { parsedId = null; }

                    if (parsedId != null){
                        var ls_item = this.ihDataSources.findWhere({
                            id: parsedId
                        }); 

                        if (_.isObject(ls_item) && ls_item.get) {
                            dflt = ls_item; 
                        }
                    }
                }

                if (!dflt){
                    dflt = this.ihDataSources.findWhere({ default: true });
                }

                if (!this.get("id") && _.isObject(dflt) && dflt.get) {
                    this.set("id", dflt.get("id"), { fromDefault: true }); 
                }
            } catch (error) {
                console.log("Something went wrong while trying to get default selected IHDatasource. ");
                try { localStorage.setItem("ihdatasources-dropdown-id-selected", ""); } catch (e) { }
            }
        }, 
        start: function () {
            if (!this.refreshing) {
                this.refresh(); 
            }
            return this;
        },
        refresh: function () {
            var that = this; 
            clearTimeout(this.toid);
            this.refreshing = true; 

            this.fetch({
                callback: function () {
                    that.refreshing = false;
                    that.toid = setTimeout(_.bind(that.refresh, that), that.delay);
                }
            });
        }, 
        restart: function () {
            this.stop();
            this.set(this.defaults);
            this.firstLoad = true; 
            this.start(); 
        }, 
        stop: function () {
            clearTimeout(this.toid);

            this.refreshing = false;

            return this;
        },
    }); 

    IHDataSourcesDropdown.Views.Main = Backbone.Epoxy.View.extend({
        id: "ihdatasources-dropdown"
        , template: "ihdatasources-dropdown"
        , isCacheable: false
        , initialize: function () {
            this.options = {}; 

            //_.bindAll(this);

            //binding model-view events (all models and views should be created BEFORE calling to this function
            this.bindEvents();
        },
        render: function (container) {
            var that = this;
            //var thatContainer = container;
            
            var customPath = "/app/modules/ihdatasources-dropdown/";

            T.render.call(this, this.template, function (tmp) {
                //getInternationalizationData
                if (!that.options.i18n) that.options.i18n = {};
                app.getI18NJed(that, that.template, function (i18nJED) {
                    //storing internationalization data
                    that.options.i18n[that.template] =
                    that.model.i18n.global = i18nJED;

                    //start: before the view is visible, but the template was already loaded (not instanced nor appended)

                    //end:
                    //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")

                    //:end

                    //appending view to the main container
                    //thatContainer.append(that.$el);
                }, true, customPath);
            }, customPath); 
        }
        , outdatedChanged: function () {
            var elem = $(".slow-ihdatasource-connection"); 
            var outdated = this.model.get("isOutdated");
            var selected = this.model.ihDataSources.findWhere({ id: this.model.get("id") }); 
            var lastDataReceived = null; 

            if (_.isObject(selected) && selected.get) {
                if (_.isString(selected.get("lastDataReceived"))){
                    lastDataReceived = new moment(selected.get("lastDataReceived")); 
                }
            }

            var tmp = Handlebars.compile(elem.find("#slow-ihdatasource-connection-msg-template").html()); 
            elem.find(".slow-ihdatasource-connection-msg").html(tmp({
                lastDataReceived: ((_.isObject(lastDataReceived) && _.isFunction(lastDataReceived.format))
                    ? lastDataReceived.local().format("YYYY-MM-DD HH:mm:ss") : "-"),  
            })); 

            if (outdated) {
                elem.show();
                $("body").css("padding-top", (parseInt($("body").css("padding-top")) + 40) + "px");
                $(".fixed-subnavbar").css("top", (parseInt($(".fixed-subnavbar").css("top")) + 40) + "px");
            }
            else
            {
                elem.hide();
                $("body").css("padding-top", (parseInt($("body").css("padding-top")) - 40) + "px");
                $(".fixed-subnavbar").css("top", (parseInt($(".fixed-subnavbar").css("top")) - 40) + "px");
            }
        }
        , bindEvents: function () {
            this.listenTo(this.model, "change:isOutdated", this.outdatedChanged);
        }
    });

    // Required, return the module for AMD compliance.
    return IHDataSourcesDropdown;

});
