const axios = require('axios')
const flatten = require('flat')
const CustomError = require('../errors')
const CRM_Contact = require('../models/CRM_Contact')
const CRM = require('../models/CRM')

const { URL } = require('url')
const { getAccessToken } = require('./oauth2')
const findProperty = require('./findProperty')
const requestConfigHeader = require('./requestConfigHeader')
const sendMessageSocket = require('./sendMessageSocket')
const CRM_Ticket = require('../models/CRM_Ticket')

async function lookupContactByPhone(rest, authentication, crmPhone, companyId, test = {}, cacheContact = false) {
   
    let { request, body, response } = findProperty(rest, 'lookupContactByPhone')

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

    const { type, userName, passWord, token, crmClientId, crmAccountId} = authentication

    if (cacheContact) {
        const crmInfo = await CRM_Contact.findOne({ companyId, crmBaseURL: new URL(url).hostname, phone: crmPhone })

        if (crmInfo) return { exist: true, contactId: crmInfo.contactId, phone: crmPhone }
    }

    const config = await requestConfigHeader(url, crmPhone, requestType, requestContentType, type, userName, passWord, token, crmClientId, '', '', companyId)

    if (test?.testing) {
        let msg = `Tentanto checar se o contato de numero ${crmPhone} existe no crm`
        sendMessageSocket({ companyId, status: 'processing', data: { request: config, msg } })
    }

    console.log("PAYLOAD CONFIG LOOKUP CONTACT BY PHONE: ", JSON.stringify(config, null, 6))

    let data

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

        // throw error
    }

    console.log('CONTACT LOOKUP BY PHONE DATA: ', JSON.stringify(data, null, 6))

    if (url.includes("hubapi") && data?.contacts.length > 1) {

        const auxContatWithName = data.contacts.find((c) => c.properties?.hs_full_name_or_email?.value?.trim().length > 2)

        if (auxContatWithName) {

            console.log(`[${new Date()}] ****** HUBSPOT CONTATO DUPLICADO. CONTACTID ${auxContatWithName.vid} A SER CONSIDERADO ****** `)

            data.contacts = data.contacts = [auxContatWithName]

            const contacts = await CRM_Contact.find({ companyId, crmBaseURL: new URL(url).hostname, phone: crmPhone })

            if (contacts && contacts.length > 1) {

                for (const contact of contacts.slice(0, -1)) {

                    await CRM_Ticket.deleteMany({ companyId, contact: contact })

                    await contact.deleteOne()
                }

            }

            console.log(`[${new Date()}]  dados do contato duplicado no crm: `, data)

            const updateResult = await CRM_Contact.updateOne(
                { companyId, crmBaseURL: new URL(url).hostname, phone: crmPhone },
                {
                    $set: { contactId: auxContatWithName.vid }
                })

            if (updateResult.modifiedCount > 0)
                return { exist: true, contactId: auxContatWithName.vid }
        }

    }



    data = flatten(data)

    let auxPhone
    let auxContactId
    let auxName
    let auxAccountId

    for (const prop in data) {

        const _prop = prop.replace(/^\d+\./, '').replace(/(?:^|\.)\d+\b/g, '')

        if (_prop == response?.phone?.trim()) {
            auxPhone = data[prop].replace('+', '')
        }

        if (_prop == response?.id?.trim()) {
            auxContactId = data[prop]
        }

        if (auxPhone && auxContactId) break

    }

    console.log('===========> !auxPhone && !auxContactId: ', !auxPhone && !auxContactId)


    if (!auxPhone && !auxContactId) {
        for (const prop in data) {

            let _prop = prop.replace(/\.(\d+)(\.|$)/g, '[$1]$2')

            // SALESFORCE GETTING THE NAME 
            if (_prop == response?.name?.trim()) {
                auxName = data[prop]
            }

            // SALESFORCE GETTING THE ACCOUNT ID 
            if (_prop == response?.accountId?.trim()) {
                auxAccountId = data[prop]
            }

            if (_prop == response?.phone?.trim()) {
                auxPhone = data[prop].replace('+', '')
            }

            if (_prop == response?.id?.trim()) {
                auxContactId = data[prop]
            }

            // SALESFORCE CASE LOOOK UP ALL THE OBJECT PROPERTIES
            if (!url.includes('salesforce'))
                if (auxPhone && auxContactId) break

        }
    }

    // Tenta pegar o accountId no body da resposta se não conseguir, pega do template se a propriedade crmAccountId existir no template
    // Foi criado dessa forma para evitar problemas com integrações que já estão em funcionamento
    if(!auxAccountId && crmAccountId){
        console.log('---------> auxAccountId definido a partir do crmAccountId do template: ',crmAccountId)
        auxAccountId = crmAccountId
    }

    console.log('---------> auxPhone: ', auxPhone, ' | auxContactId: ', auxContactId, ' | auxAccountId: ', auxAccountId)

    if (auxPhone) {

        if (auxPhone && auxContactId) {

            // Garante apenas 1 contato 
            const contacts = await CRM_Contact.find({
                companyId,
                crmBaseURL: new URL(url).hostname,
                phone: crmPhone,
                contactId: { $ne: auxContactId }
            })
  
            if (contacts && contacts.length > 0) {

                for (const contact of contacts) {

                    console.log("=====> DELETING CONTACTS: ", contact)

                    await CRM_Ticket.deleteMany({ companyId, contact: contact })

                    await contact.deleteOne()
                }

            }
            //

            const contactInfo = await CRM_Contact.findOne({ companyId, crmBaseURL: new URL(url).hostname, contactId: auxContactId })

            console.log('contactInfo: ', contactInfo, " | crmPhone: ", crmPhone)

            if (!contactInfo) {
                console.log('----------------> CREATE CONTACT MONGO')
                const crm = await CRM.findOne({ companyId, crmBaseURL: new URL(url).hostname })
                await CRM_Contact.create({ companyId, crm, crmBaseURL: new URL(url).hostname, contactId: auxContactId, phone: auxPhone })


            }

        }

        return { exist: true, contactId: auxContactId, phone: crmPhone, name: auxName, accountId: auxAccountId }
    }

    return { exist: false }
}

module.exports = lookupContactByPhone


