import extend from './extend.js';
import token from './token.js';
import result from './result.js';
import ResultData from './resultData.js';
import Tone from './tone.js';
import url from './url.js';

/**
 * 基础链接存储键
 */
const baseUrlKey = 'base_url';

/**
 * 基础链改变标记接存储键
 */
const baseUrlChangedKey = 'base_url_changed';

/**
 * 发送请求集合
 */
const sendMap = new Map();

/**
 * 提示音
 */
const tone = new Tone();

/**
 * 网络请求
 */
const request = {
    /**
     * 设置基础地址
     * @param {string} url - 基础地址
     */
    async setBaseUrl(url) {
        if (!extend.isString(url)) {
            url = '';
        }
        extend.addStorage(baseUrlKey, url);
    },

    /**
     * 获取基础地址
     */
    async getBaseUrl() {
        return url.apiUrl;
        // return extend.readStorage(baseUrlKey);
    },

    /**
     * 网络请求
     * @param {Object} opts - 请求参数
     * @param {string} opts.url - 请求地址
     * @param {string} opts.method - 请求方法，合法值：get、post、put、delete，默认 get，默认 get
     * @param {string} opts.type - 发送数据类型，合法值：json、xml、text、form、url、blob，默认 json
     * @param {string} opts.dataType - 接收数据类型，如果设为json，会尝试对返回的数据做一次 JSON.parse，默认 json
     * @param {string} opts.responseType - 响应数据类型，合法值：text、arraybuffer，默认 text
     * @param {Object} opts.data - 请求参数
     * @param {Object} opts.header - 请求头
     * @returns {ResultData} 结果对象
     */
    send(opts) {
        return new Promise(async (resolve, reject) => {
            if (!extend.isObject(opts)) {
                resolve({
                    success: false,
                    message: '参数不能为空'
                });
                return;
            }
            let data = null;
            let url = '';
            let baseUrl = await request.getBaseUrl();

            try {
                if (extend.isUrl(opts.url)) {
                    url = opts.url;
                } else {
                    if (extend.isEmptyString(baseUrl)) {
                        resolve({
                            success: false,
                            message: '未设置 BaseUrl'
                        });
                        return;
                    } else {
                        url = baseUrl + opts.url;
                    }
                }
                if (!extend.isObject(opts.header)) {
                    opts.header = {};
                }
                switch (opts.type) {
                    case 'xml':
                        opts.header['content-type'] = 'application/xml; charset=utf-8';
                        break;
                    case 'text':
                        opts.header['content-type'] = 'text/plain; charset=utf-8';
                        break;
                    case 'form':
                        opts.header['content-type'] = 'multipart/form-data; boundary=something';
                        break;
                    case 'url':
                        opts.header['content-type'] = 'application/x-www-form-urlencoded';
                        break;
                    case 'blob':
                        opts.header['content-type'] = 'text/plain';
                        break;
                    case 'json':
                    default:
                        opts.header['content-type'] = 'application/json';
                }
                if (extend.isEmptyString(opts.method)) {
                    opts.method = 'get';
                }

                /* 调试代码-记得删除 */
                // uni.hideLoading();
                // return console.log('sendData', opts.data);
                /* 调试代码-记得删除 */

                // 存储访问次数
                let mapValue = sendMap.get(url);
                if (extend.isNumber(mapValue)) {
                    mapValue++;
                } else {
                    mapValue = 1;
                }
                sendMap.set(url, mapValue);

                // 发送访问请求
                uni.request({
                    url: url,
                    method: opts.method || 'get',
                    dataType: opts.dataType || 'json',
                    responseType: opts.responseType || 'text',
                    header: opts.header || {},
                    data: opts.data,
                    timeout: 300000,
                    async success(res) {
                        let mapValue = sendMap.get(url);
                        if (mapValue > 2) {
                            sendMap.delete(url);
                            let errRes = result.get(res);
                            return resolve(new ResultData({
                                success: false,
                                message: `状态码：${res.statusCode}\n${errRes.message}\n${url}`
                            }));
                        }
                        if (res.statusCode === 401) {
                            let r = await token.getByServer();
                            if (r.success) {
                                res = await request.sendToken(opts);
                            } else {
                                tone.playDing();
                                return resolve(new ResultData({
                                    success: false,
                                    message: r.message
                                }));
                            }
                        }
                        sendMap.delete(url);
                        res = result.get(res);
                        if (!res.success) {
                            tone.playDing();
                        }
                        resolve(new ResultData({
                            success: res.success,
                            message: res.message,
                            statusCode: res.statusCode,
                            data: res.data
                        }));
                    },
                    fail(ex) {
                        tone.playDing();
                        console.error(ex);
                        sendMap.delete(url);
                        ex = extend.errorFormatter(ex);
                        resolve(new ResultData({
                            success: false,
                            message: ex.message
                        }));
                    }
                });
            } catch (ex) {
                tone.playDing();
                sendMap.delete(url);
                let err = extend.errorFormatter(ex);
                console.error(ex);
                resolve(new ResultData({
                    success: false,
                    message: err.message,
                }));
            }
        });
    },

    /**
     * Token 网络请求
     * 在 header 中带 Authorization 参数。
     * @param {Object} opts - 请求参数
     * @param {string} opts.url - 请求地址
     * @param {string} opts.method - 请求方法，默认 get
     * @param {Object} opts.data - 请求参数
     * @param {Object} opts.header - 请求头
     * @returns {RequestResult} 网络请求结果对象
     */
    async sendToken(opts) {
        if (!extend.isObject(opts)) {
            return {
                success: false,
                message: '参数不能为空'
            };
        }
        let tokenStr = token.get();
        if (extend.isNonEmptyString(tokenStr)) {
            opts.header = {
                Authorization: tokenStr
            };
        }
        return await this.send(opts);
    }
};

/**
 * 网络请求
 */
export default request;