const qs = require('qs')
const axios = require('axios')
const findProperty = require('./findProperty')
const CRM = require('../models/CRM')

const { set, get, del } = require('./redisClient')
const get75PercentTimeInSeconds = require('./get75PercentTimeInSeconds')

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

    console.log('===========> exchangeForTokens companyId: ', companyId)

    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
            }
        }
    }

    console.log('======> CONFIG: ', config)
    console.log('======> companyId: ', companyId)

    // const { data } = await axios(config)

     

    //test 
    let data
        try {
            let { data: _data } = await axios(config)
            data = _data
        } catch (error) { 
            if (error.response) {
                console.error('==================> oauth2 Erro na resposta da API:', {
                    status: error.response.status,
                    data: error.response.data,
                })
            } 
            else if (error.request) {
                console.error('==================> oauth2 Nenhuma resposta recebida da API:', error.request)
            } 
            else {
                console.error('==================> oauth2 Erro ao configurar a request:', error.message)
            }
     
            throw error
        }

    //

    console.log('===========> auth2 data: ', data)


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

    console.log('===========> refresh_token: ', refresh_token)
    console.log('===========> access_token: ', access_token)

    // `${clientId+companyId}`

    // salesforce case
    if (issued_at)
        await set(`${crmOauth.crm.authentication.crmClientId+companyId}`, access_token, get75PercentTimeInSeconds(issued_at))
    else
        await set(`${crmOauth.crm.authentication.crmClientId+companyId}`, access_token, Math.round(expires_in * 0.75))

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

    if (refresh_token) {
        console.log('===========> refresh_token2: ', refresh_token)

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

    return access_token

}

const refreshAccessToken = async (clientId, companyId) => {

    let crmOauth = await CRM.findOne({ 'crm.authentication.crmClientId': clientId, companyId })
 
    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, companyId)
}

const getAccessToken = async (clientId, companyId) => {

    console.log(`============> clientId+companyId: ${clientId+companyId}`)

    if (!await get(`${clientId+companyId}`)) {
        console.log('Refreshing expired access token')
        await refreshAccessToken(clientId, companyId)
    }
    return await get(`${clientId+companyId}`)
}


module.exports = {
    exchangeForTokens,
    refreshAccessToken,
    getAccessToken
}