package config

import (
	"strings"
	"time"

	"github.com/spf13/viper"
)

// Config contiene toda la configuración de la aplicación
type Config struct {
	App      AppConfig      `mapstructure:"app"`
	Database DatabaseConfig `mapstructure:"database"`
	Soap     SoapConfig     `mapstructure:"soap"`
}

// contiene la configuración general de la aplicación
type AppConfig struct {
	Name           string        `mapstructure:"name"`
	Port           int           `mapstructure:"port"`
	Environment    string        `mapstructure:"environment"`
	LogLevel       string        `mapstructure:"log_level"`
	RequestTimeout time.Duration `mapstructure:"request_timeout"`
	LogFilePath    string        `mapstructure:"log_file_path"`
	LogMaxSize     int           `mapstructure:"log_max_size"`
	LogMaxBackups  int           `mapstructure:"log_max_backups"`
	LogMaxAge      int           `mapstructure:"log_max_age"`
	LogCompress    bool          `mapstructure:"log_compress"`
}

// DatabaseConfig contiene la configuración de la base de datos
type DatabaseConfig struct {
	Host            string        `mapstructure:"host"`
	Port            int           `mapstructure:"port"`
	Username        string        `mapstructure:"username"`
	Password        string        `mapstructure:"password"`
	Database        string        `mapstructure:"database"`
	MaxOpenConns    int           `mapstructure:"max_open_conns"`
	MaxIdleConns    int           `mapstructure:"max_idle_conns"`
	ConnMaxLifetime time.Duration `mapstructure:"conn_max_lifetime"`
}

// SoapConfig contiene la configuración general para clientes SOAP
type SoapConfig struct {
	Timeout time.Duration        `mapstructure:"timeout"`
	APIs    map[string]APIConfig `mapstructure:"apis"`
}

// APIConfig contiene la configuración específica para cada API SOAP
type APIConfig struct {
	Endpoint string        `mapstructure:"endpoint"`
	Username string        `mapstructure:"username"`
	Password string        `mapstructure:"password"`
	Timeout  time.Duration `mapstructure:"timeout"`
}

// LoadConfig carga la configuración desde el archivo config.yaml
func LoadConfig() (*Config, error) {
	viper.SetConfigName("config")
	viper.SetConfigType("yaml")
	viper.AddConfigPath("./configs")
	viper.AddConfigPath(".")
	viper.AutomaticEnv()
	viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))

	if err := viper.ReadInConfig(); err != nil {
		return nil, err
	}

	var config Config
	if err := viper.Unmarshal(&config); err != nil {
		return nil, err
	}

	return &config, nil
}

// actualiza la configuración con parámetros de la base de datos
func (c *Config) MergeParameters(params map[string]string) {
	// Ejemplo de sobrescritura de configuración con parámetros de BD
	if endpoint, ok := params["soap.api1.endpoint"]; ok {
		if api1Config, exists := c.Soap.APIs["api1"]; exists {
			api1Config.Endpoint = endpoint
			c.Soap.APIs["api1"] = api1Config
		}
	}

	if endpoint, ok := params["soap.api2.endpoint"]; ok {
		if api2Config, exists := c.Soap.APIs["api2"]; exists {
			api2Config.Endpoint = endpoint
			c.Soap.APIs["api2"] = api2Config
		}
	}
	// Otros parámetros pueden ser añadidos según sea necesario
}
