package common

import (
	"fmt"
	"github.com/go-rod/rod"
	"math"
	"reflect"
	"strconv"
	"strings"

	"github.com/shopspring/decimal"
)

var MonthNum1 = map[string]string{
	"01": "1月",
	"02": "2月",
	"03": "3月",
	"04": "4月",
	"05": "5月",
	"06": "6月",
	"07": "7月",
	"08": "8月",
	"09": "9月",
	"10": "10月",
	"11": "11月",
	"12": "12月",
}

// string to int
func StrToInt(str string) int {
	intValue, err := strconv.Atoi(str)
	if err != nil {
		intValue = int(StrToFloat(str))
	}
	return intValue
}

// float64 to string
func FloatToStr(f float64) string {
	// 如果格式标记为 'e'，'E'和'f'，则 prec 表示小数点后的数字位数
	// 如果格式标记为 'g'，'G'，则 prec 表示总的数字位数（整数部分+小数部分）
	//func FormatFloat(f float64, fmt byte, prec, bitSize int) string
	//f := 100.12345678901234567890123456789
	//zaplog.LoggerS.Info(strconv.FormatFloat(f, 'f', 5, 64))
	// 100.12346
	//zaplog.LoggerS.Info(strconv.FormatFloat(f, 'g', 5, 64))
	// 100.12
	//zaplog.LoggerS.Info(strconv.FormatFloat(f, 'G', 5, 64))
	// 100.12
	return strconv.FormatFloat(f, 'f', 2, 64)
}

// string to Float
func StrToFloat(str string) float64 {
	if str == "NaN" {
		return 0.0
	}
	str = strings.TrimSpace(str)
	str = TrimQff(str)
	intValue, err := strconv.ParseFloat(str, 64)
	if err != nil {
		intValue = 0
	}
	d := decimal.NewFromFloat(intValue)
	//zaplog.LoggerS.Info(n.String())
	f, _ := d.Round(2).Float64()
	return f
}

// int to string
func IntToStr(intvalue int) string {
	return strconv.Itoa(intvalue)
}

// string 去千分符
func TrimQff(str string) string {
	return strings.Replace(str, ",", "", -1)
}

// string to Float 不保留两位小数
func StrToFloatAll(str string) float64 {
	str = strings.TrimSpace(str)
	str = TrimQff(str)
	str = strings.ReplaceAll(str, "%", "")
	intValue, err := strconv.ParseFloat(str, 64)
	if err != nil {
		intValue = 0
	}
	d := decimal.NewFromFloat(intValue)
	//zaplog.LoggerS.Info(n.String())
	f, _ := d.Float64()
	return f
}

// float64 to string
func FloatToIntStr(floatValue float64) string {
	//return strconv.FormatFloat(floatValue, 'e', 2, 64)
	return strconv.Itoa(int(floatValue))
}

// 不保留两位小数转字符串
func FloatAllToStr(f float64) string {
	return strconv.FormatFloat(f, 'f', -1, 64)
}

func FormatAmt(n float64) string {
	return strconv.FormatFloat(n, 'f', 2, 64) //格式化金额 保留两位小数（四舍五入）
}

func IsNumeric(s string) bool {
	_, err := strconv.Atoi(s)
	return err == nil
}

func DecimalDivFF(v1 float64, v2 float64) float64 {
	r, _ := decimal.NewFromFloat(v1).Div(decimal.NewFromFloat(v2)).Float64()
	return r
}

func Round2(value float64) float64 {
	d := decimal.NewFromFloat(value)
	//zaplog.LoggerS.Info(n.String())
	f, _ := d.Round(2).Float64()
	return f
}

// DecimalAddFF 精确相加 小数
func DecimalAddFF(v1 float64, v2 float64) float64 {
	r, _ := decimal.NewFromFloat(v1).Add(decimal.NewFromFloat(v2)).Float64()
	return r
}

func InterfaceToFloat(unk any) float64 {
	var floatType = reflect.TypeOf(float64(0))
	var stringType = reflect.TypeOf("")
	switch i := unk.(type) {
	case float64:
		return i
	case float32:
		return float64(i)
	case int64:
		return float64(i)
	case int32:
		return float64(i)
	case int:
		return float64(i)
	case uint64:
		return float64(i)
	case uint32:
		return float64(i)
	case uint:
		return float64(i)
	case string:
		f, _ := strconv.ParseFloat(i, 64)
		return f
	default:
		v := reflect.ValueOf(unk)
		v = reflect.Indirect(v)
		if v.Type().ConvertibleTo(floatType) {
			fv := v.Convert(floatType)
			return fv.Float()
		} else if v.Type().ConvertibleTo(stringType) {
			sv := v.Convert(stringType)
			s := sv.String()
			f, _ := strconv.ParseFloat(s, 64)
			return f
		} else {
			return math.NaN()
		}
	}
}

