package config

import (
	"log"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"github.com/joho/godotenv"
)

// Config holds all configuration for the application
type Config struct {
	// App settings
	AppEnv string
	Port   string
	Debug  bool

	// Database settings
	DatabaseURL        string
	MaxIdleConnections int
	MaxOpenConnections int
	ConnMaxLifetime    time.Duration

	// JWT settings
	JWTSecret     string
	JWTExpiration time.Duration

	// Server settings
	ReadTimeout  time.Duration
	WriteTimeout time.Duration
	IdleTimeout  time.Duration
	// Security
	ContentSecurityPolicy string

	// File upload settings
	UploadDir        string
	MaxUploadSize    int64
	AllowedMimeTypes []string

	// Email settings
	SMTPHost       string
	SMTPPort       int
	SMTPUser       string
	SMTPPassword   string
	SMTPFrom       string
	SMTPFromName   string
	SMTPEncryption string
	SMTPAuth       bool
	SMTPSkipVerify bool

	// Email templates
	EmailTemplateDir string

	// Contact settings
	ContactEmail string
	AdminEmail   string
	// Admin access token (optional) to allow token-based admin access
	AdminAccessToken string

	// Newsletter settings
	NewsletterEnabled bool

	// CORS settings
	AllowedOrigins []string

	// External services
	ScraperBaseURL  string
	FrontendBaseURL string
	PublicAPIBaseURL string
	
	// Umami Analytics
	UmamiURL      string
	UmamiUsername string
	UmamiPassword string
	UmamiWebsiteID string // If empty, will auto-create on production
}

var AppConfig *Config

