package config

import (
	"fmt"
	"os"
	"strconv"
	"time"

	"github.com/jackc/pgx/v5/pgxpool"
)

// DatabaseConfig holds database configuration
type DatabaseConfig struct {
	Host            string
	Port            int
	User            string
	Password        string
	Database        string
	SSLMode         string
	MaxConnections  int
	MaxIdleTime     time.Duration
	ConnMaxLifetime time.Duration
}

// LoadDatabaseConfig loads database configuration from environment variables
func LoadDatabaseConfig() *DatabaseConfig {
	maxConns, _ := strconv.Atoi(getEnv("DB_MAX_CONNECTIONS", "25"))
	maxIdle, _ := time.ParseDuration(getEnv("DB_MAX_IDLE_TIME", "5m"))
	maxLifetime, _ := time.ParseDuration(getEnv("DB_CONN_MAX_LIFETIME", "1h"))

	return &DatabaseConfig{
		Host:            getEnv("DB_HOST", "localhost"),
		Port:            getIntEnv("DB_PORT", 5432),
		User:            getEnv("DB_USER", "explorer"),
		Password:        getEnv("DB_PASSWORD", ""),
		Database:        getEnv("DB_NAME", "explorer"),
		SSLMode:         getEnv("DB_SSLMODE", "disable"),
		MaxConnections:  maxConns,
		MaxIdleTime:     maxIdle,
		ConnMaxLifetime: maxLifetime,
	}
}

// ConnectionString returns PostgreSQL connection string
func (c *DatabaseConfig) ConnectionString() string {
	return fmt.Sprintf(
		"host=%s port=%d user=%s password=%s dbname=%s sslmode=%s",
		c.Host, c.Port, c.User, c.Password, c.Database, c.SSLMode,
	)
}

// PoolConfig returns pgxpool configuration
func (c *DatabaseConfig) PoolConfig() (*pgxpool.Config, error) {
	config, err := pgxpool.ParseConfig(c.ConnectionString())
	if err != nil {
		return nil, err
	}

	config.MaxConns = int32(c.MaxConnections)
	config.MaxConnIdleTime = c.MaxIdleTime
	config.MaxConnLifetime = c.ConnMaxLifetime

	return config, nil
}

// ReadReplicaConfig holds read replica configuration
type ReadReplicaConfig struct {
	Host     string
	Port     int
	User     string
	Password string
	Database string
	SSLMode  string
}

// LoadReadReplicaConfig loads read replica configuration
func LoadReadReplicaConfig() *ReadReplicaConfig {
	return &ReadReplicaConfig{
		Host:     getEnv("DB_REPLICA_HOST", ""),
		Port:     getIntEnv("DB_REPLICA_PORT", 5432),
		User:     getEnv("DB_REPLICA_USER", ""),
		Password: getEnv("DB_REPLICA_PASSWORD", ""),
		Database: getEnv("DB_REPLICA_NAME", ""),
		SSLMode:  getEnv("DB_REPLICA_SSLMODE", "disable"),
	}
}

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

func getIntEnv(key string, defaultValue int) int {
	if value := os.Getenv(key); value != "" {
		if intValue, err := strconv.Atoi(value); err == nil {
			return intValue
		}
	}
	return defaultValue
}
