package app

import (
	"fmt"

	"code.tnxs.net/taxnexus/lib/api/crm/crm_client/accounts"
	"code.tnxs.net/taxnexus/lib/api/geo/geo_client/coordinate"
	"code.tnxs.net/taxnexus/lib/api/geo/geo_models"
)

// GetAccount is first class retrieval function
func GetAccount(key string, principal *User) *Account {
	if key == "" {
		return nil
	}
	a, ok := accountCache.get(key)
	if ok {
		return a
	}
	acct, err := GetAccountByID(key, principal)
	if err != nil {
		return nil
	}
	return acct
}

// GetAccountByID is first class retrieval function
func GetAccountByID(recordID string, principal *User) (*Account, error) {
	sugar.Debug("app.GetAccountByID: 📥")
	if recordID == "" {
		return nil, fmt.Errorf("app.getAccountByID: 💣 ⛔ key is blank")
	}
	obj, ok := accountCache.get(recordID)
	if ok {
		sugar.Debug("app.getAccountByID: 👍 🎯 📤")
		return obj, nil
	}
	crmParams := accounts.NewGetAccountsParamsWithTimeout(getTimeout)
	crmParams.AccountID = &recordID
	response, err := crmClient.Accounts.GetAccounts(crmParams, principal.Auth)
	if err != nil {
		return nil, err
	}
	var newObj *Account
	for _, itm := range response.Payload.Data { // single iteration execution
		newObj = UnMarshalAccount(itm)
	}
	accountCache.put(recordID, newObj)
	sugar.Debug("app.getAccountByID: 👍 🆕 📤")
	return newObj, nil
}

// GetCoordinate is a first class retrieval function
func (obj *Account) GetCoordinate(principal *User) *Coordinate {
	sugar.Debug("app.Account.getCoordinate: 📥")
	if obj.CoordinateID != "" { // if CoordinateID is set, then just get it
		geoParams := coordinate.NewGetCoordinatesParamsWithTimeout(getTimeout)
		geoParams.CoordinateID = &obj.CoordinateID
		response, err := geoClient.Coordinate.GetCoordinates(geoParams, principal.Auth)
		if err != nil {
			return nil
		}
		var obj *Coordinate
		for _, itm := range response.Payload.Data { // single iteration execution
			obj = UnMarshalCoordinate(itm, principal)
		}
		return obj
	} // else get it via addresses, shipping #1, Business #2
	if obj.ShippingAddress.ToString() == "" && obj.BillingAddress.ToString() == "" {
		sugar.Errorf("app.Account.getCoordinate: 💣 ⛔ billing and shipping address both blank")
		return nil
	}
	theAddress := obj.ShippingAddress.ToString()
	if theAddress == "" {
		theAddress = obj.BillingAddress.ToString()
	}
	geoParams := coordinate.NewGetCoordinatesParamsWithTimeout(getTimeout)
	geoParams.Address = &theAddress
	response, err := geoClient.Coordinate.GetCoordinates(geoParams, principal.Auth)
	if err != nil {
		sugar.Error(err)
		return nil
	}
	var swag *geo_models.Coordinate
	for _, itm := range response.Payload.Data { // single iteration execution
		swag = itm
	}
	sugar.Debug("app.Account.getCoordinate: 👍 📤")
	return UnMarshalCoordinate(swag, principal)
}
