package config

import (
	"fmt"
	"os"

	"github.com/joho/godotenv"
)

// Config holds all configuration for the service
type Config struct {
	// Server
	Port        string
	Environment string

	// Database
	DatabaseURL string

	// JWT
	JWTSecret        string
	JWTRefreshSecret string

	// CORS
	AllowedOrigins []string

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

	// BreakPilot Integration
	BreakPilotAPIURL string
	FrontendURL      string

	// SMTP Email Configuration
	SMTPHost     string
	SMTPPort     int
	SMTPUsername string
	SMTPPassword string
	SMTPFromName string
	SMTPFromAddr string

	// Consent Settings
	ConsentDeadlineDays    int
	ConsentReminderEnabled bool

	// VAPID Keys for Web Push
	VAPIDPublicKey  string
	VAPIDPrivateKey string

	// Matrix (Synapse) Configuration
	MatrixHomeserverURL string
	MatrixAccessToken   string
	MatrixServerName    string
	MatrixEnabled       bool

	// Jitsi Configuration
	JitsiBaseURL   string
	JitsiAppID     string
	JitsiAppSecret string
	JitsiEnabled   bool
}

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

	cfg := &Config{
		Port:              getEnv("PORT", "8080"),
		Environment:       getEnv("ENVIRONMENT", "development"),
		DatabaseURL:       getEnv("DATABASE_URL", ""),
		JWTSecret:         getEnv("JWT_SECRET", ""),
		JWTRefreshSecret:  getEnv("JWT_REFRESH_SECRET", ""),
		RateLimitRequests: getEnvInt("RATE_LIMIT_REQUESTS", 100),
		RateLimitWindow:   getEnvInt("RATE_LIMIT_WINDOW", 60),
		BreakPilotAPIURL:  getEnv("BREAKPILOT_API_URL", "http://localhost:8000"),
		FrontendURL:       getEnv("FRONTEND_URL", "http://localhost:8000"),

		// SMTP Configuration
		SMTPHost:     getEnv("SMTP_HOST", ""),
		SMTPPort:     getEnvInt("SMTP_PORT", 587),
		SMTPUsername: getEnv("SMTP_USERNAME", ""),
		SMTPPassword: getEnv("SMTP_PASSWORD", ""),
		SMTPFromName: getEnv("SMTP_FROM_NAME", "BreakPilot"),
		SMTPFromAddr: getEnv("SMTP_FROM_ADDR", "noreply@breakpilot.app"),

		// Consent Settings
		ConsentDeadlineDays:    getEnvInt("CONSENT_DEADLINE_DAYS", 30),
		ConsentReminderEnabled: getEnvBool("CONSENT_REMINDER_ENABLED", true),

		// VAPID Keys
		VAPIDPublicKey:  getEnv("VAPID_PUBLIC_KEY", ""),
		VAPIDPrivateKey: getEnv("VAPID_PRIVATE_KEY", ""),

		// Matrix Configuration
		MatrixHomeserverURL: getEnv("MATRIX_HOMESERVER_URL", "http://synapse:8008"),
		MatrixAccessToken:   getEnv("MATRIX_ACCESS_TOKEN", ""),
		MatrixServerName:    getEnv("MATRIX_SERVER_NAME", "breakpilot.local"),
		MatrixEnabled:       getEnvBool("MATRIX_ENABLED", true),

		// Jitsi Configuration
		JitsiBaseURL:   getEnv("JITSI_BASE_URL", "http://localhost:8443"),
		JitsiAppID:     getEnv("JITSI_APP_ID", "breakpilot"),
		JitsiAppSecret: getEnv("JITSI_APP_SECRET", ""),
		JitsiEnabled:   getEnvBool("JITSI_ENABLED", true),
	}

	// Parse allowed origins
	originsStr := getEnv("ALLOWED_ORIGINS", "http://localhost:3000,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
}
