package config

import (
	"context"
	"fmt"

	"github.com/joho/godotenv"
	"github.com/sethvargo/go-envconfig"
)

// Config holds the application configuration settings loaded from environment variables
type Config struct {
	// App
	// AppName is the name of the application
	AppName string `env:"APP_NAME, default=rentease"`
	// DatabaseURL is the connection string for the database
	DatabaseURL string `env:"DATABASE_URL, required"`
	// Debug enables debug mode when true
	Debug bool `env:"DEBUG, default=false"`
	// LogLevel is the logging level (e.g., debug, info, warn, error)
	LogLevel string `env:"LOG_LEVEL, default=info"`
	// Origins is the list of allowed origins
	Origins []string `env:"ORIGINS, required"`
	// Port is the HTTP server port number
	Port int `env:"PORT, default=4200"`
	// SentryDsn is the DSN for Sentry error reporting
	SentryDsn string `env:"SENTRY_DSN"`
	// Auth
	// Admin is the email used to access the admin panel
	Admin string `env:"ADMIN, required"`
	// AdminSecret is the password used to access the admin panel
	AdminSecret string `env:"ADMIN_SECRET, required"`
	// APIKey is the API access key
	APIKey string `env:"API_KEY, required"`
	// SecretKey is the secret key used for JWT token signing
	SecretKey string `env:"SECRET_KEY, required"`
	// SessionSecret is the secret key used for session signing
	SessionSecret string `env:"SESSION_SECRET, required"`
	// StripeSecretKey is the API key used to authenticate with Stripe
	StripeSecretKey string `env:"STRIPE_SECRET_KEY"`
	// StripeWebhookSecret is the signing secret for validating Stripe webhooks
	StripeWebhookSecret string `env:"STRIPE_WEBHOOK_SECRET"`
}

// New creates a [Config] struct. It first parses the environment variables. You can use a .env file.
// Please note that the env variables must be prefixed, e.g. with "APP_" to be accounted for.
func New(ctx context.Context) (*Config, error) {
	_ = godotenv.Load()
	config := new(Config)
	if err := envconfig.ProcessWith(ctx, &envconfig.Config{
		Target:   config,
		Lookuper: envconfig.PrefixLookuper("APP_", envconfig.OsLookuper()),
	}); err != nil {
		return nil, fmt.Errorf("could not parse environment variables: %w", err)
	}

	return config, nil
}

// MustConfig is a helper that wraps [New] and panics if an error occurs.
// Use it in cases a [Config] is required and you want to exit the application if an error occurs.
func MustConfig(ctx context.Context) *Config {
	c, err := New(ctx)
	if err != nil {
		panic(err)
	}
	return c
}
