(function() {
    'use strict'
    window.CApp = getApp();

    function getApp () {
        function App () {
            this.appName = 'DIDOX24';
            this.storage = {
                didoxToken: {
                    key: '__d.token',
                    limit: this._getLimit(24-1)
                },
                authId: {
                    key: '__d.authid',
                    limit: this._getLimit(6-1)
                },
                signature: {
                    key: '__d.signature',
                    limit: this._getLimit(6-1)
                },
                authInfo: {
                    key: 'auth_info',
                    limit: this._getLimit(24-1)
                },
                dealTIN: {
                    key: 'deal_tin'
                }
            }

            this.BX_DOC_PLACEMENT = 'CRM_DEAL_DOCUMENTGENERATOR_BUTTON';
            this.BX_ACTIVITY = 'ecpsign_didox';
            this.BX_ACTIVITY_FILE = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB8AAAAfCAMAAAAocOYLAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAActQTFRF////9fX17u7u8fHx8vLy+Pj4+fn5x8fHUlJSW1tb7Ozstra2GxsbYGBg0tLSExMTAQEBQ0ND/v7+9/f39vb2Y2NjPz8/BAQE4+Pj/Pz87+/vHx8fZWVlGBgYBwcH3Nzc+vr6oqKiISEhfHx8AgICPT09RkZGUVFRXV1dnJyc6enpCAgIDQ0NdXV1FBQUFxcX9PT0mJiYNTU1e3t7VVVV3d3ddHR0REREgoKC7e3tNjY2nZ2dwMDAOTk5y8vLpKSkKSkp2dnZvb29CgoKZGRkCQkJKCgoU1NT6urqmZmZLy8vR0dHERERv7+/VFRUIiIi/f39bW1tw8PD8PDw6OjotLS0AwMDBgYG+/v7sbGxzs7OoKCgLS0t1NTU6+vrvLy8QkJCi4uLYmJia2trXl5eCwsL0dHRyMjIS0tLf39/JiYm29vbNDQ0srKyTExMxsbG3t7eampqd3d3WFhYenp65+fnr6+vIyMjurq6QUFBMzMzrKysVlZW4uLiV1dXBQUFfn5+gYGBDw8P2traNzc3z8/P5eXlGhoaSEhIj4+P4eHhXFxcHBwct7e32NjYwsLCqqqqxMTEbGxsJCQknp6eMjIyWVlZ8/Pz5ubm9L5eZAAAAllJREFUeJx1k1lbE1EMhnO2YVEktCN4poBIiwtQKFQUqhUQKwgoVbCoaEUFF4qCO26ogCLuu/5cc2baPpQHb+Yi70nyJfkGABgXAJIzAM4VWJxnQ0XFJaUAm/MtW8u2lSNW+IAxv6UYU5bf+9iWRaHtWFmMiFU7KMcCzbkGxR1Tyy0jA1XVNcRrd4IQStcJWaeVkFozYWstxC6sD4aIN4jN++/GPXsJ4z5Pn8xyh7hyODQ2NYdbCLdGCEiqL4WllaT6tqT6sg3boyZ9v5Cuvo4DDQc7u/L6umJYXUE4dIh60TCHy83juGBK2cyv1BHE7somxJ5eRq/haAv2RY8lsC2nr/R4PxcDJwbDESPPN4TDJ33OqdBI0nGMPgd88vQZ8I2OmWx+NjXexp1z5xEv5PczgVUXo5doZRx4MfakaX8dKbyc55NG3RWXR1rxqhEmrk2lSasyZxibJj58ndlKwQ2cnti4v24zz01uQnALZzK2ZQYzZ/SbM9qzhMdvm5AFd3Aoqbmz/n5zKeIj89rtP4h3N973nil/v8vjI/jAvV9jJNf/oVln8yNPEjzGKBe+hSe1T3WWPzPp7TLL4/hcvVh8SaGM5y9VbYZ/lbUcvA4lYks43oeJ+WVt+lsrxANvPEkc3k6mMLQafIc1/StrjPz1foZ4id+zHClLd34IFyXLTNOlxbUBa+4jYtOn3Mpy/lqox0Ar9Z39/GUVMZi3XNZf0sp8zXybiifwe+8PXBl1Q8Zyhf73//w1wWK/l/Mh11/K/D/u4dSfeZGZ/Lsu9J//jxfoW89VIf8HChpZmBmGF5MAAAAASUVORK5CYII=';
            this.BX_ACTIVITY_FILE_NAME = 'icon.png';
            this.BX_ACTIVITY_NAME = 'Подпись ЭЦП';
            this.appBtnText = 'Отправить в DIDOX';
            this.appBtnDescription = 'Отправить в DIDOX';

            this.TIN_KEY = '';

            this.eurl = 'https://didox.4u.uz';
            this.VERSION = '0.1.46';
        }

        App.prototype = {
            init: function (func) {
                var self = this;
                var _state = 0;

                this.getAppOtions(function (info) {
                    var bxv;
                    self.setAppTinKey(info.tin_key);

                    if (typeof info === 'object' && info.version) {
                        bxv = info.version;

                        check(bxv);
                    } else {
                        self.setAppOptions({
                            version: self.VERSION,
                        }, function (res) {
                            check('');
                        });
                    }
                });

                function check (bxv) {
                    BX24.callMethod('app.info', {}, function (res) {
                        var data = res.data();
                        console.log('app.info bxv, data, self.VERSION', bxv, data, self.VERSION);
                        if (data.INSTALLED && bxv && self.checkVersion(bxv)) {
                            func();
                        } else {
                            self.setAppOptions({
                                version: self.VERSION,
                            }, function (res) {});
                            BX24.callMethod('event.bind', {
                                event: 'OnAppUninstall',
                                handler: self.getPlacementHandler() + '/uninstall.html'
                            });

                            self.bxRemoveAppFieldTin(function () {
                                self.bxCreateAppField();
                            }, function () {
                                self.bxCreateAppField();
                            });

                            self.bxUnbindAppButton(function () {
                                self.bxBindAppButton(runEvent);
                            }, function () {
                                self.bxBindAppButton(runEvent);
                            });

                            self.bxUnbindActivity(function () {
                                self.bxBindActivity(runEvent);
                            }, function () {
                                self.bxBindActivity(runEvent);
                            });
                        }
                    });
                }

                function runEvent () {
                    _state += 1;
                    console.log('runEvent', _state);
                    if (_state < 2) {
                        return;
                    }
                    console.log('runEvent finish');
                    BX24.installFinish();
                    func();
                }
            },
            uninstall: function (func) {
                var self = this;
                var _status = 0;
                console.log('uninstall start');

                this.setAppOptions({
                    version: '0.0.0',
                }, function (res) {});

                this.bxUnbindAppButton(runEvent);
                this.bxUnbindActivity(runEvent);
                this.bxRemoveAppFieldTin(runEvent);

                self.bxGetDealConfiguration(
                    function (arr) {
                        arr = arr.filter(function (a) {
                            a.name !== 'didox24';
                        });
                        self.bxCreateDealConfiguration(arr, runEvent);
                    }
                );
                BX24.callMethod('event.unbind', {
                    event: 'OnAppUninstall',
                    handler: self.getPlacementHandler() + '/uninstall.html',
                }, runEvent);

                function runEvent() {
                    _status += 1;
                    console.log('uninstall', _status);
                    if (_status < 5) {
                        return;
                    }
                    console.log('uninstall end');
                    func(2);
                }
            },

            getAppOtions: function (success) {
                BX24.callMethod('app.option.get', {}, function (res) {
                    if (res.error()) {
                        console.error(res.error());
                    } else {
                        success(res.data());
                    }
                });
            },
            setAppOptions: function (node, success) {
                BX24.callMethod('app.option.set', {
                    options: node
                }, function (res) {
                    if (res.error()) {
                        console.error(res.error());
                    } else {
                        helper.callFunc(success, res.data());
                    }
                });
            },

            bxBindAppButton: function (success) {
                console.log('placement.bind button', this.BX_DOC_PLACEMENT);
                BX24.callMethod('placement.bind',{
                    PLACEMENT: this.BX_DOC_PLACEMENT,
                    HANDLER: this.getPlacementHandler(),
                    TITLE: this.appBtnText,
                    DESCRIPTION: this.appBtnDescription,
                }, function(result) {
                    console.log('placement.bind result ', result);
                    if(result.error()) {
                        console.error(result.error());
                    } else {
                        helper.callFunc(success, result.data());
                    }
                });
            },
            bxBindActivity: function (success) {
                var self = this;
                var iconFile = this.createFile(this.BX_ACTIVITY_FILE, this.BX_ACTIVITY_FILE_NAME);
                var fields = {
                    ICON_FILE: iconFile,
                    NAME: this.BX_ACTIVITY_NAME,
                    TYPE_ID: self.getActivityKey()
                }
                console.log('crm.activity.type.add start', fields);
                BX24.callMethod('crm.activity.type.add', {
                    fields: fields
                }, function (result) {
                    console.log('crm.activity.type.add result ', result);
                    if (result.error()) {
                        console.error(result.error());
                    } else {
                        helper.callFunc(success, result.data());
                    }
                });
            },
            bxUnbindAppButton: function (success, error) {
                console.log('placement.unbind start');
                BX24.callMethod('placement.unbind',{
                    PLACEMENT: this.BX_DOC_PLACEMENT,
                    HANDLER: this.getPlacementHandler(),
                }, function(result) {
                    console.log('placement.unbind result', result);
                    if(result.error()) {
                        console.error(result.error());
                        helper.callFunc(error, result.error());
                    } else {
                        helper.callFunc(success, result.data());
                    }
                });
            },
            bxUnbindActivity: function (success, error) {
                var self = this;
                console.log('crm.activity.type.delete start');
                BX24.callMethod('crm.activity.type.delete', {
                    TYPE_ID: self.getActivityKey()
                }, function (result) {
                    console.log('crm.activity.type.delete result  ', result);
                    if (result.error()) {
                        console.error(result.error());
                        helper.callFunc(error, result.error());
                    } else {
                        helper.callFunc(success, result.data());
                    }
                });
            },
            bxRemoveAppFieldTin: function (success, error) {
                BX24.callMethod("crm.deal.userfield.list", {
                    filter: {
                        'FIELD_NAME': 'UF_CRM_' + this.getBXTinFieldName()
                    } 
                }, function(result) {
                    if(result.error()) {
                        console.error(result.error());
                        helper.callFunc(error, res.error());
                    } else {
                        var data = result.data();
                        console.log('bxRemoveAppFieldTin', data);
                        if (data[0]) {
                            BX24.callMethod("crm.deal.userfield.delete", { 
                                id: data[0].ID 
                            }, function(res) {
                                    if(res.error()) {
                                        console.error(res.error());
                                        helper.callFunc(error, res.error());
                                    } else {
                                        helper.callFunc(success, res.data());
                                    }
                                }
                            );
                        } else {
                            helper.callFunc(success, result.data());
                        }
                    }
                }
                );
            },

            getPlacementHandler: function () {
                return location.origin + location.pathname;
            },

            uiGetFullDate: function () {
                return 'DD.MM.YYYY HH:mm';
            },
            didoxDateFormat: function () {
                return 'YYYY-MM-DD';
            },

            loadFile: function (url, callback) {
                var xhr = new XMLHttpRequest();
                xhr.onload = function() {
                    var reader = new FileReader();
                    reader.onloadend = function() {
                        callback(reader.result);
                    }
                    reader.readAsDataURL(xhr.response);
                };
                xhr.open('GET', url);
                xhr.responseType = 'blob';
                xhr.send();
            },

            getDocId: function (description) {
                return description.replace(/\[|\]/g, '');
            },

            showDoc: function (b64) {
                var embed = document.createElement('embed');

                $(embed).css({
                    'height': '98vh',
                    'overflow-y': 'hidden'
                });
                $('.app').html(embed);

                embed.setAttribute('src', b64);
            },

            setBxDocValues: function (doc, values, success, error) {
                BX24.callMethod('crm.documentgenerator.document.update', {
                    id: doc.id,
                    values: values
                }, function(result) {
                    if(result.error()) {
                        console.error(result.error());
                    } else {
                        doc.values = result.data().document.values
                        success({
                            document: doc
                        });
                    }
                });
            },
            addActivity: function (doc, text, success) {
                BX24.callMethod('crm.activity.add', {
                    fields: {
                        OWNER_TYPE_ID: doc.entityTypeId,
                        OWNER_ID: doc.entityId,
                        PROVIDER_ID: 'REST_APP',
                        PROVIDER_TYPE_ID: this.getActivityKey(),
                        SUBJECT: text,
                        COMPLETED: 'Y',
                        RESPONSIBLE_ID: 1,
                        DESCRIPTION: this.getActivityDescription(doc),
                    }
                }, function(result) {
                    if(result.error()) {
                        console.log("Error: " , result.error());
                    } else {
                        success();
                    }
                });
            },

            isDocCreated: function (doc) {
                if (doc.values[this.getB24DocId()]) {
                    return true;
                }
                return false;
            },
            isDocSign: function (doc) {
                if (doc.values[this.getB24DicSign()] == '1') {
                    return true;
                }
                return false;
            },

            showMessage: function (msg) {
                alert(msg);
            },

            createFile: function (dataurl, filename) {
                console.log('createFile', dataurl, filename);
                var arr = dataurl.split(','),
                    mime = arr[0].match(/:(.*?);/)[1],
                    bstr = atob(arr[1]),
                    n = bstr.length,
                    u8arr = new Uint8Array(n);

                while (n--) {
                    u8arr[n] = bstr.charCodeAt(n);
                }
                var file = new File([u8arr], filename, {type:mime});

                return {
                    tagName: 'INPUT',
                    type: 'file',
                    nodeType: 1,
                    files: [file],
                    cloneNode: function () {
                        return true
                    }
                };
            },

            checkSavedData: function (sData, limit) {
                return sData.data && this.checkValid(new Date(), sData.date, limit);
            },
            checkValid: function (currentDate, savedDate, limit) {
                var res = currentDate - savedDate;

                if (limit <= res) {
                    return false;
                }
                return true;
            },

            /**
             * get saved tokens datas
             * @returns {Array}
             */
            getAuthTokens: function () {
                var keys = AppStorage.getItems(), result = [];

                keys.forEach(val => {
                    if (!val.match('__d.token')) {
                        return;
                    }
                    result.push({
                        key: val,
                        serialNumber: val.replace(/__d.token_|__d.token/, '')
                    });
                });

                return result;
            },

            checkVersion: function (bxVersion) {
                var bxv = bxVersion.split('.');
                var appv = this.VERSION.split('.');
                var result = true;
                var previ = -1;

                appv.forEach(function (value, index) {
                    var appn = value*1;
                    var bxn = bxv[index]*1;

                    if (appn > bxn) {
                        if (previ < index) {
                            previ = index;
                            result = false;
                        }
                    }

                });

                return result;
            },

            eventRegist: function (method, params, success, fail) {
                $.ajax({
                    url: this.eurl,
                    data: {
                        method: method,
                        params: params
                    },
                    method: 'post',
                    dataType: 'json',
                    success: function (res) {
                        helper.callFunc(success, res);
                    },
                    error: function (res) {
                        helper.callFunc(fail, res);
                    }
                });
            },

            getDomain: function () {
                BX24.getDomain();
            },
            getAppName: function () {
                return this.appName;
            },
            getActivityDescription: function (doc) {
                return '['+doc.id+']';
            },

            getDocSignText: function (doc) {
                return 'Подписан документ: ' + doc.id;
            },
            getDocSignRemoveText: function (doc) {
                return 'Удаление документ: ' + doc.id;
            },


            bxCreateAppField: function () {
                var self = this;
                console.log('crm.deal.userfield.add start');
                BX24.callMethod('crm.deal.userfield.add', this.getBXTinFiledOptions(), function (res) {
                    if (res.error()) {
                        console.error(res.error());
                    } else {
                        var id = res.data();
                        console.log('crm.deal.userfield.add end', id);

                        self.setAppOptions({
                            tin_key: 'UF_CRM_'+ self.getBXTinFieldName()
                        });
                        self.setAppTinKey('UF_CRM_'+ self.getBXTinFieldName());

                        self.bxGetDealConfiguration(
                            function (arr) {
                                console.log('bxGetDealConfiguration', arr);
                                if (!self.checkDealConfuguration(arr)) {
                                    arr.push({
                                        name: 'didox24',
                                        title: 'DIDOX24',
                                        type: 'section',
                                        elements: [{ 
                                            name: 'UF_CRM_' + self.getBXTinFieldName()
                                        }]
                                    });
                                    console.log('bxGetDealConfiguration 2', arr);
                                    self.bxCreateDealConfiguration(arr);
                                }
                            }
                        );
                    }
                });
            },
            checkDealConfuguration: function (arr) {
                var result = false;
                arr.forEach(function (el) {
                    if (el.name === 'didox24') {
                        result = true;
                    }
                });
                return result;
            },
            bxGetDealConfiguration: function (success, error) {
                BX24.callMethod('crm.deal.details.configuration.get', {
                    scope: "C"
                }, function (result) {
                    if(result.error()) {
                        helper.callFunc(error, result.error());
                    } else {
                        helper.callFunc(success, result.data());
                    }
                });
            },
            bxCreateDealConfiguration: function (arr, success, error) {
                var data = {
                    scope: 'C',
                    data: arr
                }
                console.log('bxCreateDealConfiguration', data);
                BX24.callMethod('crm.deal.details.configuration.set', data, function(result) {
                    if(result.error())
                        console.error(result.error());
                    else
                        console.dir(result.data());
                });
            },

            getBXTinFiledOptions: function () {
                return {
                    "ID": "",
                    "ENTITY_ID": "CRM_DEAL",
                    "FIELD_NAME": this.getBXTinFieldName(),
                    "USER_TYPE_ID": "string",
                    "EDIT_FORM_LABEL": this.getBXTimFieldTitle(),
                    "LIST_COLUMN_LABEL": this.getBXTimFieldTitle(),
                    "XML_ID": null,
                    "SORT": "100",
                    "MULTIPLE": "N",
                    "MANDATORY": "N",
                    "SHOW_FILTER": "E",
                    "SHOW_IN_LIST": "Y",
                    "EDIT_IN_LIST": "Y",
                    "IS_SEARCHABLE": "N",
                    "SETTINGS": {
                        "SIZE": 20,
                        "ROWS": 1,
                        "REGEXP": "",
                        "MIN_LENGTH": 0,
                        "MAX_LENGTH": 0,
                        "DEFAULT_VALUE": null
                    }
                }
            },
            getBXTimFieldTitle: function () {
                return 'ИНН (Узбекистан)';
            },
            getBXTinFieldName: function () {
                return 'BX_APP_DIDOX24_TIN';
            },


            /**
             * @public get didox id from bx doc data
             * @param {Object} doc
             * @returns {String}
             */
            getDiDocId: function (doc) {
                if (this.isDocCreated(doc)) {
                    return doc.values[this.getB24DocId()];
                }

                return '';
            },

            /**
             * @param key {String}
             * @returns {void}
             */
            setAppTinKey: function (key) {
                console.log('tin key ->', key);
                self.TIN_KEY = key;
            },

            /**
             * @returns {string}
             */
            getSavedTinKey: function () {
                return self.TIN_KEY;
            },

            /**
             * @returns {string}
             */
            getDealTIN: function () {
                // global var deal
                var key = this.getSavedTinKey();
                if (typeof deal !== 'object' || !key) {
                    return '';
                }
                return deal[key];
            },



            /**
             * @public getB24DocId - key in bx doc [values] where saved didox doc id
             * @returns
             */
            getB24DocId: function () {
                return 'DIDOX_DOC_ID';
            },
            /**
             * @public getB24DicSign - key in bx doc [values] where saved didox doc id
             * @returns {String}
             */
            getB24DicSign: function () {
                return 'DIDOX_DOC_IS_SIGN';
            },

            /**
             * @public resurn bx crm activity key
             * @returns
             */
            getActivityKey: function () {
                return this.BX_ACTIVITY;
            },
            getDocPdfUrl: function (doc) {
                return doc.pdfUrlMachine;
            },



            _getLimit(h) {
                return h * 60 * 60 * 1000;
            }

        }

        return App;
    }
})();