package game

import (
	"encoding/json"
	"net/url"
	"strings"

	gamedomain "hyapp/services/game-service/internal/domain/game"
)

type bridgeScriptConfig struct {
	URL            string `json:"bridge_script_url"`
	URLAlias       string `json:"bridgeScriptUrl"`
	Version        string `json:"bridge_script_version"`
	VersionAlias   string `json:"bridgeScriptVersion"`
	SHA256         string `json:"bridge_script_sha256"`
	SHA256Alias    string `json:"bridgeScriptSha256"`
	SHA256AltAlias string `json:"bridge_script_hash"`
}

func bridgeScriptConfigFromPlatform(value any) bridgeScriptConfig {
	var raw string
	switch typed := value.(type) {
	case gamedomain.Platform:
		raw = typed.AdapterConfigJSON
	case gamedomain.LaunchableGame:
		raw = typed.AdapterConfigJSON
	}
	var config bridgeScriptConfig
	_ = json.Unmarshal([]byte(strings.TrimSpace(raw)), &config)
	config.URL = firstBridgeScriptValue(config.URL, config.URLAlias)
	config.Version = firstBridgeScriptValue(config.Version, config.VersionAlias)
	config.SHA256 = firstBridgeScriptValue(config.SHA256, config.SHA256Alias, config.SHA256AltAlias)
	return config
}

func firstBridgeScriptValue(values ...string) string {
	for _, value := range values {
		normalized := strings.TrimSpace(value)
		if normalized != "" {
			return normalized
		}
	}
	return ""
}

func appendBridgeScriptQuery(query url.Values, game gamedomain.LaunchableGame) {
	config := bridgeScriptConfigFromPlatform(game)
	if config.URL == "" {
		return
	}
	// Flutter 从启动 URL 还原 bridgeConfig；同时写 snake/camel 别名，避免 H5 或老客户端只识别其中一种命名。
	query.Set("bridge_script_url", config.URL)
	query.Set("bridgeScriptUrl", config.URL)
	if config.Version != "" {
		query.Set("bridge_script_version", config.Version)
		query.Set("bridgeScriptVersion", config.Version)
	}
	if config.SHA256 != "" {
		query.Set("bridge_script_sha256", config.SHA256)
		query.Set("bridgeScriptSha256", config.SHA256)
	}
	appendBridgeKeys(query, "bridge_script_url", "bridge_script_version", "bridge_script_sha256")
}

func appendBridgeKeys(query url.Values, keys ...string) {
	seen := make(map[string]bool)
	values := make([]string, 0, len(keys)+1)
	for _, raw := range strings.Split(query.Get("bridge_keys"), ",") {
		key := strings.TrimSpace(raw)
		if key == "" || seen[key] {
			continue
		}
		seen[key] = true
		values = append(values, key)
	}
	for _, raw := range keys {
		key := strings.TrimSpace(raw)
		if key == "" || seen[key] {
			continue
		}
		seen[key] = true
		values = append(values, key)
	}
	if len(values) > 0 {
		query.Set("bridge_keys", strings.Join(values, ","))
	}
}
