// Package app is a utility package
package app

import (
	"strings"
	"time"

	"code.tnxs.net/taxnexus/lib/api/auth0/auth0_client"
	"code.tnxs.net/taxnexus/lib/api/crm/crm_client"
	"code.tnxs.net/taxnexus/lib/api/geo/geo_client"
	"code.tnxs.net/taxnexus/lib/api/stash/stash_client"
	"code.tnxs.net/taxnexus/lib/app/logger"
	httptransport "github.com/go-openapi/runtime/client"
	"github.com/spf13/viper"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

var sugar *zap.SugaredLogger
var config = Configuration{}
var appViper = viper.New()
var auth0Client = auth0_client.Default
var geoClient = geo_client.Default
var crmClient = crm_client.Default
var stashClient = stash_client.Default
var configured = false
var apiUsers map[string]User

const getTimeout = 6 * time.Minute
const postTimeout = 6 * time.Minute
const constNotFound = "not found"
const percentFactor = 100
const dateFormatDB = "2006-01-02"
const dateFormat = "2006-01-02"
const dateTimeFormat = "2006-01-02T15:04:05-0800"
const dateTimeFormatAlt = "2006-01-02 15:04:05"
const dateFormatAlt = "1/2/2006"
const countyGeocodeLength = 7
const cityGeocodeLength = 12

// InitConfig exports the config initialization func
func InitConfig(systemName string, initalLogLevel zapcore.Level) {
	if configured {
		return
	}
	sugar = logger.New(initalLogLevel)
	sugar.Infof("app.InitConfig: 📥 %s", systemName)
	appViper.SetConfigType("yaml")
	appViper.SetConfigName(systemName)
	appViper.AddConfigPath("/etc/taxnexus")
	appViper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
	appViper.SetEnvPrefix("taxnexus")
	appViper.AutomaticEnv() // read in environment variables that match
	err := appViper.ReadInConfig()
	if err != nil {
		sugar.Fatalf("app.InitConfig: 💣 ⛔ can't read system config: %w", err)
	}
	err = appViper.Unmarshal(&config)
	if err != nil {
		sugar.Fatalf("app.InitConfig: 💣 ⛔ can't unmarshal system config: %w", err)
	}
	sugar = logger.New(GetLogLevel())
	apiUsers = initAPIUsers()
	sugar.Debugf("app.InitConfig: 👍 📤 serviceAccounts: %d", len(config.ServiceAccounts))
	configured = true
}

func initAPIUsers() map[string]User {
	sugar.Info("board.initAPIUsers: 📥")
	users := map[string]User{
		"auth": {
			APIKey: GetServiceAccount("auth").APIKey,
			Auth: httptransport.APIKeyAuth(
				"X-API-Key",
				"header",
				GetServiceAccount("auth").APIKey,
			),
		},
		"test-service-account": {
			APIKey: GetServiceAccount("test-service-account").APIKey,
			Auth: httptransport.APIKeyAuth(
				"X-API-Key",
				"header",
				GetServiceAccount("test-service-account").APIKey),
		},
	}
	sugar.Debugf("board.initAPIUsers: 👍 📤")
	return users
}
