import { athenaConfig, athenaConfigOptions } from './athena-config.js';

/**
 * Check Response
 *
 * @param response
 * @param isTextResponse
 * @returns {any}
 */
function checkResponse(
    response,
    isTextResponse
)
{
    if(response.ok) {
        return isTextResponse ?
            response.text() :
            response.json();
    } else {
        return Promise.reject(
            `Network response status ${response.status}`
        );
    }
}

/**
 * Generate Form Data for API Calls
 *
 * @param data
 * @returns {FormData}
 */
function generateFormData(
    data
)
{
    const formData = new FormData();

    Object.keys(data).forEach(key => {
        formData.append(key, data[key]);
    });

    return formData;
}

/**
 * Generate Request Data
 *
 * @param data
 * @returns {null}
 */
function generateRequestData(data)
{
    data['token'] = athenaConfig.websiteToken;

    let requestData = null;
    if(athenaConfig.apiVersion === 1) {
        delete data['service'];
        requestData = generateFormData(data);
    } else if(athenaConfig.apiVersion === 3) {
        requestData = JSON.stringify(data);
    }

    return requestData;
}

/**
 * Check what api version to apply
 * and set it after
 *
 * @return {string|null}
 */
function apiVersionSet(
    apiVersion,
    service
)
{
    if (!apiVersion) {
        throw new Error('You have to set API_VERSION');
    }

    if (isNaN(apiVersion)) {
        throw new Error('API_VERSION needs to be a number');
    }

    const allowedVersions = [1, 3];
    if(!allowedVersions.includes(apiVersion))
        throw new Error(`Unsupported api version: ${apiVersion}, please change to version 1 or 3`);

    if(apiVersion === 3) {
        return `${athenaConfig.proxyUrl}athena-proxy`;
    }

    return apiVersion === 3 ?
        `${athenaConfig.proxyUrl}athena-proxy` :
        `${athenaConfig.apiUrl}api/v1/${service}`;
}

/**
 * Fetch API function
 *
 * @param data
 * @param executeSignal
 * @param isTextResponse
 */
export function athenaFetchApi(
    data,
    executeSignal = null,
    isTextResponse = false
)
{
    const service = data['service'];

    const finalUrl = apiVersionSet(athenaConfig.apiVersion, service);
    const requestData = generateRequestData(data);

    athenaConfigOptions.cancelRequest ? athenaConfigOptions.cancelRequest.abort('AthenaXAi Request Cancel Reason: Too many requests.') : null;
    athenaConfigOptions.cancelRequest = new AbortController();
    const signal = athenaConfigOptions.cancelRequest.signal;

    const init = {
        method: 'POST',
        cache: 'no-cache',
        headers: {
            'Accept': 'application/json'
        },
        body: requestData
    };

    if(executeSignal) init['signal'] = signal;

    if(!athenaConfig.originUrl) {
        return Promise.reject(
            `AthenaXAi error: originUrl is a required parameter it needs to be set.`
        );
    }

    if(athenaConfig.originUrl !== `${window.location.origin}/`) {
        return Promise.reject(
            `AthenaXAi error: originUrl does not match the origin.`
        );
    }

    return fetch(finalUrl, init)
        .then(response => checkResponse(response, isTextResponse));
}