package profile

import (
	"encoding/json"
	"strings"
)

type openCodeConfig struct {
	Model    string                      `json:"model"`
	Provider map[string]openCodeProvider `json:"provider"`
}

type openCodeProvider struct {
	NPM     string                   `json:"npm,omitempty"`
	Name    string                   `json:"name,omitempty"`
	Options *openCodeProviderOptions `json:"options,omitempty"`
	Models  map[string]interface{}   `json:"models,omitempty"`
}

type openCodeProviderOptions struct {
	BaseURL string            `json:"baseURL,omitempty"`
	APIKey  string            `json:"apiKey,omitempty"`
	Headers map[string]string `json:"headers,omitempty"`
	WireAPI string            `json:"wireAPI,omitempty"`
	EnvKey  string            `json:"envKey,omitempty"`
}

type claudeSettings struct {
	Env map[string]json.RawMessage `json:"env"`
}

// rawEnvValue extracts a string value from a raw JSON env map,
// tolerating non-string types by using their JSON representation.
func rawEnvValue(env map[string]json.RawMessage, key string) string {
	raw, ok := env[key]
	if !ok {
		return ""
	}
	var s string
	if err := json.Unmarshal(raw, &s); err == nil {
		return s
	}
	return string(raw)
}

type codexConfig struct {
	ModelProvider        string                        `toml:"model_provider"`
	Model                string                        `toml:"model"`
	ModelReasoningEffort string                        `toml:"model_reasoning_effort"`
	ModelProviders       map[string]codexModelProvider `toml:"model_providers"`
}

type codexModelProvider struct {
	Name    string `toml:"name"`
	BaseURL string `toml:"base_url"`
	WireAPI string `toml:"wire_api"`
	EnvKey  string `toml:"env_key"`
}

func stripJSONComments(s string) string {
	var result strings.Builder
	result.Grow(len(s))

	i := 0
	inString := false
	escape := false

	for i < len(s) {
		ch := s[i]

		if escape {
			result.WriteByte(ch)
			escape = false
			i++
			continue
		}

		if ch == '\\' && inString {
			result.WriteByte(ch)
			escape = true
			i++
			continue
		}

		if ch == '"' {
			inString = !inString
			result.WriteByte(ch)
			i++
			continue
		}

		if inString {
			result.WriteByte(ch)
			i++
			continue
		}

		if ch == '/' && i+1 < len(s) {
			if s[i+1] == '/' {
				for i < len(s) && s[i] != '\n' {
					i++
				}
				continue
			}
			if s[i+1] == '*' {
				i += 2
				for i+1 < len(s) && !(s[i] == '*' && s[i+1] == '/') {
					i++
				}
				if i+1 < len(s) {
					i += 2
				}
				continue
			}
		}

		result.WriteByte(ch)
		i++
	}

	return result.String()
}
