// internal/config/config.go
package config

import (
	"database/sql"
	"fmt"
	"log"
	"os"
	"time"

	_ "github.com/lib/pq"
	"github.com/redis/go-redis/v9"
)

type Config struct {
	ServerAddress string
	DatabaseURL   string
	RedisAddr     string
	RedisPassword string
	RedisDB       int
	TimeThreshold time.Duration
}

func Load() *Config {
	timeThresholdStr := getEnv("TIME_THRESHOLD", "1h")
	timeThreshold, err := time.ParseDuration(timeThresholdStr)
	if err != nil {
		log.Printf("Invalid TIME_THRESHOLD '%s', using default 1h", timeThresholdStr)
		timeThreshold = 1 * time.Hour
	}

	// ساخت DATABASE_URL از environment variables جداگانه
	dbURL := getEnv("DATABASE_URL", "")
	if dbURL == "" {
		host := getEnv("DB_HOST", "localhost")
		port := getEnv("DB_PORT", "5432")
		user := getEnv("DB_USER", "postgres")
		password := getEnv("DB_PASSWORD", "secret")
		dbname := getEnv("DB_NAME", "loan")
		dbURL = fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
			host, port, user, password, dbname)
	}

	// ساخت Redis address
	redisAddr := getEnv("REDIS_ADDR", "")
	if redisAddr == "" {
		redisHost := getEnv("REDIS_HOST", "localhost")
		redisPort := getEnv("REDIS_PORT", "6379")
		redisAddr = fmt.Sprintf("%s:%s", redisHost, redisPort)
	}

	return &Config{
		ServerAddress: getEnv("SERVER_ADDRESS", ":8080"),
		DatabaseURL:   dbURL,
		RedisAddr:     redisAddr,
		RedisPassword: getEnv("REDIS_PASSWORD", ""),
		RedisDB:       0,
		TimeThreshold: timeThreshold,
	}
}

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

func ConnectDB(cfg *Config) (*sql.DB, error) {
	db, err := sql.Open("postgres", cfg.DatabaseURL)
	if err != nil {
		return nil, err
	}

	db.SetMaxOpenConns(25)
	db.SetMaxIdleConns(5)
	db.SetConnMaxLifetime(5 * time.Minute)

	if err := db.Ping(); err != nil {
		return nil, fmt.Errorf("database ping failed: %w", err)
	}

	return db, nil
}

func ConnectRedis(cfg *Config) *redis.Client {
	client := redis.NewClient(&redis.Options{
		Addr:     cfg.RedisAddr,
		Password: cfg.RedisPassword,
		DB:       cfg.RedisDB,
	})

	return client
}
