import {FetchContext, FetchOptions} from "ohmyfetch";
import {TYPE_ALERT} from "~/types/enum/enums";
import ApiRequestService from "~/services/data/apiRequestService";
import {Ref} from "@vue/reactivity";
import {usePageStore} from "~/stores/page";
import UnauthorizedError from "~/services/error/UnauthorizedError";
import {useAccessProfileStore} from "~/stores/accessProfile";
import {AssociativeArray} from "~/types/data";

/**
 * Retourne une instance de ApiRequestService configurée pour interroger l'api Ap2i
 *
 * @see https://github.com/unjs/ohmyfetch/blob/main/README.md#%EF%B8%8F-create-fetch-with-default-options
 */
let apiRequestServiceClass:null|ApiRequestService = null
export const useAp2iRequestService = () => {
    const runtimeConfig = useRuntimeConfig()

    const baseURL = runtimeConfig.baseUrl ?? runtimeConfig.public.baseUrl

    const pending: Ref<boolean> = ref(false)

    /**
     * Peuple les headers avant l'envoi de la requête
     *
     * @param request
     * @param options
     */
    const onRequest = async function ({ request, options }: FetchContext) {
        // @ts-ignore
        if(options && options.noXaccessId) {
            return
        }

        const accessProfileStore = useAccessProfileStore()

        const headers: AssociativeArray = {
            'x-accessid': String(accessProfileStore.id),
            'Authorization': 'BEARER ' + accessProfileStore.bearer,
        }

        if (accessProfileStore.switchId) {
            headers['x-switch-user'] = String(accessProfileStore.switchId)
        }

        options.headers = { ...options.headers, ...headers }

        pending.value = true
        console.log('Request : ' + request + ' (SSR: ' + process.server + ')')
    }

    const onRequestError = async function({ request, options, response }: FetchContext) {
        pending.value = false
    }

    /**
     * Server responded
     *
     * @param request
     * @param options
     * @param response
     */
    const onResponse = async function({ request, options, response }: FetchContext) {
        pending.value = false
    }

    /**
     * Gère les erreurs retournées par l'api
     *
     * @param request
     * @param response
     * @param error
     */
    const onResponseError = async function ({ request, response, error }: FetchContext) {
        pending.value = false

        if (response && response.status === 401) {
            throw new UnauthorizedError('Ap2i - Unauthorized')
        }
        else if (response && response.status === 403) {
            usePageStore().addAlert(TYPE_ALERT.ALERT, ['forbidden'])
            console.error('Forbidden')
        }
        else if (response && response.status >= 404) {
            // @see https://developer.mozilla.org/fr/docs/Web/HTTP/Status
            usePageStore().addAlert(TYPE_ALERT.ALERT, [error ? error.message : response.statusText])
            // console.error(error ?? response)
        }
    }

    const config : FetchOptions = {
        baseURL,
        onRequest,
        onRequestError,
        onResponse,
        onResponseError
    }

    //Avoid memory leak
    if (apiRequestServiceClass === null) {
        // Utilise la fonction `create` d'ohmyfetch pour générer un fetcher dédié à l'interrogation de Ap2i
        const fetcher = $fetch.create(config)
        // @ts-ignore
        apiRequestServiceClass = new ApiRequestService(fetcher)
    }

    return { apiRequestService: apiRequestServiceClass, pending: pending }
}
