package netproxy

import (
	"fmt"
	"net/url"
	"strings"
)

const (
	ModeNone   = "none"
	ModeGlobal = "global"
	ModeCustom = "custom"
)

type Config struct {
	Mode      string
	HTTPProxy string
}

func FromPlatformConfig(values map[string]any) Config {
	config := Config{
		Mode:      stringFromMap(values, "proxyMode"),
		HTTPProxy: stringFromMap(values, "httpProxy"),
	}
	if nested := recordFromAny(values["networkProxy"]); nested != nil {
		if mode := stringFromMap(nested, "mode"); mode != "" {
			config.Mode = mode
		}
		if proxy := stringFromMap(nested, "httpProxy"); proxy != "" {
			config.HTTPProxy = proxy
		}
	}
	return config
}

func Normalize(input Config) (Config, error) {
	mode, err := normalizeMode(input.Mode)
	if err != nil {
		return Config{}, err
	}
	config := Config{Mode: mode}
	if mode != ModeCustom {
		return config, nil
	}
	normalized, _, err := ParseHTTPProxy(input.HTTPProxy)
	if err != nil {
		return Config{}, err
	}
	config.HTTPProxy = normalized
	return config, nil
}

func NormalizePlatformConfig(values map[string]any) (map[string]any, error) {
	next := map[string]any{}
	for key, value := range values {
		next[key] = value
	}
	config, err := Normalize(FromPlatformConfig(values))
	if err != nil {
		return nil, err
	}
	networkProxy := map[string]any{"mode": config.Mode}
	if config.Mode == ModeCustom {
		networkProxy["httpProxy"] = config.HTTPProxy
	}
	next["networkProxy"] = networkProxy
	delete(next, "proxyMode")
	delete(next, "httpProxy")
	return next, nil
}

func ParseHTTPProxy(raw string) (string, *url.URL, error) {
	trimmed := strings.TrimSpace(raw)
	if trimmed == "" {
		return "", nil, fmt.Errorf("http proxy is required")
	}
	if !strings.Contains(trimmed, "://") {
		trimmed = "http://" + trimmed
	}
	parsed, err := url.Parse(trimmed)
	if err != nil {
		return "", nil, fmt.Errorf("invalid http proxy: %w", err)
	}
	if parsed.Scheme != "http" && parsed.Scheme != "https" {
		return "", nil, fmt.Errorf("http proxy scheme must be http or https")
	}
	if parsed.Host == "" {
		return "", nil, fmt.Errorf("http proxy host is required")
	}
	return parsed.String(), parsed, nil
}

func normalizeMode(value string) (string, error) {
	switch strings.ToLower(strings.TrimSpace(value)) {
	case "", "none", "off", "disabled", "disable":
		return ModeNone, nil
	case "global", "system", "env", "environment":
		return ModeGlobal, nil
	case "custom":
		return ModeCustom, nil
	default:
		return "", fmt.Errorf("unsupported proxy mode %q", value)
	}
}

func recordFromAny(value any) map[string]any {
	record, _ := value.(map[string]any)
	return record
}

func stringFromMap(values map[string]any, key string) string {
	value, _ := values[key].(string)
	return strings.TrimSpace(value)
}
