package utils

import (
	"context"
	"fmt"
	"github.com/gogf/gf/v2/crypto/gaes"
	"github.com/gogf/gf/v2/encoding/gbase64"
	"strings"

	"github.com/gogf/gf/v2/encoding/gcharset"
	"github.com/gogf/gf/v2/encoding/gjson"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
)

// GetCityByIp 获取ip所属城市
func GetCityByIp(ctx context.Context, ip string) string {
	if ip == "" {
		return ""
	}
	if ip == "::1" || ip == "127.0.0.1" {
		return "内网IP"
	}
	url := "https://whois.pconline.com.cn/ipJson.jsp?json=true&ip=" + ip
	bytes := g.Client().GetBytes(ctx, url)
	src := string(bytes)
	srcCharset := "GBK"
	tmp, _ := gcharset.ToUTF8(srcCharset, src)
	json, err := gjson.DecodeToJson(tmp)
	if err != nil {
		return ""
	}
	if json.Get("code").Int() == 0 {
		city := fmt.Sprintf("%s %s", json.Get("pro").String(), json.Get("city").String())
		return city
	} else {
		return ""
	}
}

func GetIPFromCtx(ctx context.Context) string {
	return ghttp.RequestFromCtx(ctx).GetClientIp()
}

// GetUserAgent 获取user-agent
func GetUserAgent(ctx context.Context) string {
	return ghttp.RequestFromCtx(ctx).Header.Get("User-Agent")
}

// GetTargetIndex 返回制定长度内，当前数字的下一个数字，如果超过最大数字，返回当前数字在0~max之间
func GetTargetIndex(num, max int) int {
	if num < 0 {
		return 0
	}
	return num % max
}

// GetClientTypeFromUserAgent 从 useragent中获取客户端类型
func GetClientTypeFromUserAgent(userAgent string) string {
	if strings.Contains(userAgent, "iPhone") {
		return "iPhone"
	}
	if strings.Contains(userAgent, "Android") {
		return "Android"
	}
	return "web"
}

func Decrypt(s string) (string, error) {
	key, _ := gbase64.DecodeString("P0x6Gy6dXIpPbhE7PHxaHbfZHhsbT2qNPlx3qbHTP1o=")
	iv, _ := gbase64.DecodeString("nywao1XkDXeYwbPeWh+SxA==")
	text, _ := gbase64.DecodeString(s)
	result, err := gaes.Decrypt(text, key, iv)
	if err != nil {
		return "", err
	}
	return string(result), nil
}

// MaskSensitiveData 对敏感数据进行隐私处理
// prefixLen: 前缀保留长度, suffixLen: 后缀保留长度, maskChar: 掩码字符
func MaskSensitiveData(data string, prefixLen, suffixLen int, maskChar string) string {
	if len(data) <= prefixLen+suffixLen {
		// 如果数据长度小于等于需要显示的长度，全部用掩码代替
		return strings.Repeat(maskChar, len(data))
	}

	// 构建掩码字符串
	maskLen := len(data) - prefixLen - suffixLen
	mask := strings.Repeat(maskChar, maskLen)

	// 返回前缀 + 掩码 + 后缀
	return data[:prefixLen] + mask + data[len(data)-suffixLen:]
}

// MaskTokenValue 对 Token 值进行隐私处理，默认显示前4位和后4位
func MaskTokenValue(tokenValue string) string {
	return MaskSensitiveData(tokenValue, 4, 4, "*")
}

// MaskPhoneNumber 对手机号进行隐私处理，显示前3位和后4位
func MaskPhoneNumber(phone string) string {
	return MaskSensitiveData(phone, 3, 4, "*")
}

// MaskEmail 对邮箱进行隐私处理，显示前2位和@后的域名
func MaskEmail(email string) string {
	if email == "" {
		return ""
	}

	parts := strings.Split(email, "@")
	if len(parts) != 2 {
		return MaskSensitiveData(email, 2, 2, "*")
	}

	username := parts[0]
	domain := parts[1]

	if len(username) <= 2 {
		return MaskSensitiveData(email, 2, 2, "*")
	}

	return username[:2] + strings.Repeat("*", len(username)-2) + "@" + domain
}

// MaskBankCard 对银行卡号进行隐私处理，显示前4位和后4位
func MaskBankCard(cardNumber string) string {
	return MaskSensitiveData(cardNumber, 4, 4, "*")
}

// MaskIDCard 对身份证号进行隐私处理，显示前3位和后4位
func MaskIDCard(idCard string) string {
	return MaskSensitiveData(idCard, 3, 4, "*")
}
