import { storeGet } from '../store';
import logMsgWithSentry from '../helpers/logMsgWithSentry';
import { isEmpty } from 'ramda';

export class NetworkService {

    static logApiError = (endpoint, status = 0, resp = {}) => {
        if (status === 500) {
            logMsgWithSentry(endpoint, status, resp);
        } else if (status === 403) {
            /*storeSet('token', '');
            const { pathname } = window.location;
            if (!['/login', '/registration', '/loginadmin', '/reset-password-admin', '/confidi', '/reset-password'].includes(pathname)) {
                window.location.replace('/login');
            }*/
        }
    }

    static post = (url, body, callback, errorCallback, queryParams) => {
        url = this.buildUrl(url, queryParams);

        fetch(url, {
            method: 'POST',
            mode: 'cors',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + storeGet('getToken'),
            },
            body: JSON.stringify(body)
        })
            .then(async response => {
                let status = response.status;
                this.logApiError(url, status);
                return { response: await response.json(), status: status }
            })
            .then(data => {
                if (data.status >= 400 && data.status <= 599) {
                    errorCallback(data.response)
                    this.logApiError(url, data.status, data.response);
                } else {
                    callback(data.response)
                }
            })
            .catch(err => errorCallback(err));
    };

    static postMultiPart = (url, body, callback, errorCallback, queryParams) => {
        url = this.buildUrl(url, queryParams);

        fetch(url, {
            method: 'POST',
            mode: 'cors',
            headers: {
                'Authorization': 'Bearer ' + storeGet('getToken'),
            },
            body: body
        })
            .then(async response => {
                let status = response.status;
                this.logApiError(url, status);
                return { response: await response.json(), status: status }
            })
            .then(data => {
                if (data.status >= 400 && data.status <= 599) {
                    errorCallback(data.response)
                    this.logApiError(url, data.status, data.response);
                } else {
                    callback(data.response)
                }
            })
            .catch(err => errorCallback(err));
    };

    static postBlob = (url, body, callback, errorCallback, queryParams) => {
        url = this.buildUrl(url, queryParams);

        fetch(url, {
            method: 'POST',
            mode: 'cors',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + storeGet('getToken'),
            },
            body: JSON.stringify(body)
        })
            .then(async response => {
                let status = response.status;
                this.logApiError(url, status);
                return { response: await response.blob(), status: status }
            })
            .then(data => {
                if (data.status >= 400 && data.status <= 599) {
                    errorCallback(data.response)
                    this.logApiError(url, data.status, data.response);
                } else {
                    callback(data.response)
                }
            })
            .catch(err => errorCallback(err));
    };

    static unauthorizedGet = (url, callback, errorCallback) => {
        fetch(url, {
            method: 'GET',
            mode: 'cors',
            headers: {
                'Content-Type': 'application/json',
            },
        })
            .then(async response => {
                let status = response.status;
                this.logApiError(url, status);
                return { response: await response.json(), status: status }
            })
            .then(data => {
                if (data.status >= 400 && data.status <= 599) {
                    errorCallback(data.response);
                    this.logApiError(url, data.status, data.response);
                } else {
                    callback(data.response)
                }
            })
            .catch(err => errorCallback(err));
    };

    static unauthorizedPost = (url, body, callback, errorCallback, queryParams) => {
        url = this.buildUrl(url, queryParams);

        fetch(url, {
            method: 'POST',
            mode: 'cors',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(body)
        })
            .then(async response => {
                let status = response.status;
                this.logApiError(url, status);
                return { response: await response.json(), status: status }
            })
            .then(data => {
                if (data.status >= 400 && data.status <= 599) {
                    errorCallback(data.response)
                    this.logApiError(url, data.status, data.response);
                } else {
                    callback(data.response)
                }
            })
            .catch(err => errorCallback(err));
    };

    static put = (url, body, callback, errorCallback, queryParams = null) => {
        url = this.buildUrl(url, queryParams);

        fetch(url, {
            method: 'PUT',
            mode: 'cors',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + storeGet('getToken'),
            },
            body: JSON.stringify(body)
        })
            .then(async response => {
                let status = response.status;
                this.logApiError(url, status);
                return { response: await response.json(), status: status }
            })
            .then(data => {
                if (data.status >= 400 && data.status <= 599) {
                    errorCallback(data.response)
                    this.logApiError(url, data.status, data.response);
                } else {
                    callback(data.response)
                }
            })
            .catch(err => errorCallback(err));
    };

    static putMultiPart = (url, body, callback, errorCallback, queryParams = null) => {
        url = this.buildUrl(url, queryParams);

        fetch(url, {
            method: 'PUT',
            mode: 'cors',
            headers: {
                'Authorization': 'Bearer ' + storeGet('getToken'),
            },
            body: body
        })
            .then(async response => {
                let status = response.status;
                this.logApiError(url, status);
                return { response: await response.json(), status: status }
            })
            .then(data => {
                if (data.status >= 400 && data.status <= 599) {
                    errorCallback(data.response)
                    this.logApiError(url, data.status, data.response);
                } else {
                    callback(data.response)
                }
            })
            .catch(err => errorCallback(err));
    };

    static isNotBlank(value) {
        return value !== null && value !== undefined && value !== ''
    }

    static buildUrl(url, queryParams) {
        if (!queryParams || !queryParams.length) return url;
        const parts = queryParams
            .filter(p => p && this.isNotBlank(p[0]) && this.isNotBlank(p[1]))
            .map(p => encodeURIComponent(p[0]) + '=' + encodeURIComponent(p[1]));
        return parts.length ? url + '?' + parts.join('&') : url;
    }

    static get = (url, callback, errorCallback, queryParams = null) => {
        url = this.buildUrl(url, queryParams);

        if (url.includes('user/me') && isEmpty(storeGet('getToken'))) {
            return;
        }

        fetch(url, {
            method: 'GET',
            mode: 'cors',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + storeGet('getToken'),
            },
            //signal: AbortSignal.timeout(5000)
        })
            .then(async response => {
                let status = response.status;
                this.logApiError(url, status);
                return { response: await response.json(), status: status }
            })
            .then(data => {
                if (data.status >= 400 && data.status <= 599) {
                    errorCallback(data.response);
                    this.logApiError(url, data.status, data.response);
                } else {
                    callback(data.response)
                }
            })
            .catch(err => {
                errorCallback(err)
            });

    };

    static getBlob = (url, callback, errorCallback, queryParams) => {
        url = this.buildUrl(url, queryParams);

        fetch(url, {
            method: 'GET',
            mode: 'cors',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + storeGet('getToken'),
            },
        })
            .then(async response => {
                let status = response.status;
                this.logApiError(url, status);
                return { response: await response.blob(), status: status }
            })
            .then(data => {
                if (data.status >= 400 && data.status <= 599) {
                    errorCallback(data.response)
                    this.logApiError(url, data.status, data.response);
                } else {
                    callback(data.response)
                }
            })
            .catch(err => errorCallback(err));
    };

    static delete = (url, body, callback, errorCallback, queryParams = null) => {
        url = this.buildUrl(url, queryParams);

        fetch(url, {
            method: 'DELETE',
            mode: 'cors',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + storeGet('getToken'),
            },
            body: JSON.stringify(body)
        })
            .then(async response => {
                let status = response.status;
                this.logApiError(url, status);
                return { response: await response.json(), status: status }
            })
            .then(data => {
                if (data.status >= 400 && data.status <= 599) {
                    errorCallback(data.response)
                    this.logApiError(url, data.status, data.response);
                } else {
                    callback(data.response)
                }
            })
            .catch(err => errorCallback(err));

    };
}
