package helper

import (
	"net"
	"strings"

	"github.com/go-kratos/kratos/v2/transport/http"
)

// GetClientIP 获取客户端真实 IP
func GetClientIP(ctx http.Context) string {

	// 检查 X-Forwarded-For 头（多个代理时格式为 "client, proxy1, proxy2"）
	if xff := ctx.Header().Get("X-Forwarded-For"); xff != "" {
		ips := strings.Split(xff, ",")
		for _, ip := range ips {
			ip = strings.TrimSpace(ip)
			if ip != "" {
				// 验证是否为合法 IP
				if isValidIP(ip) {
					return ip
				}
			}
		}
	}

	// 检查 X-Real-IP 头
	if realIP := ctx.Header().Get("X-Real-IP"); realIP != "" {
		if isValidIP(realIP) {
			return realIP
		}
	}

	// 检查 X-Forwarded
	if forwarded := ctx.Header().Get("X-Forwarded"); forwarded != "" {
		// 格式可能为 "for=client-ip;host=example.com;proto=https"
		parts := strings.Split(forwarded, ";")
		for _, part := range parts {
			part = strings.TrimSpace(part)
			if strings.HasPrefix(part, "for=") {
				ip := strings.TrimPrefix(part, "for=")
				ip = strings.Trim(ip, `"`) // 可能被引号包围
				if isValidIP(ip) {
					return ip
				}
			}
		}
	}

	// 直接从 RemoteAddr 获取
	remoteAddr := ctx.Request().RemoteAddr
	if ip, _, err := net.SplitHostPort(remoteAddr); err == nil {
		if isValidIP(ip) {
			return ip
		}
	}

	return ""
}

// 验证是否为合法 IP
func isValidIP(ip string) bool {
	parsedIP := net.ParseIP(ip)
	return parsedIP != nil
}
