package gateway

import (
	"net/http"
	"strings"

	"github.com/tech/sendico/gateway/mntx/internal/service/monetix"
	"github.com/tech/sendico/gateway/mntx/storage"
	"github.com/tech/sendico/pkg/clock"
	msg "github.com/tech/sendico/pkg/messaging"
	pmodel "github.com/tech/sendico/pkg/model"
	gatewayv1 "github.com/tech/sendico/pkg/proto/common/gateway/v1"
)

// Option configures optional service dependencies.
type Option func(*Service)

// WithClock injects a custom clock (useful for tests).
func WithClock(c clock.Clock) Option {
	return func(s *Service) {
		if c != nil {
			s.clock = c
		}
	}
}

// WithProducer attaches a messaging producer to the service.
func WithProducer(p msg.Producer) Option {
	return func(s *Service) {
		s.producer = p
	}
}

func WithStorage(storage storage.Repository) Option {
	return func(s *Service) {
		s.storage = storage
	}
}

// WithHTTPClient injects a custom HTTP client (useful for tests).
func WithHTTPClient(client *http.Client) Option {
	return func(s *Service) {
		if client != nil {
			s.httpClient = client
		}
	}
}

// WithMonetixConfig sets the Monetix connectivity options.
func WithMonetixConfig(cfg monetix.Config) Option {
	return func(s *Service) {
		s.config = cfg
	}
}

// WithGatewayDescriptor sets the self-declared gateway instance descriptor.
func WithGatewayDescriptor(descriptor *gatewayv1.GatewayInstanceDescriptor) Option {
	return func(s *Service) {
		if descriptor != nil {
			s.gatewayDescriptor = descriptor
		}
	}
}

// WithDiscoveryInvokeURI sets the invoke URI used when announcing the gateway.
func WithDiscoveryInvokeURI(invokeURI string) Option {
	return func(s *Service) {
		s.invokeURI = strings.TrimSpace(invokeURI)
	}
}

// WithMessagingSettings applies messaging driver settings.
func WithMessagingSettings(settings pmodel.SettingsT) Option {
	return func(s *Service) {
		if settings != nil {
			s.msgCfg = settings
		}
	}
}

// WithStrictOperationIsolation serialises payout processing to one unresolved operation at a time.
func WithStrictOperationIsolation(enabled bool) Option {
	return func(s *Service) {
		s.strictIsolation = enabled
	}
}
