package orchestrator

import (
	"context"
	"sort"

	"github.com/tech/sendico/payments/orchestrator/storage/model"
	"github.com/tech/sendico/pkg/mlogger"
	"go.uber.org/zap"
)

type compositeGatewayRegistry struct {
	logger     mlogger.Logger
	registries []GatewayRegistry
}

func NewCompositeGatewayRegistry(logger mlogger.Logger, registries ...GatewayRegistry) GatewayRegistry {
	items := make([]GatewayRegistry, 0, len(registries))
	for _, registry := range registries {
		if registry != nil {
			items = append(items, registry)
		}
	}
	if len(items) == 0 {
		return nil
	}
	if logger != nil {
		logger = logger.Named("gateway_registry")
	}
	return &compositeGatewayRegistry{
		logger:     logger,
		registries: items,
	}
}

func (r *compositeGatewayRegistry) List(ctx context.Context) ([]*model.GatewayInstanceDescriptor, error) {
	if r == nil || len(r.registries) == 0 {
		return nil, nil
	}
	items := map[string]*model.GatewayInstanceDescriptor{}
	for _, registry := range r.registries {
		list, err := registry.List(ctx)
		if err != nil {
			if r.logger != nil {
				r.logger.Warn("Failed to list gateway registry", zap.Error(err))
			}
			continue
		}
		for _, entry := range list {
			if entry == nil || entry.ID == "" {
				continue
			}
			items[entry.ID] = entry
		}
	}
	result := make([]*model.GatewayInstanceDescriptor, 0, len(items))
	for _, entry := range items {
		result = append(result, entry)
	}
	sort.Slice(result, func(i, j int) bool {
		return result[i].ID < result[j].ID
	})
	return result, nil
}
