package serverimp

import (
	"os"
	"strings"
	"time"

	"github.com/tech/sendico/pkg/api/routers"
	"github.com/tech/sendico/pkg/server/grpcapp"
	"go.uber.org/zap"
	"gopkg.in/yaml.v3"
)

type config struct {
	*grpcapp.Config   `yaml:",inline"`
	Fees              clientConfig `yaml:"fees"`
	Oracle            clientConfig `yaml:"oracle"`
	QuoteRetentionHrs int          `yaml:"quote_retention_hours"`
}

type clientConfig struct {
	Address           string `yaml:"address"`
	AddressEnv        string `yaml:"address_env"`
	DialTimeoutSecs   int    `yaml:"dial_timeout_seconds"`
	CallTimeoutSecs   int    `yaml:"call_timeout_seconds"`
	InsecureTransport bool   `yaml:"insecure"`
}

func (c clientConfig) resolveAddress() string {
	if address := strings.TrimSpace(c.Address); address != "" {
		return address
	}
	if env := strings.TrimSpace(c.AddressEnv); env != "" {
		return strings.TrimSpace(os.Getenv(env))
	}
	return ""
}

func (c clientConfig) dialTimeout() time.Duration {
	if c.DialTimeoutSecs <= 0 {
		return 5 * time.Second
	}
	return time.Duration(c.DialTimeoutSecs) * time.Second
}

func (c clientConfig) callTimeout() time.Duration {
	if c.CallTimeoutSecs <= 0 {
		return 3 * time.Second
	}
	return time.Duration(c.CallTimeoutSecs) * time.Second
}

func (c *config) quoteRetention() time.Duration {
	if c == nil || c.QuoteRetentionHrs <= 0 {
		return 72 * time.Hour
	}
	return time.Duration(c.QuoteRetentionHrs) * time.Hour
}

func (i *Imp) loadConfig() (*config, error) {
	data, err := os.ReadFile(i.file)
	if err != nil {
		i.logger.Error("Could not read configuration file", zap.String("config_file", i.file), zap.Error(err))
		return nil, err
	}

	cfg := &config{Config: &grpcapp.Config{}}
	if err := yaml.Unmarshal(data, cfg); err != nil {
		i.logger.Error("Failed to parse configuration", zap.Error(err))
		return nil, err
	}

	if cfg.Runtime == nil {
		cfg.Runtime = &grpcapp.RuntimeConfig{ShutdownTimeoutSeconds: 15}
	}

	if cfg.GRPC == nil {
		cfg.GRPC = &routers.GRPCConfig{
			Network:          "tcp",
			Address:          ":50064",
			EnableReflection: true,
			EnableHealth:     true,
		}
	} else {
		if strings.TrimSpace(cfg.GRPC.Address) == "" {
			cfg.GRPC.Address = ":50064"
		}
		if strings.TrimSpace(cfg.GRPC.Network) == "" {
			cfg.GRPC.Network = "tcp"
		}
	}

	if cfg.Metrics == nil {
		cfg.Metrics = &grpcapp.MetricsConfig{Address: ":9414"}
	} else if strings.TrimSpace(cfg.Metrics.Address) == "" {
		cfg.Metrics.Address = ":9414"
	}

	return cfg, nil
}
