import utils from "./utils";

//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;
    }

    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);
        if (!this._header['Content-Type']) {
            this.xmlHTTPRequest.setRequestHeader('Content-Type', 'application/' + (method == 'POST' || method == 'PUT' ? 'json' : 'text'));
        }
        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')) {
            if (this._header['Content-Type'] && this._header['Content-Type'].indexOf('application/x-www-form-urlencoded;') != -1 ) {
                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('&');
            } else {
                sendBody = JSON.stringify(this._data);
            }
        }
        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 (utils.readLocalstorage('uid')) {
            request.header({
                'uid': utils.readLocalstorage('uid')
            });
        }
        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;