package config

import (
	"fmt"
	"os"

	"github.com/joho/godotenv"
)

// Config holds all configuration for the AI Compliance SDK
type Config struct {
	// Server
	Port        string
	Environment string

	// Database
	DatabaseURL string

	// JWT
	JWTSecret string

	// CORS
	AllowedOrigins []string

	// Rate Limiting
	RateLimitRequests int
	RateLimitWindow   int // in seconds

	// LLM Providers
	LLMProvider         string // 'ollama', 'anthropic', 'openai'
	LLMFallbackProvider string // Fallback provider if primary fails

	// Ollama Configuration
	OllamaURL          string
	OllamaDefaultModel string

	// Anthropic Configuration
	AnthropicAPIKey     string
	AnthropicDefaultModel string

	// OpenAI Configuration (optional)
	OpenAIAPIKey     string
	OpenAIDefaultModel string

	// PII Detection
	PIIRedactionEnabled bool
	PIIRedactionLevel   string // 'strict', 'moderate', 'minimal'

	// Audit
	AuditRetentionDays int
	AuditExportEnabled bool

	// Valkey/Redis for Caching
	ValkeyURL     string
	ValkeyEnabled bool

	// Consent Service Integration
	ConsentServiceURL string

	// Frontend URLs
	AdminFrontendURL string
	// TTS Service
	TTSServiceURL string
}

// Load loads configuration from environment variables
func Load() (*Config, error) {
	// Load .env file if exists (for development)
	_ = godotenv.Load()

	cfg := &Config{
		Port:              getEnv("PORT", "8090"),
		Environment:       getEnv("ENVIRONMENT", "development"),
		DatabaseURL:       getEnv("DATABASE_URL", ""),
		JWTSecret:         getEnv("JWT_SECRET", ""),
		RateLimitRequests: getEnvInt("RATE_LIMIT_REQUESTS", 100),
		RateLimitWindow:   getEnvInt("RATE_LIMIT_WINDOW", 60),

		// LLM Configuration
		LLMProvider:         getEnv("LLM_PROVIDER", "ollama"),
		LLMFallbackProvider: getEnv("LLM_FALLBACK_PROVIDER", "anthropic"),

		// Ollama
		OllamaURL:          getEnv("OLLAMA_URL", "http://localhost:11434"),
		OllamaDefaultModel: getEnv("OLLAMA_DEFAULT_MODEL", "qwen2.5:7b"),

		// Anthropic
		AnthropicAPIKey:     getEnv("ANTHROPIC_API_KEY", ""),
		AnthropicDefaultModel: getEnv("ANTHROPIC_DEFAULT_MODEL", "claude-3-sonnet-20240229"),

		// OpenAI
		OpenAIAPIKey:     getEnv("OPENAI_API_KEY", ""),
		OpenAIDefaultModel: getEnv("OPENAI_DEFAULT_MODEL", "gpt-4-turbo-preview"),

		// PII
		PIIRedactionEnabled: getEnvBool("PII_REDACTION_ENABLED", true),
		PIIRedactionLevel:   getEnv("PII_REDACTION_LEVEL", "strict"),

		// Audit
		AuditRetentionDays: getEnvInt("AUDIT_RETENTION_DAYS", 365),
		AuditExportEnabled: getEnvBool("AUDIT_EXPORT_ENABLED", true),

		// Valkey
		ValkeyURL:     getEnv("VALKEY_URL", "redis://localhost:6379"),
		ValkeyEnabled: getEnvBool("VALKEY_ENABLED", true),

		// Integration
		ConsentServiceURL: getEnv("CONSENT_SERVICE_URL", "http://localhost:8081"),
		AdminFrontendURL:  getEnv("ADMIN_FRONTEND_URL", "http://localhost:3002"),
		TTSServiceURL:    getEnv("TTS_SERVICE_URL", "http://compliance-tts-service:8095"),
	}

	// Parse allowed origins
	originsStr := getEnv("ALLOWED_ORIGINS", "http://localhost:3000,http://localhost:3002,http://localhost:8000")
	cfg.AllowedOrigins = parseCommaSeparated(originsStr)

	// Validate required fields
	if cfg.DatabaseURL == "" {
		return nil, fmt.Errorf("DATABASE_URL is required")
	}

	if cfg.JWTSecret == "" {
		return nil, fmt.Errorf("JWT_SECRET is required")
	}

	return cfg, nil
}

func getEnv(key, defaultValue string) string {
	if value := os.Getenv(key); value != "" {
		return value
	}
	return defaultValue
}

func getEnvInt(key string, defaultValue int) int {
	if value := os.Getenv(key); value != "" {
		var result int
		fmt.Sscanf(value, "%d", &result)
		return result
	}
	return defaultValue
}

func getEnvBool(key string, defaultValue bool) bool {
	if value := os.Getenv(key); value != "" {
		return value == "true" || value == "1" || value == "yes"
	}
	return defaultValue
}

func parseCommaSeparated(s string) []string {
	if s == "" {
		return []string{}
	}
	var result []string
	start := 0
	for i := 0; i <= len(s); i++ {
		if i == len(s) || s[i] == ',' {
			item := s[start:i]
			// Trim whitespace
			for len(item) > 0 && item[0] == ' ' {
				item = item[1:]
			}
			for len(item) > 0 && item[len(item)-1] == ' ' {
				item = item[:len(item)-1]
			}
			if item != "" {
				result = append(result, item)
			}
			start = i + 1
		}
	}
	return result
}

// IsDevelopment returns true if running in development mode
func (c *Config) IsDevelopment() bool {
	return c.Environment == "development"
}

// IsProduction returns true if running in production mode
func (c *Config) IsProduction() bool {
	return c.Environment == "production"
}
