/* eslint-disable no-unused-vars */
const VERSAO = '3.263.17.1';
const rotasBasicAuth = ['/enviarwhatsapp',
    '/cnpjliberado',
    '/verificausuario',
    '/conectado',
    '/limiteusuario',
    '/versao',
    '/healthcheckdatabase',
    '/healthcheck',
    '/porta',
    '/validarcnpj',
    '/validarquantidadeusuarios',
    '/sisplan/log/v1/geralog',
    '/sisplan/funcoes/v1/loginweb',
    '/sisplan/usuario/v1/empresas',
    '/sisplan/usuario/v1/dadoslogin',
    '/sisplan/funcoes/v1/ping',
    '/sisplan/funcoes/v1/imagemweb',
    '/sisplan/usuario/v1/buscaidiomausuario',
    '/statusapi'
];

function timeout(ms, promise) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            reject(new Error("timeout"));
        }, ms);
        promise.then(resolve, reject);
    });
}

async function conectadoExterno() {
    try {
        const usaHttps = typeof USA_HTTPS === 'undefined' ? false : USA_HTTPS;
        const protocolo = usaHttps ? 'https' : 'http';
        let urlRequisicao = `${protocolo}://${ipExterno}/sisplan/funcoes/v1/ping`
        const usaProxy = typeof USA_PROXY === 'undefined' ? false : USA_PROXY;
        if (usaProxy) {
            urlRequisicao = `${window.location.protocol}//${window.location.host}/apiroot/sisplan/funcoes/v1/ping`
        }
        let response = await timeout(3000, fetch(urlRequisicao, {
            method: "GET",
            headers: {
                'Authorization': basicAuth,
                'Content-Type': 'application/json',
            },
        }));

        if (response.status == 200) {
            return true;
        }
        return false;

    } catch (error) {
        return false;
    }

}

async function getLastWhatsappToken(idWpp) {
    const objetoPesquisa = {
        tabela: "WHATSAPPWEB",
        camposSelect: ["TOKEN"],
        where: [`ID = ${idWpp}`]
    }

    const response = await requisicao("GET", "/Sisplan/Funcoes/v1/pesquisa?", `JSON=${JSON.stringify(objetoPesquisa)}`, null);
    if (!response) {
        return '';
    }

    const jsonStr = await response.json();
    if (response.status != 200) {
        return '';
    }
    return jsonStr.RESULT[0][0].TOKEN;
}

async function setaConexao() {
    let externo = await conectadoExterno();
    if (externo == true) {
        setCookie('conexao', 'externa', 30);
        setCookie('ip_api', ipExterno, 30);
    } else {
        setCookie('conexao', 'interna', 30);
        setCookie('ip_api', ipInterno, 30);
    }

    const usaHttps = typeof USA_HTTPS === 'undefined' ? false : USA_HTTPS;
    let protocolo = usaHttps ? 'https' : 'http';
    const usaProxy = typeof USA_PROXY === 'undefined' ? false : USA_PROXY;
    if (usaProxy) {
        protocolo = window.location.protocol.replace(':', '')
        setCookie('ip_api', `${window.location.host}/apiroot`, 30);
    }
    setCookie('protocolo', protocolo, 30);
}

async function requisicao_ecf(tipo, url, parametros, body, timeOut) {
    let empresa = getCookie('empresa');
    let usuario = getCookie('usuario').toUpperCase();
    let portaApi = getCookie('porta_api_local');
    let response;
    if (timeOut == undefined) {
        timeOut = 10000;
    }
    parametros += parametros != '' ? `&EMPRESA=${empresa}&USUARIO=${usuario}&VERSAO_WEB=${VERSAO}` : `EMPRESA=${empresa}&USUARIO=${usuario}&VERSAO_WEB=${VERSAO}`;

    try {
        try {
            setCookie('enviando_comando', 'true');
            response = await timeout(timeOut, fetch(`http://127.0.0.1:${portaApi}${url}${parametros}`, {
                method: tipo,
                headers: {
                    'Authorization': basicAuth,
                    'Content-Type': 'application/json',
                },
                body: tipo.toUpperCase() != 'GET' ? body : null,
            }));
            return response;
        } catch (error) {
            console.log(`Erro (${error}).`);
            return;
        }
    } finally {
        setCookie('enviando_comando', 'false');
    }
}

async function requisicao_impressora(tipo, url, parametros, body, timeOut) {
    let empresa = getCookie('empresa');
    let usuario = getCookie('usuario').toUpperCase();
    let api_impressora = getCookie('api_impressora');
    let response;
    if (timeOut == undefined) {
        timeOut = 10000;
    }
    parametros += parametros != '' ? `&EMPRESA=${empresa}&USUARIO=${usuario}&VERSAO_WEB=${VERSAO}` : `EMPRESA=${empresa}&USUARIO=${usuario}&VERSAO_WEB=${VERSAO}`;

    try {
        try {
            setCookie('enviando_comando', 'true');
            response = await timeout(timeOut, fetch(`http://${api_impressora}${url}${parametros}`, {
                method: tipo,
                headers: {
                    'Authorization': basicAuth,
                    'Content-Type': 'application/json',
                },
                body: tipo.toUpperCase() != 'GET' ? body : null,
            }));
            return response;
        } catch (error) {
            console.log(`Erro (${error}).`);
            return;
        }
    } finally {
        setCookie('enviando_comando', 'false');
    }
}

