odoo.define('jd_dashboard.dashboardWidget', function (require) {
    'use strict';

    String.prototype.jdgSimpleJSTemplate = function(data){

        var js = '';
        if(Array.isArray(data)){
              var self = this;
              data.forEach(function(item){
                     var pattern,
                           str = self;
                     Object.keys(item).forEach(function(key){
                          pattern = new RegExp('\\$'+key+'\\$', 'g');
                          str = str.replace(pattern, JSON.stringify(item[key]));
                     });
                    js += str;
             });
        }
        return js;
    }

    var core = require('web.core');
    var Dialog = require('jd_dashboard.inputDialog');
    var Model = require('web.Model');
    var crash_manager = require('web.crash_manager');

    var Widget = require('web.Widget');

    var QWeb = core.qweb;
    var _t = core._t;

    var DashboardWidget = Widget.extend({

        init: function (parent, title, channel_id) {
            // console.log('init')
            this._super(parent, title, channel_id);
            this.gridStack = null;
            this.locked = true;
            this.saveBtnPane = null;
            this.cardCount = 0;
            this.initCode = {};
            this.initData = {};
        },
        start: function () {
            // console.log('start')
            // this.action_id = this.$el.context.baseURI.match(new RegExp('action=([\\s\\S]*)'))[1]
            this.$el.append(QWeb.render("DashboardPageTemplate"), this);
            var self = this;
            setTimeout(function () {
                self.saveBtnPane = $(".jdg-edit-ctrl");
                self.gridStack = self.initGrid();
                self.gridStack.disable();
                self.loadConfig(self.action_id);
                self.bindEvent();
            }, 50);
            this.$el.attr('id', 'jdg-dashboard');
        },


        destroy: function () {
            // console.log('destroy')
            this._super.apply(this, arguments);
        },

        initGrid: function () {
            this.action_id = this.$el.context.baseURI.match(new RegExp('action=([\\s\\S]*)'))[1]
            // console.log(window.location.hash)
            // console.log('initGrid')
            var options = {};
            $('.grid-stack').gridstack(options);
            var result = $('.grid-stack').data('gridstack');
            jscolor.installByClassName('jdg-edit-background-btn')
            return result;
        },

        addElement: function (serializedData) {
            // console.log('addElement')
            var self = this;
            self.gridStack.removeAll();
            self.cardCount = 0;
            for (var i in serializedData) {
                self.cardCount += 1;
                var node = serializedData[i].config_based;
                var elementId = 'e-id-' + self.cardCount;
                var pageData = {
                    title: node.title || '',
                    id: node.id,
                    elementId: elementId,
                    sourceId: node.sourceId,
                    widgetType: node.widgetType,
                }
                var elementHtml = QWeb.render('DashboardPageElement', pageData);
                self.gridStack.addWidget(elementHtml,
                    node.x, node.y, node.width, node.height);
                self.loadWidgetData(node.id, elementId, (function(node, elementId, configAdvanced, self) {
                    return function() {
                        if(node.widgetType == '4' && node.text) {
                            // console.log('yessss')
                            // console.log(node.text)
                            $('.jdg-editable-text').html(node.text);
                        }
                        // 执行实例初始化代码
                        var echartName = elementId.replace(/([^-])(?:-+([^-]))/g, function ($0, $1, $2) {
                                        return $1 + $2.toUpperCase();
                                    });
                        // console.log(configAdvanced)
                        // console.log(elementObj)
                        var widgetObj = self[echartName]
                        if(configAdvanced && widgetObj) {
                            new Function('widgetObj', configAdvanced)(widgetObj);
                        }
                    }
                })(node, elementId, serializedData[i].config_advanced, self));
            }

        },

        loadConfig: function (action_id) {
            // console.log('loadConfig')
            var self = this;
            var dashboardConfigModel = new Model("jd.dashboard.kpi.view");
            dashboardConfigModel.call('load_items', [{'action_id': action_id}]).then(function (result) {
                if(result.items) {
                    // console.log(result.items)
                    var items = _.sortBy(result.items, function(value) {
                        return value.config_based.index;
                    });
                    // console.log(items)
                    self.addElement(items);
                }
                if(result.background_style) {
                    $('#valueElement').html(result.background_style)
                    $('#jdg-dashboard').attr('style', 'background-color: #' + result.background_style)
                }
                self.gridStack.disable();
                self.bindRemoveEvent();
            });
        },

        /**
         * 加载数据
         * @param widgetId 部件id
         * @param elementId 页面元素id
         */
        loadWidgetData: function (widgetId, elementId, LoadedFunc) {
            // console.log('loadWidgetData')
            var self = this;
            var widgetModel = new Model("jd.dashboard.widget");
            widgetModel.call('get_data', [{'widget_id': widgetId}]).then(function (result) {
                $('#' + elementId).attr('data-widget-type', result['type'])
                if (result['type'] == '0') {
                    var title = result['title'];
                    var k = $("#" + elementId).find(".jdg-card-title");
                    $("#" + elementId).find(".jdg-card-title").text(title);
                    self.addListData(result['data'], result['header'], elementId)
                }
                else if(result['type'] == '1') {
                    // 图表类型
                    // 记录初始化代码
                    self.initCode[elementId] = result['init_code']

                    // 记录初始化数据
                    if(result['init_data']) {
                        // console.log(elementId + '存在初始化数据: ' + result['init_data'])
                        self.initData[elementId] = result['init_data']
                    }
                    // 查找数据来源
                    // console.log('数据来源: ' + $('#' + elementId).attr('data-source-id'))
                     // 渲染元素
                    var dataSourceId = $('#' + elementId).attr('data-source-id');
                    if(dataSourceId != -1) {
                        crash_manager.disable();
                        var resultBefore = result
                        new Model("jd.dashboard.widget.data").call('get_data_by_id', ['{"id":' + dataSourceId + "}"]).then(function (result) {
                            new Model(result['model'])
                                .call(result['method'], result['param'])
                                .fail(function(error, event) {
                                    console.log('数据获取错误，采用实例默认数据！')
                                    // console.log(result['data_default'])
                                    if (result['data_default']) {
                                        try {
                                            self.renderDashboardElement(elementId, JSON.parse(result['data_default']))
                                        }
                                        catch (e) {
                                            console.log(e)
                                            console.log('实例数据获取错误，采用控件默认数据！')
                                        }
                                    }
                                    else {
                                        console.log('实例数据获取错误，采用控件默认数据！')
                                        self.renderDashboardElement(elementId, JSON.parse(resultBefore['init_data']))
                                    }
                                    // crash_manager.enable();
                                })
                                .done(function(data) {
                                    self.renderDashboardElement(elementId, data)
                                })
                        })
                    }
                    else {
                        self.renderDashboardElement(elementId, JSON.parse(result['init_data']))
                    }

                }
                else if(result['type'] == '4') {
                    // 文字部件
                    self.initCode[elementId] = result['init_code']
                    self.renderDashboardElement(elementId)
                }
                // 回调
                if(LoadedFunc && typeof LoadedFunc === "function") {
                    LoadedFunc();
                }
            });
        },

        /**
         * 添加列表型部件
         * @param dataList
         * @param titleDict
         */
        addListData: function (dataList, titleDict, elementId) {
            // console.log('addListData')
            var html = "<ul style='padding-left:0px !important;list-style:none;'>"
            var index = 0;
            for (var index = 0; index < dataList.length; index++) {
                var item = dataList[index];
                var itemTxt = "";
                for (var key in item) {
                    if (key == 'id') {
                        continue;
                    }
                    var val = item[key];
                    if (Array.isArray(val)) {
                        val = val[1];
                    }
                    itemTxt += val;
                }
                html = html + "<li style='text-align: left;'>" + itemTxt + "</li>";
            }
            html = html + "</ul>";
            $("#" + elementId).find(".jdg-card-content").html(html);
        },

        bindEvent: function () {
            // console.log('bindEvent')
            var self = this;
            $(".jdg-edit-btn").unbind('click').click(function (e) {
                self.saveBtnPane.show();
                self.gridStack.enable();
                $(".jdg-delete-element-img").show();
                $(".jdg-change-element-data").show();
                $(".jdg-change-size").show();
                $(".jdg-edit-btn").hide()
                self.bindTextEditableEvent();
            })
            self.gridStack.disable();
            self.saveBtnPane.hide();
            $(".jdg-edit-add-card").hide();
            $(".jdg-delete-element-img").hide();
            $(".jdg-change-element-data").hide();
            $(".jdg-change-size").hide();

            $(".jdg-btn-cancel").unbind('click').click(function (e) {
                self.gridStack.disable();
                self.saveBtnPane.hide();
                $(".jdg-edit-add-card").hide();
                $(".jdg-delete-element-img").hide();
                $(".jdg-change-element-data").hide();
                $(".jdg-change-size").hide();
                self.loadConfig(self.action_id);
                $(".jdg-edit-btn").show();
                self.unbindTextEditableEvent();
            });
            $(".jdg-btn-save").unbind('click').click(function (e) {
                if($('.jdg-editable-text.clicked').length) {
                    $('.jdg-editable-text.clicked').find(`input[value='保存']`).click();
                }
                var items = self.getSerializedData();
                items = _.indexBy(items, function(value, index){
                    value.index = index;
                    return value.name;
                })
                // console.log(items);
                var backgroundStyle = $('#valueElement').html()
                var dashboardConfigModel = new Model("jd.dashboard.kpi.view");
                dashboardConfigModel.call('create_or_update', [{'action_id': self.action_id, 'items': items, 'background_style': backgroundStyle}]).then(function (result) {
                    self.gridStack.disable();
                    self.saveBtnPane.hide();
                    $(".jdg-edit-add-card").hide();
                    $(".jdg-delete-element-img").hide();
                    $(".jdg-change-element-data").hide();
                    $(".jdg-change-size").hide();
                    $(".jdg-edit-btn").show();
                    self.unbindTextEditableEvent();
                });
            });

            $(".jdg-edit-add-card-btn").unbind('click').click(function (e) {
                $(".jdg-edit-add-card").show();
                $(".jdg-delete-element-img").show();
                $(".jdg-change-element-data").show();
                $(".jdg-change-size").show();
                $(".jdg-edit-add-card").css('display', 'flex');
                self.updateWidgetList();
            });

        },

        bindRemoveEvent: function () {
            // console.log('bindRemoveEvent')
            var self = this;
            $(".jdg-delete-element-img").unbind('click').click(function (e) {
                var a = $(this).parent();
                self.gridStack.removeWidget(a);
            });
            $(".jdg-change-element-data").unbind('click').click(function (e) {
                var element = this;
                try {
                    var elementDataId = $(this).parent().attr('data-id');
                    var elementId = $(this).parent().attr('id');
                    var sourceId = $(this).parent().attr('data-source-id');
                    var dashboardDataModel = new Model("jd.dashboard.widget.data");
                    dashboardDataModel.call('get_data_list', ['{"widget_id":' + elementDataId + "}"]).then(function (result) {
                        result['sourceId'] = sourceId;
                        Dialog.inputDialog(self, result, {
                            confirm_callback: function() {
                                var selected = $(".selectpicker").find("option:selected").attr("index")
                                if(selected == '-1') {
                                    if(sourceId != selected) {
                                        $(element).parent().attr('data-source-id', "-1")
                                        // 渲染初始数据
                                        // console.log(self.initData[elementId])
                                        self.renderDashboardElement(elementId, JSON.parse(self.initData[elementId]))
                                    }
                                    return;
                                }
                                crash_manager.disable();
                                new Model(result[selected]['model'])
                                    .call(result[selected]['method'], result[selected]['param'])
                                    .fail(function(error, event) {
                                        // crash_manager.enable();
                                        console.log('数据获取错误，采用实例默认数据！')
                                        // console.log(result[selected]['data_default'])
                                        if (result[selected]['data_default']) {
                                            try {
                                                $(element).parent().attr('data-source-id', result[selected]['id'])
                                                self.renderDashboardElement(elementId, JSON.parse(result[selected]['data_default']))
                                            }
                                            catch (e) {
                                                console.log(e)
                                                console.log('实例数据获取错误，采用控件默认数据！')
                                            }
                                        }
                                        else {
                                            console.log(e)
                                            console.log('实例数据获取错误，采用控件默认数据！')
                                        }
                                    })
                                    .then(function(data) {
                                        crash_manager.enable();
                                        // 重新给来源元素赋值
                                        $(element).parent().attr('data-source-id', result[selected]['id'])
                                        // 根据新数据重新渲染部件
                                        self.renderDashboardElement(elementId, data)
                                    })
                                }
                        });
                    })
                }
                catch (e) {
                    console.log('服务器数据获取错误！')
                    console.log(e)
                }
            });

            $(".jdg-change-size").unbind('click').click(function (e) {
                var element = $(this).parent();
                try {
                    var elementX = element.attr('data-gs-x');
                    var elementY = element.attr('data-gs-y');
                    var elementWidth = element.attr('data-gs-width');
                    var elementHeight = element.attr('data-gs-height');
                    Dialog.changeSizeDialog(self, {"elementX": elementX, "elementY": elementY, "elementWidth": elementWidth, "elementHeight": elementHeight}, {
                            confirm_callback: function() {
                                var newElementX = parseInt($('#newX').val());
                                var newElementY = parseInt($('#newY').val());
                                var newElementWidth = parseInt($('#newWidth').val());
                                var newElementHeight = parseInt($('#newHeight').val());
                                // 根据新尺寸重新渲染echarts部件
                                self.gridStack.update(element[0], newElementX, newElementY, newElementWidth, newElementHeight)
                            }
                        })
                }
                catch (e) {
                    console.log('服务器数据获取错误！')
                    console.log(e)
                }
            });
        },

        unbindTextEditableEvent: function() {
            $('.jdg-editable-text').unbind('click');
        },

        bindTextEditableEvent: function() {
            $('.jdg-editable-text').unbind('click').click(function() {
                if ($(this).hasClass('btn_clicked')) {
                    $(this).removeClass('btn_clicked');
                } else if (!$(this).hasClass('clicked')) {
                    $(this).addClass('clicked');
                    var strContent = $(this).html();
                    strContent = '<form><textarea>' + strContent + '</textarea>';
                    strContent += '<input type="button" value="保存" />&nbsp;';
                    strContent += '<input type="button" value="取消" />&nbsp;';
                    strContent += '<input type="reset" value="重置" /></form>';
                    $(this).html(strContent);
                    $(':button').click(function() {
                        var _this = $(this);
                        var strOnBtn = _this.val();
                        var textarea = $('textarea');
                        var str = textarea.val();
                        var blnUnbind = true;
                        if ('Cancel' == strOnBtn) {
                            $(':reset').trigger('click');
                            str = textarea.val();
                        } else if ('Save' == strOnBtn && str.length == 0) {
                            blnUnbind = false;
                            alert('Please input some words!!!');
                        }
                        if (blnUnbind) {
                            _this.unbind('click');
                            var p = $('.jdg-editable-text');
                            p.html(str);
                            p.removeClass('clicked');
                            p.addClass('btn_clicked');
                        }
                    });
                }
            });
        },

        // 根据id渲染部件
        renderDashboardElement: function(elementId, data) {
            var self = this;
            var dataTmp = {
                'elementId': elementId,
            }
            var dataTmpList = []
            if(data) {
                dataTmp = _.extend(dataTmp, data)
            }
            dataTmpList.push(dataTmp)
            var initCode = self.initCode[elementId].jdgSimpleJSTemplate(dataTmpList)
            var echartName = elementId.replace(/([^-])(?:-+([^-]))/g, function ($0, $1, $2) {
                                return $1 + $2.toUpperCase();
                            });
            self[echartName] = new Function(initCode)();
        },

        getSerializedData: function () {
            // console.log('getSerializedData')
            var serializedData = $.map($('.grid-stack > .grid-stack-item:visible'), function (el) {
                el = $(el);
                var dataId = parseInt(el.attr('data-id') || 0);
                var dataTitle = el.attr("data-title" || '');
                var node = el.data('_gridstack_node');
                var dataSourceId = el.attr('data-source-id');
                var dataWidgetType = el.attr('data-widget-type');
                var text = el.find('.jdg-editable-text').html();
                var element_id = el.attr('id');
                return {
                    name: element_id,
                    x: node.x,
                    y: node.y,
                    width: node.width,
                    height: node.height,
                    id: dataId,
                    title: dataTitle,
                    sourceId: dataSourceId,
                    widgetType: dataWidgetType,
                    text: text || ''
                };
            });
            return serializedData;
        },

        updateWidgetList: function () {
            var self = this;
            var page = 0;
            // console.log('updateWidgetList')
            $(".jdg-edit-add-card").html("");
            var widgetModel = new Model("jd.dashboard.widget");
            widgetModel.call('get_widget_list', [{'page': page}]).then(function (result) {
                // console.log(result.length)
                for(var i = 0; i < result.length; i++){
                    var item = result[i];
                    var elementHtml = QWeb.render('WidgetList', item);
                    $(".jdg-edit-add-card").append(elementHtml);
                }
                self.rebindWidgetCardEvent();
            });
        },


        rebindWidgetCardEvent: function () {
            var self = this;
            // console.log('rebindWidgetCardEvent')
            $(".jdg-edit-add-card-item").click(function (e) {
                self.cardCount += 1;
                var elementId = 'e-id-' + self.cardCount;
                var title = $(this).attr('data-title');
                var widgetId = $(this).attr('data-id');
                var sourceId = $(this).attr('data-source-id');
                var dataWidgetType = $(this).attr('data-widget-type');
                var dataWidthDefault = $(this).attr('data-default-width');
                var dataHeightDefault = $(this).attr('data-default-height');
                var pageData = {
                    title: title || '',
                    id: widgetId,
                    elementId: elementId,
                    sourceId: sourceId,
                    widgetType: dataWidgetType,
                    widthDefault: dataWidthDefault,
                    heightDefault: dataHeightDefault,
                }
                var elementHtml = QWeb.render('DashboardPageElement', pageData);
                self.gridStack.addWidget(elementHtml,
                    0, 0, dataWidthDefault, dataHeightDefault, true);
                self.loadWidgetData(widgetId, elementId);
                self.bindRemoveEvent();
                $(".jdg-delete-element-img").show();
                $(".jdg-change-element-data").show();
                $(".jdg-change-size").show();
            });
        }


    });


    core.action_registry.add('jd_dashboard.dashboardWidget', DashboardWidget);

    return DashboardWidget;

});


