(function () {
    window.CDidox = getDidoxAPI();

    function getDidoxAPI () {
        function DidoxAPI () {
            // this.URL = 'https://devapi.goodsign.biz';
            this.URL = 'https://api.goodsign.biz';
            this.API_KEY = '';
            this.USER_KEY = '';
        }
    
        DidoxAPI.prototype = {
            /**
             * get didox api token
             * @param {Object} node 
             * @returns {void}
             */
            loadToken: function (node, success, error, fail) {
                var self = this;

                this._call({
                    method: 'post',
                    url: this._getUrl('/v1/auth/login'),
                    data: node,
                    dataType: 'json',
                    success: function (data) {
                        if (typeof data === 'object' && data.token) {
                            success(data);
                        } else {
                            error(data);
                        }
                    },
                    error: function (data) {
                        if (self._ifFailed(data)) {
                            fail(data);
                        } else {
                            error(data);
                        }
                    }
                });
            },
            loadTokenByTin: function (tin, node, success, error, fail) {
                var self = this;

                this._call({
                    url: this._getUrl('/waltz/goodsign/0.0.1/user/{tin}/token', {
                        tin: tin
                    }),
                    data: node,
                    method: 'post',
                    success: function (data) {
                        if (typeof data === 'string') {
                            success(data);
                        } else {
                            error(data);
                        }
                    },
                    error: function (data) {
                        if (self._ifFailed(data)) {
                            fail(data);
                        } else {
                            error(data);
                        }
                    }
                });
            },


            createDoc: function (docType, node, success, error, fail) {
                var self = this;

                this._call({
                    method: 'post',
                    url: this._getUrl('/v1/documents/{docType}/create', {
                        docType: docType
                    }),
                    data: node,
                    headers: this.getHeaders(),
                    dataType: 'json',
                    success: function (data) {
                        if (self._checkData(data)) {
                            success(data);
                        } else {
                            error(data);
                        }
                    },
                    error: function (data) {
                        if (self._ifFailed(data)) {
                            fail(data);
                        } else {
                            error(data);
                        }
                    }
                });    
            },
            getDoc: function (docId, success, error, fail) {
                var self = this;
                this._call({
                    method: 'get',
                    url: this._getUrl('/v1/documents/{docId}', {
                        docId: docId
                    }),
                    dataType: 'json',
                    headers: this.getHeaders(),
                    success: function (data) {
                        if (typeof data === 'object' && data.data) {
                            success(data);
                        } else {
                            error(data);
                        }
                    },
                    error: function (data) {
                        if (self._checkErrorData(data)) {
                            fail(data);
                        } else {
                            error(data);
                        }
                    }
                });
            },
            signDoc: function (documentId, node, success, error, fail) {
                var self = this;

                this._call({
                    url: this._getUrl('/v1/documents/{documentId}/sign', {
                        documentId: documentId
                    }),
                    data: node,
                    method: 'post',
                    dataType: 'json',
                    headers: this.getHeaders(),
                    success: function (data) {
                        if (typeof data === 'object' && data.data) {
                            success(data);
                        } else {
                            error(data);
                        }
                    },
                    error: function (data) {
                        if (self._ifFailed(data)) {
                            fail(data);
                        } else {
                            error(data);
                        }
                    }
                });
            },

            delateDoc: function (docId, data, success, error, fail) {
                var self = this;
                this._call({
                    url: this._getUrl('/v1/documents/{documentId}/delete', {
                        documentId: docId
                    }),
                    data: data,
                    method: 'post',
                    headers: this.getHeaders(),
                    success: function (res) {
                        if (typeof res === 'object' && res.data) {
                            success(res);
                        } else {
                            error(res);
                        }
                    },
                    error: function (res) {
                        if (self._ifFailed(res)) {
                            fail(res);
                        } else {
                            error(res);
                        }
                    }
                });
            },
            deleteDocInDraf: function (docId, success, error, fail) {
                var self = this;
                this._call({
                    url: this._getUrl('/v1/documents/{documentId}/delete/draft', {
                        documentId: docId
                    }),
                    method: 'post',
                    headers: this.getHeaders(),
                    success: function (res) {
                        if (typeof res === 'object' && res.data) {
                            success(res);
                        } else {
                            error(res);
                        }
                    },
                    error: function (res) {
                        if (self._ifFailed(res)) {
                            fail(res);
                        } else {
                            error(res);
                        }
                    }
                });
            },


            docTosign: function (docId, data, success, error, fail) {
                var self = this;
                this._call({
                    url: this._getUrl('/v1/documents/{docId}/tosign', {
                        docId: docId
                    }),
                    method: 'post',
                    data: data,
                    headers: this.getHeaders(),
                    success: function (res) {
                        if (typeof res === 'object' && res.data) {
                            success(res);
                        } else {
                            error(res);
                        }
                    },
                    error: function (res) {
                        if (self._ifFailed(res)) {
                            fail(res);
                        } else {
                            error(res);
                        }
                    }
                });
            },

            getTimestamp: function (data, success, error, fail) {
                var self = this;
                this._call({
                    url: this._getUrl('/v1/dsvs/gettimestamp'),
                    method: 'post',
                    data: data,
                    dataType: 'json',
                    headers: this.getHeaders(),
                    success: function (res) {
                        if (typeof res === 'object' && res.success) {
                            success(res);
                        } else {
                            error(res);
                        }
                    },
                    error: function (res) {
                        if (self._ifFailed(res)) {
                            fail(res);
                        } else {
                            error(res);
                        }
                    }
                });
            },

            getInfoByTaxId: function (taxId, success, error, fail) {
                var self = this;
                this._call({
                    method: 'get',
                    url: this._getUrl('/v1/profile/{taxId}', {
                        taxId: taxId
                    }),
                    dataType: 'json',
                    success: function (data) {
                        if (typeof data === 'object' && !data.error) {
                            success(data);
                        } else {
                            error(data);
                        }
                    },
                    error: function (data) {
                        if (self._ifFailed(data)) {
                            fail(data);
                        } else {
                            error(data);
                        }
                    }
                });
            },
            loadAuthId: function (serialNumber, success, error, fail) {
                var self = this;

                this._call({
                    method: 'get',
                    url: this._getUrl('/v1/auth/authId/{serialNumber}', {
                        serialNumber: serialNumber
                    }),
                    dataType: 'json',
                    success: function (data) {
                        if (typeof data === 'object' && data.authId) {
                            success(data);
                        } else {
                            error(data);
                        }
                    },
                    error: function (data) {
                        if (self._ifFailed(data)) {
                            fail(data);
                        } else {
                            error(data);
                        }
                    }
                });    
            },
            getHeaders: function () {
                return {
                    'user-key': this.USER_KEY,
                };
            },
            _checkData: function (data) {
                return typeof data === 'object' && !data.error && data.status !== 'error';
            },
            _ifFailed: function (data) {
                return data.status === 500;
            },


            setApiKey: function (key) {
                this.API_KEY = key;
            },
            setUserKey: function (key) {
                this.USER_KEY = key;
            },

            _call: function (params) {
                $.ajax(params);
            },
    
            /**
             * @private _getUrl
             * @param {String} url 
             * @param {Object|undefined} val
             * @returns {String}
             */
            _getUrl: function (url, vals) {
                var current = url, keys = [];

                if (vals) {
                    keys = Object.keys(vals);

                    keys.forEach(function (key) {
                        var value = vals[key];
                        var reg = new RegExp('{'+key+'}', 'g');
                        current = current.replace(reg, value);
                    });
                }
                return this.URL + current;
            },
        }
    
        return DidoxAPI;
    }
})()