package config

import (
	"fmt"
	"os"

	"github.com/joho/godotenv"
)

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

	// Database
	DatabaseURL string

	// JWT (shared with consent-service)
	JWTSecret string

	// Stripe
	StripeSecretKey       string
	StripeWebhookSecret   string
	StripePublishableKey  string
	StripeMockMode        bool   // If true, Stripe calls are mocked (for dev without Stripe keys)

	// URLs
	BillingSuccessURL string
	BillingCancelURL  string
	FrontendURL       string

	// Trial
	TrialPeriodDays int

	// CORS
	AllowedOrigins []string

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

	// Internal API Key (for service-to-service communication)
	InternalAPIKey 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", "8083"),
		Environment:       getEnv("ENVIRONMENT", "development"),
		DatabaseURL:       getEnv("DATABASE_URL", ""),
		JWTSecret:         getEnv("JWT_SECRET", ""),

		// Stripe
		StripeSecretKey:      getEnv("STRIPE_SECRET_KEY", ""),
		StripeWebhookSecret:  getEnv("STRIPE_WEBHOOK_SECRET", ""),
		StripePublishableKey: getEnv("STRIPE_PUBLISHABLE_KEY", ""),
		StripeMockMode:       getEnvBool("STRIPE_MOCK_MODE", false),

		// URLs
		BillingSuccessURL: getEnv("BILLING_SUCCESS_URL", "http://localhost:8000/app/billing/success"),
		BillingCancelURL:  getEnv("BILLING_CANCEL_URL", "http://localhost:8000/app/billing/cancel"),
		FrontendURL:       getEnv("FRONTEND_URL", "http://localhost:8000"),

		// Trial
		TrialPeriodDays: getEnvInt("TRIAL_PERIOD_DAYS", 7),

		// Rate Limiting
		RateLimitRequests: getEnvInt("RATE_LIMIT_REQUESTS", 100),
		RateLimitWindow:   getEnvInt("RATE_LIMIT_WINDOW", 60),

		// Internal API
		InternalAPIKey: getEnv("INTERNAL_API_KEY", ""),
	}

	// 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")
	}

	// Stripe key is required unless mock mode is enabled
	if cfg.StripeSecretKey == "" && !cfg.StripeMockMode {
		// In development mode, auto-enable mock mode if no Stripe key
		if cfg.Environment == "development" {
			cfg.StripeMockMode = true
		} else {
			return nil, fmt.Errorf("STRIPE_SECRET_KEY is required (set STRIPE_MOCK_MODE=true to bypass in dev)")
		}
	}

	return cfg, nil
}

// IsMockMode returns true if Stripe should be mocked
func (c *Config) IsMockMode() bool {
	return c.StripeMockMode
}

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
}