// LoadConfig loads the configuration from environment variables
func LoadConfig() {
	// Load .env file if it exists
	_ = godotenv.Load()

	AppConfig = &Config{
		// App settings
		AppEnv: getEnv("APP_ENV", "development"),
		Port:   getEnv("PORT", "8080"),
		Debug:  getEnvAsBool("DEBUG", true),

		// Database settings
		DatabaseURL:        getEnv("DATABASE_URL", "postgres://postgres:postgres@localhost:5432/fotbal_club?sslmode=disable"),
		MaxIdleConnections: getEnvAsInt("DB_MAX_IDLE_CONNS", 10),
		MaxOpenConnections: getEnvAsInt("DB_MAX_OPEN_CONNS", 100),
		ConnMaxLifetime:    time.Duration(getEnvAsInt("DB_CONN_MAX_LIFETIME", 60)) * time.Minute,

		// JWT settings
		JWTSecret:     getEnv("JWT_SECRET", "default-secret-key-change-in-production"),
		JWTExpiration: time.Duration(getEnvAsInt("JWT_EXPIRATION_HOURS", 24)) * time.Hour,

		// Server settings
		ReadTimeout:  time.Duration(getEnvAsInt("READ_TIMEOUT", 5)) * time.Second,
		WriteTimeout: time.Duration(getEnvAsInt("WRITE_TIMEOUT", 10)) * time.Second,
		IdleTimeout:  time.Duration(getEnvAsInt("IDLE_TIMEOUT", 120)) * time.Second,

		// Security
		ContentSecurityPolicy: getEnv("CONTENT_SECURITY_POLICY", "default-src 'self' data: blob: https: http:; img-src * data: blob:; style-src 'self' 'unsafe-inline' https: http:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https: http:; connect-src *; frame-ancestors 'self';"),

		// File upload settings
		UploadDir:     getEnv("UPLOAD_DIR", "./uploads"),
		MaxUploadSize: int64(getEnvAsInt("MAX_UPLOAD_SIZE", 10)) * 1024 * 1024, // 10MB default
		AllowedMimeTypes: []string{
			// Images
			"image/jpeg",
			"image/png",
			"image/gif",
			"image/webp",
			"image/svg+xml",
			// Documents
			"application/pdf",
			"application/msword",                                                         // .doc
			"application/vnd.openxmlformats-officedocument.wordprocessingml.document",   // .docx
			"application/vnd.ms-excel",                                                   // .xls
			"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",         // .xlsx
			"application/vnd.ms-powerpoint",                                              // .ppt
			"application/vnd.openxmlformats-officedocument.presentationml.presentation", // .pptx
			// Text
			"text/plain",
			// Archives
			"application/zip",
			"application/x-zip-compressed",
			"application/x-rar-compressed",
			"application/vnd.rar",
		},

		// Email settings
		SMTPHost:       getEnv("SMTP_HOST", "smtp.example.com"),
		SMTPPort:       getEnvAsInt("SMTP_PORT", 587),
		SMTPUser:       getEnv("SMTP_USER", ""),
		SMTPPassword:   getEnv("SMTP_PASSWORD", ""),
		SMTPFrom:       getEnv("SMTP_FROM", "noreply@fotbal-club.cz"),
		SMTPFromName:   getEnv("SMTP_FROM_NAME", "Fotbal Club"),
		SMTPEncryption: getEnv("SMTP_ENCRYPTION", "tls"),
		SMTPAuth:       getEnvAsBool("SMTP_AUTH", true),
		SMTPSkipVerify: getEnvAsBool("SMTP_SKIP_VERIFY", false),

		// Email templates - using absolute path to templates
		EmailTemplateDir: getEnv("EMAIL_TEMPLATE_DIR", filepath.Join("templates", "emails")),

		// Contact settings
		ContactEmail:     getEnv("CONTACT_EMAIL", "help@tdvorak.dev"),
		AdminEmail:       getEnv("ADMIN_EMAIL", "help@tdvorak.dev"),
		AdminAccessToken: getEnv("ADMIN_ACCESS_TOKEN", ""),

		// Newsletter settings
		NewsletterEnabled: getEnvAsBool("NEWSLETTER_ENABLED", true),

		// CORS settings
		AllowedOrigins: []string{
			"http://localhost:3000",
			"http://localhost:8080",
		},

		// External services
		ScraperBaseURL:   getEnv("FACR_SCRAPER_BASE_URL", "http://localhost:8081"),
		FrontendBaseURL:  getEnv("FRONTEND_BASE_URL", "http://localhost:3000"),
		PublicAPIBaseURL: getEnv("PUBLIC_API_BASE_URL", "http://localhost:8080/api/v1"),
		
		// Umami Analytics
		UmamiURL:       getEnv("UMAMI_URL", ""),
		UmamiUsername:  getEnv("UMAMI_USERNAME", ""),
		UmamiPassword:  getEnv("UMAMI_PASSWORD", ""),
		UmamiWebsiteID: getEnv("UMAMI_WEBSITE_ID", ""),
	}

	// Override allowed origins if specified in environment (comma-separated)
	if origins := os.Getenv("ALLOWED_ORIGINS"); origins != "" {
		parts := strings.Split(origins, ",")
		var list []string
		for _, p := range parts {
			v := strings.TrimSpace(p)
			if v != "" {
				list = append(list, v)
			}
		}
		if len(list) > 0 {
			AppConfig.AllowedOrigins = list
		}
	}
}

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

func getEnvAsInt(key string, defaultValue int) int {
	valueStr := os.Getenv(key)
	if valueStr == "" {
		return defaultValue
	}

	value, err := strconv.Atoi(valueStr)
	if err != nil {
		log.Printf("Invalid value for %s: %v. Using default: %d", key, err, defaultValue)
		return defaultValue
	}

	return value
}

func getEnvAsBool(key string, defaultValue bool) bool {
	valueStr := os.Getenv(key)
	if valueStr == "" {
		return defaultValue
	}

	value, err := strconv.ParseBool(valueStr)
	if err != nil {
		log.Printf("Invalid boolean value for %s: %v. Using default: %t", key, err, defaultValue)
		return defaultValue
	}

	return value
}