async function requisicaoSat(tipo, url, parametros, body, timeOut) {
    if (getCookie('enviando_comando') == 'true') {
        console.log('tentou enviar comando com impressora ocupada');
        return;
    }
    let params = parametros;
    let time = timeOut;
    let empresa = getCookie('empresa');
    let usuario = getCookie('usuario').toUpperCase();
    let ipServidorSat = getCookie('ipPortaServidor');
    let response;
    if (time == undefined) {
        time = 10000;
    }
    params += params != '' ? `&EMPRESA=${empresa}&USUARIO=${usuario}&VERSAO_WEB=${VERSAO}` : `EMPRESA=${empresa}&USUARIO=${usuario}&VERSAO_WEB=${VERSAO}`;

    try {
        try {
            setCookie('enviando_comando', 'true');
            response = await timeout(time, fetch(`http://${ipServidorSat}${url}${params}`, {
                method: tipo,
                headers: {
                    'Authorization': basicAuth,
                    'Content-Type': 'application/json',
                },
                body: tipo.toUpperCase() != 'GET' ? body : null,
            }));
            return response;
        } catch (error) {
            console.log(`Erro (${error}).`);
            return;
        }
    } finally {
        setCookie('enviando_comando', 'false');
    }
}

async function revalidaToken(protocolo, externo, ipInterno, ipExterno) {
    const refreshToken = 'Bearer ' + getCookie('refreshToken');
    const ip = externo ? ipExterno : ipInterno;
    let urlRequisicao = `${protocolo}://${ip}${'/sisplan/funcoes/v1/refresh-token'}`
    const usaProxy = typeof USA_PROXY === 'undefined' ? false : USA_PROXY;
    if (usaProxy) {
        urlRequisicao = `${window.location.protocol}//${window.location.host}/apiroot${'/sisplan/funcoes/v1/refresh-token'}`
    }
    try {
        const response = await timeout(5000, fetch(urlRequisicao, {
            method: 'GET',
            headers: {
                'Authorization': refreshToken,
                'Content-Type': 'application/json',
                keepalive: true
            }
        }));
        if (response.status == 401) {
            if (parent.mandarParaLogin) {
                parent.mandarParaLogin();
            }
        }
        else {
            const jsonResponse = await response.json();
            setCookie('accessToken', jsonResponse.accessToken);
            setCookie('refreshToken', jsonResponse.refreshToken);
            return true;
        }
    } catch (error) {
        console.error(error);
        return false;
    }
}

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function requisicao(tipo, url, parametros, body, timeOut, segundaTentativa = true, obrigarEnvioBody = false) {
    let externo;
    const empresa = getCookie('empresa');
    const usuario = getCookie('usuario').toUpperCase();
    const empId = getCookie('emp_id');
    const IDUsuario = getCookie("id_usuario");
    const codUsuario = getCookie('cod_usuario')
    const jwtAuth = getCookie('accessToken') ? 'Bearer ' + getCookie('accessToken') : '';
    const ipExterno = IP_EXTERNO;

    if (!parametros) {
        parametros = '';
    }

    if (!parametros.toUpperCase().includes('EMPRESA=')) {
        parametros += parametros != '' ? `&empresa=${empresa}` : `empresa=${empresa}`;
    }

    if (!parametros.toUpperCase().includes('EMP_ID=')) {
        parametros += parametros != '' ? `&emp_id=${empId}` : `emp_id=${empId}`;
    }

    if (!parametros.toLowerCase().includes(`&usuario=${usuario.toLowerCase()}`)) {
        parametros += `&usuario=${usuario}`;
    }

    if (!parametros.toUpperCase().includes('ID_USUARIO=')) {
        parametros += parametros != '' ? `&id_usuario=${IDUsuario}` : `id_usuario=${IDUsuario}`;
    }

    if (!parametros.toUpperCase().includes('COD_USUARIO=')) {
        parametros += parametros != '' ? `&cod_usuario=${codUsuario}` : `cod_usuario=${codUsuario}`;
    }

    parametros += `&VERSAO_WEB=${VERSAO}`;

    let response;
    if (timeOut == undefined) {
        timeOut = typeof TIMEOUT_API === 'undefined' ? 5000 : TIMEOUT_API;
    }

    const usaHttps = typeof USA_HTTPS === 'undefined' ? false : USA_HTTPS;
    const protocolo = usaHttps ? 'https' : 'http';

    if (getCookie('conexao') == '') {
        await setaConexao();
    }

    externo = getCookie('conexao') == 'externa';
    let tentativas = 0;
    const maxTentativas = segundaTentativa ? 1 : 0;

    while (tentativas <= maxTentativas) {
        try {
            $('#conexaoInternaExterna').html(externo ? 'IP Externo   -' : 'IP Interno  -   ');
            setCookie('ip_api', externo ? ipExterno : ipInterno, 30);
            let urlRequisicao = `${protocolo}://${externo ? ipExterno : ipInterno}${url.toLowerCase()}${parametros}`
            const usaProxy = typeof USA_PROXY === 'undefined' ? false : USA_PROXY;
            if (usaProxy) {
                urlRequisicao = `${window.location.protocol}//${window.location.host}/apiroot${url.toLowerCase()}${parametros}`
                setCookie('ip_api', `${window.location.host}/apiroot`, 30);
            }
            response = await timeout(timeOut, fetch(urlRequisicao, {
                method: tipo,
                headers: {
                    'Authorization': rotasBasicAuth.includes(url.toLowerCase().replaceAll('?', '')) ? basicAuth : jwtAuth,
                    'Content-Type': 'application/json',
                    keepalive: true
                },
                body: tipo.toUpperCase() == 'POST' || tipo.toUpperCase() == 'PUT' || tipo.toUpperCase() == 'PATCH' || obrigarEnvioBody ? body : null,
            }));
            if (response.status == 401) {
                const revalidado = await revalidaToken(protocolo, externo, ipInterno, ipExterno);
                if (revalidado) {
                    return requisicao(tipo, url, parametros, body, timeOut);
                }
            }
            return response;
        } catch (error) {
            tentativas += 1;
            if (tentativas === 1 && segundaTentativa) {
                await sleep(2000); // 2 seg
                continue;
            }
            await setaConexao();
            console.log(`Erro (${error}).`);
            msgErro('Erro ao realizar ação, tente novamente.');

        }
    }
}