// float64 to float64 去掉金额字符串后面的0
func FloatToFloat(f float64) float64 {
	ff, _ := strconv.ParseFloat(FloatToStr3(f), 64)
	return ff
}

// string to Float
func StrToFloat4(str string) any {
	if strings.Contains(str, `*`) {
		return str
	} else {
		if strings.Contains(str, `%`) {
			str = strings.ReplaceAll(str, `%`, ``)
			str = TrimQff(str)
			intValue, err := strconv.ParseFloat(str, 64)
			if err != nil {
				intValue = 0
			}
			d := decimal.NewFromFloat(intValue)
			//zaplog.LoggerS.Info(n.String())
			f, _ := d.Round(2).Float64()
			return f / 100

		} else {
			str = TrimQff(str)
			intValue, err := strconv.ParseFloat(str, 64)
			if err != nil {
				intValue = 0
			}
			d := decimal.NewFromFloat(intValue)
			//zaplog.LoggerS.Info(n.String())
			f, _ := d.Round(2).Float64()
			return f
		}

	}

}

// float64 to string 去掉金额字符串后面的0
func FloatToStr3(f float64) string {
	ss := strconv.FormatFloat(f, 'f', 2, 64)
	return doDecimal(ss)
}

func doDecimal(s string) string {
	if strings.Index(s, ".") < 0 {
		return s
	}
	l := len(s)
	if strings.HasSuffix(s, "0") {
		return doDecimal(s[0 : l-1])
	}
	if strings.HasSuffix(s, ".") {
		return doDecimal(s[0 : l-1])
	}
	return s
}
func FloatToFloat2(f float64) float64 {
	fstr := fmt.Sprintf("%0.2f", f)
	return StrToFloat(fstr)
}

// DecimalAddSS 精确相加 字符串
func DecimalAddFS(v1 float64, v2 string) float64 {
	v2 = AmountFormat2str(v2)
	r := DecimalAddFF(v1, StrToFloat(v2))
	return r
}

// string to Float
func AmountFormat2str(str string) string {
	return strings.TrimSpace(strings.ReplaceAll(str, ",", ""))
}

func StrToFloToStr(str string) string {
	sflo := StrToFloat(str)
	str = FloatToStr(sflo)
	return str
}

// 获取input的值
func GetInputValue(p *rod.Page, xPath string) string {
	str := MustElementX(p, xPath).MustEval(`()=>{return this.value}`).Str()
	return strings.ReplaceAll(str, ",", "")
}

func FloatToStrN(f float64, lens ...int) string {
	if f == 0 {
		return ""
	}
	lenth := 2
	if len(lens) == 1 {
		lenth = lens[0]
	}
	str := strconv.FormatFloat(f, 'f', lenth, 64)
	if str == "-0.000" || str == "-0.00" || str == "-0.0" || str == "-0" {
		str = ""
	}
	return str
}

// FormatFloat 主要逻辑就是先乘，trunc之后再除回去，就达到了保留N位小数的效果
func FormatFloat(num float64, decimal int) string {
	// 默认乘1
	d := float64(1)
	if decimal > 0 {
		// 10的N次方
		d = math.Pow10(decimal)
	}
	// math.trunc作用就是返回浮点数的整数部分
	// 再除回去，小数点后无效的0也就不存在了
	return strconv.FormatFloat(math.Trunc(num*d)/d, 'f', -1, 64)
}

func DecimalDivSS(v1 string, v2 string) float64 {
	v1 = AmountFormat2str(v1)
	v2 = AmountFormat2str(v2)
	r := DecimalDivFF(StrToFloat(v1), StrToFloat(v2))
	return r
}

func DecimalAddSS(v1 string, v2 string) float64 {
	v1 = AmountFormat2str(v1)
	v2 = AmountFormat2str(v2)
	r := DecimalAddFF(StrToFloat(v1), StrToFloat(v2))
	return r
}

// string to uint
func StrToUint(str string) uint {
	intValue, _ := strconv.Atoi(str)
	return uint(intValue)
}

func FloatToStr4(f float64, len int) string {
	// 如果格式标记为 'e'，'E'和'f'，则 prec 表示小数点后的数字位数
	// 如果格式标记为 'g'，'G'，则 prec 表示总的数字位数（整数部分+小数部分）
	//func FormatFloat(f float64, fmt byte, prec, bitSize int) string
	//f := 100.12345678901234567890123456789
	//zaplog.LoggerS.Info(strconv.FormatFloat(f, 'f', 5, 64))
	// 100.12346
	//zaplog.LoggerS.Info(strconv.FormatFloat(f, 'g', 5, 64))
	// 100.12
	//zaplog.LoggerS.Info(strconv.FormatFloat(f, 'G', 5, 64))
	// 100.12
	return strconv.FormatFloat(f, 'f', len, 64)
}

// string to Float
func AmountFormat(str string) float64 {
	return StrToFloatAll(strings.TrimSpace(strings.ReplaceAll(str, ",", "")))
}
