const qs = require('qs')
const axios = require('axios')  
const findProperty = require('./findProperty')
const CRM = require('../models/CRM')
 
const { set, get, del } = require('./redisClient')

const exchangeForTokens = async (crmOauth, exchangeProof) => {

    const { request, body, response } = findProperty(crmOauth.crm.crmRest, 'tokenEndpoint')

    let { requestContentType, requestEncoding, requestType, responseType, url } = request

    let config = {
        method: requestType,
        url,
        data: qs.stringify(exchangeProof)
    }

    if (requestContentType != 'none') {
        config = {
            ...config, headers: {
                'Content-Type': requestContentType
            }
        }
    } 

    const { data } = await axios(config) 

    const { refresh_token, access_token, token_type, expires_in } = data 

    await set(crmOauth.crm.authentication.crmClientId, access_token, Math.round(expires_in * 0.75))

    crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': crmOauth.crm.authentication.crmClientId })

    if (refresh_token) { 
        crmOauth.crm.authentication.crmOAuthRefreshToken = refresh_token
    }
    crmOauth.crm.authentication.crmOAuthToken = access_token
    await crmOauth.save() 
 
    return access_token

}

const refreshAccessToken = async (clientId) => {

    let crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': clientId })
    crmOauth = crmOauth.toObject() 

    const refreshTokenProof = {
        grant_type: 'refresh_token',
        client_id: crmOauth.crm.authentication.crmClientId,
        client_secret: crmOauth.crm.authentication.crmClientSecret,
        redirect_uri: process.env.URL_OAUTH_CALLBACK,
        refresh_token: crmOauth.crm.authentication.crmOAuthRefreshToken
    }
    return await exchangeForTokens(crmOauth, refreshTokenProof)
}

const getAccessToken = async (clientId) => {

    if (!await get(clientId)) {
        console.log('Refreshing expired access token')
        await refreshAccessToken(clientId)
    }
    return await get(clientId)
}


module.exports = {
    exchangeForTokens,
    refreshAccessToken,
    getAccessToken
}