async function requisicao_feedback(body) {
    const timeOut = 10000;
    try {
        const response = await timeout(timeOut, fetch(`https://api.sisplansistemas.com.br:10555/wiki/feedback`, {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(body)
        }));
        return response;
    } catch (error) {
        console.log(`Erro (${error}).`);
        return;
    }
}


async function requisicao_wpp(tipo, url, parametros, body, timeOut, token) {
    const usaHttps = typeof USA_HTTPS === 'undefined' ? false : USA_HTTPS;
    const protocolo = usaHttps ? 'https' : 'http';// preenchido quando vinculado ao usuario, e o usuário relogar no sistema.
    const api_whatsapp = typeof API_WHATSAPP === 'undefined' ? '' : API_WHATSAPP;

    let response;
    if (timeOut == undefined) {
        timeOut = 10000;
    }
    // parametros += parametros != '' ? `&EMPRESA=${empresa}&USUARIO=${usuario}&VERSAO_WEB=${VERSAO}` : `EMPRESA=${empresa}&USUARIO=${usuario}&VERSAO_WEB=${VERSAO}`;

    try {
        response = await timeout(timeOut, fetch(`${protocolo}://${api_whatsapp}${url}${parametros}`, {
            method: tipo,
            headers: {
                'Authorization': 'bearer ' + token,
                'Content-Type': 'application/json',
            },
            body: tipo.toUpperCase() != 'GET' ? body : null,
        }));
        return response;
    } catch (error) {
        console.log(`Erro (${error}).`);
        return;
    }
}

async function requisicaoSia(tipo, url, token = null, parametros, body, timeOut = 300000) {
    try {
        if (!parametros) {
            parametros = '';
        }

        const urlRequisicao = `https://ia.sisplansistemas.com.br${url}${parametros}`

        const response = await timeout(timeOut, fetch(urlRequisicao, {
            method: tipo,
            headers: {
                "Content-Type": "application/json",
                Authorization: token ? token : ""
            },
            body: tipo.toUpperCase() == 'POST' || tipo.toUpperCase() == 'PUT' || tipo.toUpperCase() == 'PATCH' ? JSON.stringify(body) : null,
        }));

        return response
    } catch (error) {
        msgErro('Erro ao realizar ação, tente novamente.');
        return {}
    }
}

async function requisicaoSiaImage(tipo, url, auth, parametros, body, timeOut = 300000) {
    try {
        if (!parametros) {
            parametros = '';
        }

        const urlRequisicao = `https://ia-sia-draw-api.sisplansistemas.com.br${url}${parametros}`

        const response = await timeout(timeOut, fetch(urlRequisicao, {
            method: tipo,
            headers: {
                "Content-Type": "application/json",
                Authorization: auth.token ? auth.token : "",
                email: auth.email ? auth.email : "",
                password: auth.password ? auth.password : "",
            },
            body: tipo.toUpperCase() == 'POST' || tipo.toUpperCase() == 'PUT' || tipo.toUpperCase() == 'PATCH' ? JSON.stringify(body) : null,
        }));

        return response
    } catch (error) {
        msgErro('Erro ao realizar ação, tente novamente.');
        return {}
    }
}