package serverimp

import (
	"strings"

	"github.com/tech/sendico/payments/orchestrator/internal/service/orchestrationv2/psvc"
	"github.com/tech/sendico/payments/orchestrator/internal/service/orchestrator"
	"github.com/tech/sendico/payments/storage/model"
	"github.com/tech/sendico/pkg/discovery"
	"github.com/tech/sendico/pkg/mlogger"
)

func buildCardGatewayRoutes(src map[string]cardGatewayRouteConfig) map[string]orchestrator.CardGatewayRoute {
	if len(src) == 0 {
		return nil
	}
	result := make(map[string]orchestrator.CardGatewayRoute, len(src))
	for key, route := range src {
		trimmedKey := strings.TrimSpace(key)
		if trimmedKey == "" {
			continue
		}
		result[trimmedKey] = orchestrator.CardGatewayRoute{
			FundingAddress: strings.TrimSpace(route.FundingAddress),
			FeeAddress:     strings.TrimSpace(route.FeeAddress),
			FeeWalletRef:   strings.TrimSpace(route.FeeWalletRef),
		}
	}
	return result
}

func buildGatewayRegistry(logger mlogger.Logger, src []gatewayInstanceConfig, registry *discovery.Registry) orchestrator.GatewayRegistry {
	if logger != nil {
		logger = logger.Named("gateway_registry")
	}
	if len(src) > 0 && logger != nil {
		logger.Warn("Static gateway configuration ignored; using discovery registry only")
	}
	if registry == nil {
		if logger != nil {
			logger.Warn("Discovery registry unavailable; gateway routing disabled")
		}
		return nil
	}
	return orchestrator.NewDiscoveryGatewayRegistry(logger, registry)
}

func buildBatchOptimizationPolicy(cfg optimizerConfig) psvc.BatchOptimizationPolicy {
	rules := make([]psvc.BatchOptimizationRule, 0, len(cfg.Aggregation.Rules))
	for i := range cfg.Aggregation.Rules {
		ruleCfg := cfg.Aggregation.Rules[i]
		rule := psvc.BatchOptimizationRule{
			ID:       strings.TrimSpace(ruleCfg.ID),
			Enabled:  ruleCfg.Enabled,
			Priority: ruleCfg.Priority,
			Mode:     psvc.BatchOptimizationMode(strings.TrimSpace(ruleCfg.Mode)),
			GroupBy:  psvc.BatchOptimizationGrouping(strings.TrimSpace(ruleCfg.GroupBy)),
			Match: psvc.BatchOptimizationMatch{
				Rail:       model.ParseRail(ruleCfg.Match.Rail),
				Providers:  cloneTrimmedSlice(ruleCfg.Match.Providers),
				Networks:   cloneTrimmedSlice(ruleCfg.Match.Networks),
				Currencies: cloneTrimmedSlice(ruleCfg.Match.Currencies),
			},
		}
		if ruleCfg.Match.Amount != nil {
			rule.Match.Amount = &psvc.BatchOptimizationAmountRange{
				Min:      strings.TrimSpace(ruleCfg.Match.Amount.Min),
				Max:      strings.TrimSpace(ruleCfg.Match.Amount.Max),
				Currency: strings.TrimSpace(ruleCfg.Match.Amount.Currency),
			}
		}
		rules = append(rules, rule)
	}
	return psvc.BatchOptimizationPolicy{
		DefaultMode: psvc.BatchOptimizationMode(strings.TrimSpace(cfg.Aggregation.DefaultMode)),
		Rules:       rules,
	}
}

func cloneTrimmedSlice(values []string) []string {
	if len(values) == 0 {
		return nil
	}
	out := make([]string, 0, len(values))
	for i := range values {
		token := strings.TrimSpace(values[i])
		if token == "" {
			continue
		}
		out = append(out, token)
	}
	if len(out) == 0 {
		return nil
	}
	return out
}
