package utils

import (
	"fmt"
	"math"
	"strconv"
	"strings"

	beeLogger "github.com/beego/bee/v2/logger"
	"github.com/beego/beego/v2/server/web"
	"github.com/qiniu/qmgo"
	"github.com/shopspring/decimal"
)

var (
	RunMode        string //运行模式
	MYSQL_URL      string //数据库连接
	MYSQL_URL_DATA string
	MYSQL_URL_EDB  string
	MgoUrlData     string // mongodb数据库连接配置

	REDIS_CACHE string //缓存地址
	//Rc          *cache.Cache //redis缓存
	Re            error        //redis错误
	Rc            RedisClient  //redis缓存
	MgoDataCli    *qmgo.Client // mongodb客户端连接
	MgoDataDbName string       // mongodb指标数据的库名
)

// 基础配置
var (
	// APPNAME 项目中文名称
	APPNAME string
	// APP_NAME_EN 项目英文名称
	APP_NAME_EN string

	// Md5Key 签名秘钥
	Md5Key string
	// EmailSendToUsers 邮件提醒人员
	EmailSendToUsers string
	// AlarmMsgUrl 报警服务地址
	AlarmMsgUrl string
)

// 公共api内部服务调用
var (
	// EDB_LIB_URL 公共指标库
	EDB_LIB_URL         string
	APP_EDB_LIB_NAME_EN string
	EDB_LIB_Md5_KEY     string
	ETA_MINI_URL        string
	ETA_MINI_DES_KEY    string
)

var (
	LogPath    string
	LogFile    string
	BinLogPath string
	BinLogFile string
	ApiLogPath string
	ApiLogFile string
	LogMaxDays int //日志最大保留天数
)

var (
	UseMongo bool // 是否使用mongo
)

// eta_forum_hub ETA社区桥接服务地址
var (
	ETA_FORUM_HUB_URL     string
	ETA_FORUM_HUB_NAME_EN string
	ETA_FORUM_HUB_MD5_KEY string
)

func init() {
	tmpRunMode, err := web.AppConfig.String("run_mode")
	if err != nil {
		panic("配置文件读取run_mode错误 " + err.Error())
	}
	RunMode = tmpRunMode
	if RunMode == "" {
		localIp, err := GetLocalIP()
		if localIp == "10.0.0.123" {
			RunMode = "debug"
		} else {
			RunMode = "release"
		}
		configPath := `/home/code/config/eta_chart_lib/conf/app.conf`
		err = web.LoadAppConfig("ini", configPath)
		if err != nil {
			fmt.Println("web.LoadAppConfig Err:" + err.Error())
		}
	}
	config, err := web.AppConfig.GetSection(RunMode)
	if err != nil {
		panic("配置文件读取错误 " + err.Error())
	}
	beeLogger.Log.Info(RunMode + " 模式")

	APP_NAME_EN = config["app_name_en"]
	// 签名秘钥
	Md5Key = config["md5_key"]

	MYSQL_URL = config["mysql_url"]

	MYSQL_URL_DATA = config["mysql_url_data"]
	MYSQL_URL_EDB = config["mysql_url_edb"]

	// mongodb数据库连接配置
	MgoUrlData = config["mgo_url_data"]

	REDIS_CACHE = config["beego_cache"]
	if len(REDIS_CACHE) <= 0 {
		panic("redis链接参数没有配置")
	}

	//Rc, Re = cache.NewCache(REDIS_CACHE) //初始化缓存
	//if Re != nil {
	//	fmt.Println(Re)
	//	panic(Re)
	//}

	// 初始化缓存
	redisClient, err := initRedis(config["redis_type"], config["beego_cache"])
	if err != nil {
		fmt.Println("redis链接异常:", err)
		panic(any(Re))
	}
	Rc = redisClient

	// 项目中文名称
	appNameCn, err := web.AppConfig.String("app_name_cn")
	if err != nil {
		panic(any("配置文件读取app_name_cn错误 " + err.Error()))
	}
	APPNAME = appNameCn

	// 邮件提醒人员
	EmailSendToUsers = config["email_send_to_users"]

	// 报警服务地址
	AlarmMsgUrl = config["alarm_msg_url"]

	// 公共api内部服务调用
	{
		// 公共指标库相关
		EDB_LIB_URL = config["edb_lib_url"]
		APP_EDB_LIB_NAME_EN = config["app_edb_lib_name_en"]
		EDB_LIB_Md5_KEY = config["edb_lib_md5_key"]
		ETA_MINI_URL = config["eta_mini_url"]
		ETA_MINI_DES_KEY = config["eta_mini_des_key"]
	}
	//日志配置
	{
		LogPath = config["log_path"]
		LogFile = config["log_file"]
		BinLogPath = config["binlog_path"]
		BinLogFile = config["binlog_file"]
		ApiLogPath = config["apilog_path"]
		ApiLogFile = config["apilog_file"]
		logMaxDaysStr := config["log_max_day"]
		LogMaxDays, _ = strconv.Atoi(logMaxDaysStr)
	}

	// eta_forum_hub ETA社区桥接服务地址
	{
		ETA_FORUM_HUB_URL = config["eta_forum_hub_url"]
		ETA_FORUM_HUB_NAME_EN = config["eta_forum_hub_name_en"]
		ETA_FORUM_HUB_MD5_KEY = config["eta_forum_hub_md5_key"]
	}
}

