/**
 * Created by rockyl on 2019-11-22.
 */

import { injectProp, obj2query } from "./utils";

/**
 * http请求
 * @param url
 * @param method
 * @param params
 * @param type
 * @param headers
 */
export function httpRequest(url: string, method: string = 'get', params?: any, type: 'text' | 'json' | 'jsonp' = 'text', headers?) {
    let openUrl = url.indexOf('blob') === 0 ? url : urlJoin(url, '__ts__=' + Date.now());
    let mParams = {};
    injectProp(mParams, params);

    return new Promise((resolve, reject) => {
        let mHeaders = {
            'Content-Type': 'application/x-www-form-urlencoded',
        };
        injectProp(mHeaders, headers);

        let request = { url, method, params: mParams, type, headers: mHeaders };

        const mock = window['mock'];
        let mockRule;
        if (mock) {
            mock(request, (rule) => {
                mockRule = rule;
                if (!mockRule) {
                    doRequest(request, resolve, reject);
                }
            }, resolve, reject);
        } else {
            request.url = openUrl;
            doRequest(request, resolve, reject);
        }
    });
}

function doProxyRequest(payload, resolve, reject) {
    let proxyWindow = window['proxy_window'];
    window.addEventListener('message', onMessage, false);

    proxyWindow.postMessage(JSON.stringify({
        action: 'http-request-proxy',
        payload: payload,
    }), '*');

    function onMessage(event) {
        window.removeEventListener('message', onMessage);
        try {
            let data = JSON.parse(event.data);
            console.log('onMessage', event.data);

            switch (data.action) {
                case 'http-request-proxy-resolve':
                    resolve(data.payload);
                    break;
                case 'http-request-proxy-reject':
                    reject(data.payload);
                    break;
            }
        } catch (e) {

        }
    }
}

function doXhrRequest({ url, method, params, type, headers }, resolve, reject) {
    let xhr;
    if (window["XMLHttpRequest"]) {
        xhr = new XMLHttpRequest();
    } else if (window["ActiveXObject"]) {
        xhr = new window["ActiveXObject"]();
    } else {
        console.log('no xhr');
    }
    if (xhr != null) {
        const isGet = method.toUpperCase() === 'GET';
        const queryStr = obj2query(params);
        let openUrl = url;
        if (openUrl.indexOf('projectx') == 0) {
            openUrl = '/' + openUrl;
        }
        if (isGet) {
            openUrl = urlJoin(openUrl, queryStr);
        }
        xhr.open(method, openUrl, true);
        for (let key in headers) {
            xhr.setRequestHeader(key, headers[key]);
        }
        xhr.responseType = type;
        xhr.onreadystatechange = () => {
            if (xhr.readyState == 4 && xhr.status == 200) {
                resolve(xhr.response)
            }
        };
        xhr.onerror = (reason): void => {
            reject(reason)
        };
        xhr.onloadend = (): void => {
            if (xhr.status == 404) {
                reject(url + ' 404 (Not Found)')
            }
        };
        if (isGet) {
            xhr.send();
        } else {
            xhr.send(queryStr);
        }
    }
}

function doRequest(payload, resolve, reject) {
    if (window['proxy_window'] && payload.url.indexOf('blob') !== 0) {
        doProxyRequest(payload, function (p) {
            resolve(p);
        }, reject);
    } else {
        doXhrRequest(payload, resolve, reject);
    }
}

export function urlJoin(url, query) {
    if (query) {
        url += url.indexOf('?') < 0 ? '?' : '';
        url += url[url.length - 1] === '?' ? '' : '&';
        return url + query;
    } else {
        return url;
    }
}
