//http 网络请求封装类(和业务相关的代码请不要写进这个类中)
// import UserDataStorage from './UserDataStorage';

class efunRequest {

    constructor() {
        this._url = '';
        this._params = {};
        this._data = {};
        this._header = {};
        this.xmlHTTPRequest = null;
        this._onSuccess = null;
        this._onFailed = null;
        this._deserialize = null;
        // 异步获取的
        this.uid = storage.load({
            key: 'uid'
        })
    }

    request(method) {

        const paramStr = () => {
            if (!this._params) {
                return ''
            }
            var pstr = '';
            for (let key in this._params) {
                pstr += `${key}=${this._params[key]}&`;
            }
            return pstr.slice(0, -1);
        }

        this.xmlHTTPRequest = new XMLHttpRequest();
        this.xmlHTTPRequest.open(method, this._url + '?' + paramStr(), true);
        this.xmlHTTPRequest.setRequestHeader('Content-Type', 'application/' + (method == 'POST' || method == 'PUT' ? 'x-www-form-urlencoded' : 'text'));
        this.xmlHTTPRequest.setRequestHeader('uid', this.uid ? this.uid : '');


        for (let key in this._header) {
            this.xmlHTTPRequest.setRequestHeader(key, this._header[key]);
        }

        this.xmlHTTPRequest.onreadystatechange = () => {
            this.whenResponse();
        }

        var sendBody = null;
        if (this._data && (method == 'POST' || method == 'PUT')) {
            var arr = new Array();
            var i = 0;
            for (var attr in this._data) {
                arr[i] = encodeURIComponent(attr) + '=' + encodeURIComponent(this._data[attr]);
                i++;
            }
            sendBody = '&' + arr.join('&');
        }
        this.xmlHTTPRequest.send(sendBody);
        return this;
    }

    get() {
        this.request('GET');
        return this;
    }

    post() {
        this.request('POST');
        return this;
    }

    put() {
        this.request('PUT');
        return this;
    }

    delete() {
        this.request('DELETE');
        return this;
    }

    whenResponse() {
        if (this.xmlHTTPRequest.readyState != 4) {
            return;
        }

        if (this._deserialize) {
            this._deserialize(this.xmlHTTPRequest.responseText, this);
            return;
        }

        let cb = this.xmlHTTPRequest.status == 200 ? this._onSuccess : this._onFailed;
        if (!cb) {
            return;
        }
        cb(this.xmlHTTPRequest.status, this.xmlHTTPRequest.responseText);
    }

    success(callback) {
        this._onSuccess = callback;
        return this;
    }

    fail(callback) {
        this._onFailed = callback;
        return this;
    }

    header(obj, rewrite) {
        if (rewrite) {
            this._header = obj;
        } else {
            for (let key in obj) {
                this._header[key] = obj[key];
            }
        }
        return this;
    }

    params(obj) {
        this._params = obj;
        return this;
    }

    data(obj) {
        this._data = obj;
        return this;
    }

    url(str) {
        this._url = str;
        return this;
    }

    responseDeserialize(func) {
        this._deserialize = func;
        return this;
    }

    static getHttpRequest() {
        let request = new efunRequest();
        // if (UserDataStorage.getToken()) {
        //     request.header({
        //         'Authentication': UserDataStorage.getToken()
        //     });
        // }
        request.responseDeserialize(function (res, req) {
            function callFailed(data) {
                if (req._onFailed) {
                    req._onFailed(data);
                }
            }

            function callSuccess(data) {
                if (req._onSuccess) {
                    req._onSuccess(data);
                }
            }

            let rObj = null;
            try {
                rObj = JSON.parse(res);
            } catch (e) {
                callFailed(e);
                return;
            }
            if (req.xmlHTTPRequest.status != 200) {
                callFailed(rObj);
                return;
            }
            if (!rObj.success) {
                callFailed(rObj);
                return;
            }
            callSuccess(rObj);
        });
        return request;
    }
}

export default efunRequest;