package quotation

import (
	ledgerclient "github.com/tech/sendico/ledger/client"
	"github.com/tech/sendico/payments/storage"
	clockpkg "github.com/tech/sendico/pkg/clock"
	"github.com/tech/sendico/pkg/mlogger"
	"go.uber.org/zap"
)

type serviceError string

func (e serviceError) Error() string {
	return string(e)
}

const (
	defaultFeeQuoteTTLMillis int64 = 600000
	defaultOracleTTLMillis   int64 = 600000
)

var (
	errStorageUnavailable = serviceError("payments.quotation: storage not initialised")
)

// Service hosts quotation-v2 runtime dependencies.
type Service struct {
	logger  mlogger.Logger
	storage storage.Repository
	clock   clockpkg.Clock

	deps serviceDependencies
}

type serviceDependencies struct {
	fees                  feesDependency
	gateway               gatewayDependency
	oracle                oracleDependency
	ledger                ledgerclient.Client
	gatewayRegistry       GatewayRegistry
	gatewayInvokeResolver GatewayInvokeResolver
	cardRoutes            map[string]CardGatewayRoute
	feeLedgerAccounts     map[string]string
}

// NewService constructs the quotation service core.
func NewService(logger mlogger.Logger, repo storage.Repository, opts ...Option) *Service {
	if logger == nil {
		logger = zap.NewNop()
	}

	svc := &Service{
		logger:  logger.Named("service"),
		storage: repo,
		clock:   clockpkg.NewSystem(),
	}

	for _, opt := range opts {
		if opt != nil {
			opt(svc)
		}
	}

	if svc.clock == nil {
		svc.clock = clockpkg.NewSystem()
	}
	return svc
}

// Shutdown releases runtime resources. Quotation v2 has no background workers.
func (s *Service) Shutdown() {}
