({
    plugins: ['Dashlet', 'Tooltip'],

    events: {
        'click .enlarge': 'enlargeClicked',
    },

    // Current reportId
    reportId: null,
    reportData: null,
    elementId: null,

    // Endpoint URL's
    getReportsEndpoint: 'AnalyticReporting/GetReports',
    getWidgetEndpoint: 'AnalyticReporting/GetWidget?reportId=',

    store: null,

    /**
     * Initialize the View
     *
     * @constructor
     * @param {Object} options
     */
    initialize: function(options) {
        // Callbacks should access this, so bind this to all methods
        _.bindAll(this, "renderChart");
        // _.bindAll.apply(_, [this].concat(_.functions(this)));
        this.isManager = app.user.get('is_manager');
        this._super('initialize', [options]);
    },

    /**
     * Init dashlet settings
     */
    initDashlet: function() {
        // Validation handling for individual fields on the config
        this.layout.before('dashletconfig:save', function() {
            // Fields on the metadata
            var fields = _.flatten(this.dashletConfig.config.fields);

            // Grab all non-valid fields from the model
            var notValid = _.filter(fields, function(field) {
                return field.required && !this.dashModel.get(field.name);
            }, this);

            // If there no invalid fields we are good to go
            if (notValid.length === 0) {
                return true;
            }

            // Otherwise handle notification of invalidation
            _.each(notValid, function(field) {
                var fieldOnView = _.find(this.fields, function(comp, cid) {
                    return comp.name === field.name;
                });

                fieldOnView.model.trigger('error:validation:' + field.name, {required: true});
            }, this);

            // False return tells the drawer that it shouldn't close
            return false;
        }, this);
    },

    /**
     * Special case for reportId field rendering
     * TODO: In future this should be moved in config
     */
    _renderField: function(field, $fieldEl) {
        var self = this;

        // TODO: Must find better "Sugar" way for this solution
        // Special case for choosing reports
        if(field.name === "reportId") {
            App.progress.start();
            app.api.call('GET', app.api.buildURL(this.getReportsEndpoint), null, {
                success: function (data) {
                    if (this.disposed) {
                        App.progress.cancel();
                        return;
                    }

                    // Set report options as select options
                    App.progress.done();

                    field.items = data;
                    self._super("_renderField", [field, $fieldEl]);
                },
            });
        } else {
            // Render other fields
            self._super("_renderField", [field, $fieldEl]);
        }
    },

    /**
     * @inheritdoc
     */
    bindDataChange: function() {
        var self = this;
        if (!this.meta.config) {
            // Load report and render chart when changing report by select bar
            this.settings.on('change:reportId', function(model) {
                self.loadReportData(null, model.get('reportId'), self.renderChart);
            });
        }
    },

    /*
     * Perform chart render if container was resized
     */
    resize: function () {
        if (!this.reportData || !this.$el || !this.elementId) return;

        this.store = null;

        this._renderChart(this.elementId, this.$el, this.reportData);
    },

    /**
     * Load ReportData from API endpoint
     */
    loadData: function(options) {
        if (this.disposed || this.meta.config) {
            return;
        }

        // Load data and render chart when completed
        this.loadReportData(
            options,
            this.settings.get('reportId'),
            this.renderChart
        );
    },


    /**
     * Load report from endpoint and run callback when completed
     */
    loadReportData: function(options, reportId, callback) {
        var self = this;

        App.progress.start();
        app.api.call('GET', app.api.buildURL(this.getWidgetEndpoint + reportId), null, {
            /**
             * On successfully retrieved data event
             */
            success: function (data) {
                if (this.disposed) {
                    App.progress.cancel();
                    return;
                }

                App.progress.done();
                callback(data);
            },
            error: function (data) {
                if (this.disposed) {
                    App.progress.cancel();
                    return;
                }

                App.progress.done();
                self.renderErrorMessage(reportId, data.message);
            },
            complete: options ? options.complete : null,
        });
    },

    /**
     * Generic method to render chart with check for visibility and data.
     * Called by _renderHtml and loadData.
     */
    renderChart: function(reportData) {
        // Set chart title from chaart title or from report title
        var title = reportData.title;
        if(reportData.chartTitle && reportData.chartTitle.length > 0) {
            title = reportData.chartTitle;
        }
        this.layout.setTitle(title);

        // Set current reportId
        this.reportId = reportData.id;
        this.reportData = reportData;

        if (!this.meta.config) {
            // Wrap title with link to report
            var title = this.layout.$('h4.dashlet-title').text();
            var url = this.dashletConfig.config.openReportUrl + reportData.id;

            // Dirty fix for enlarging charts (open in popup window)
            // var height = jQuery(window.parent).height() - (jQuery(window.parent).height() / 3);
            // var width = jQuery(window.parent).width() - (jQuery(window.parent).width() / 3);
            // var popupUrl = this.dashletConfig.config.openWidgetUrl + this.reportId;
            // var enlarge = ' <a class="fa fa-arrows-alt enlarge" href="javascript:window.open(\''+popupUrl+'\',  \'_blank\', \'height='+height+',width='+width+'\')"></a>';
            var chartTitle = '<a href="'+ url +'" target="_blank">' + title + '</a>';
            // this.layout.setTitle(chartTitle);
            this.layout.$el.find("h4").first().html(chartTitle);
        }

        $el = this.$el.find(".ar-chart:first");

        /**
         * If store is not defined, then chart is not rendered
         * and we should render it.
         *
         * If store is defined, then update chart
         */
        if(this.store) {
            // At now this does nothing
            console.log("Chart should be refreshed.");
        } else {
            if (!this.elementId) this.elementId = $el.prop('id');

            if (!this.elementId) return;

            // Render chart first time
            this._renderChart(this.elementId, $el, reportData);
        }

        // bind resize event to widget
        let debouncedResize = _.bind(_.debounce(this.resize, 100), this);
        $(window).on('resize.' + this.cid, debouncedResize);
    },

    /**
     * Render chart on element with reportData
     * @param $el
     * @param reportData
     * @private
     */
    _renderChart: function(elementId, $el, reportData) {
        if(!window.ARWidgetApp) {
            console.log("window.ARWidgetApp is not defined.");
            return;
        }

        const height = $el ? (this.layout.$el.height() - 38) : 0;
        const width  = $el.width();

        $('#' + this.elementId).css({
            height: this.layout.$el.height() - 36,
            margin: '0 8px',
        });

        this.store = window.ARWidgetApp(elementId, reportData, width, height);
    },

    /**
     * Render error message in chart DIV container with link to report.
     * Called by loadReportData.
     */
    renderErrorMessage: function(reportId, errorMessage) {
        var url = this.dashletConfig.config.openReportUrl + reportId;
        try {
            $el = this.$el.find(".ar-chart:first");
            var a = $("<a />")
                .attr('href', url)
                .text(errorMessage);
            var div = $("<div />")
                .css({
                    height: "100%",
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "center"
                });
            a.appendTo(div.appendTo($el));
        } catch(e) {
            console.log("Couldn't render error message for reportId: " + reportId);
        }
    },

    /**
     * Open report chart in new window
     */
    enlargeClicked: function(e) {
        console.log("clicked enlarge",e);
        var height = jQuery(window.parent).height() - (jQuery(window.parent).height() / 3);
        var width = jQuery(window.parent).width() - (jQuery(window.parent).width() / 3);
        var url = this.dashletConfig.config.openWidgetUrl + this.reportId;
        var popup = window.open(url,"Enlrage",'height='+height+',width='+width);
    }
})