// FormatMixTableDataShowValue 格式化自定表格显示数据
func FormatMixTableDataShowValue(x float64) (res string) {
	res = strconv.FormatFloat(x, 'f', -1, 64)
	return
}

//http://8.136.199.33:8608/swagger/
//http://8.136.199.33:8608/v1

// FormatTableDataShowValue 格式化自定表格显示数据
func FormatTableDataShowValue(x float64) (res string) {
	if x > 1 || x < -1 {
		res = decimal.NewFromFloat(x).Round(2).String()
		return
	}
	// 介于-1到1之间
	xStr := strconv.FormatFloat(x, 'f', -10, 64)

	// 使用 strings.Split 函数将小数拆分为整数部分和小数部分
	xParts := strings.Split(xStr, ".")
	if len(xParts) < 2 {
		res = fmt.Sprint(x)
		return
	}

	// 计算小数部分的长度,即小数点后面的位数
	xDecimals := len(xParts[1])
	if xDecimals > 2 {
		parts := xParts[1]
		// 小数点后小于等于两位, 直接拼接返回
		partLen := len(xParts[1])
		if partLen <= 2 {
			res = xParts[0] + "." + parts
			return
		}
		// 找出第一个有效数字, 算出n
		one := 0
		for k, p := range parts {
			// 48->0
			if p != 48 {
				if one == 0 {
					one = k + 1
				}
			}
		}
		n := partLen - one
		if n >= 1 {
			n -= 1
		} else {
			one -= 1
		}

		var partFloat float64
		partInt, _ := strconv.Atoi(parts)
		partFloat, _ = decimal.NewFromInt(int64(partInt)).Div(decimal.NewFromFloat(math.Pow(10, float64(n)))).Float64()
		partFloat = math.Round(partFloat)
		partFloat, _ = decimal.NewFromFloat(partFloat).Div(decimal.NewFromFloat(math.Pow(10, float64(one+1)))).Float64()
		resParts := strings.Split(fmt.Sprint(partFloat), ".")
		resPart := ""
		if len(resParts) > 1 {
			resPart = resParts[1]
		} else {
			resPart = resParts[0]
		}
		res = xParts[0] + "." + resPart
	}

	if xDecimals <= 2 {
		xDecimalsStr := xParts[1]
		x, _ = strconv.ParseFloat(xParts[0]+"."+xDecimalsStr, 64)
		res = xParts[0] + "." + xDecimalsStr
	}
	return
}

func GetMiniUrl(source string) string {
	config, err := web.AppConfig.GetSection(RunMode)
	if err != nil {
		panic("配置文件读取错误 " + err.Error())
	}
	urlName := fmt.Sprintf("mini_url_%s", source)
	return config[urlName]
}