package qsnap

import (
	"context"
	"time"

	"github.com/tech/sendico/payments/storage/model"
	"github.com/tech/sendico/pkg/mlogger"
	"go.mongodb.org/mongo-driver/v2/bson"
	"go.uber.org/zap"
)

// Store is the minimal quote store contract required by the resolver.
type Store interface {
	GetByRef(ctx context.Context, orgRef bson.ObjectID, quoteRef string) (*model.PaymentQuoteRecord, error)
}

// Resolver resolves a quotation reference into canonical execution snapshots.
type Resolver interface {
	Resolve(ctx context.Context, store Store, in Input) (*Output, error)
	ResolveAll(ctx context.Context, store Store, in ResolveAllInput) (*ResolveAllOutput, error)
}

// Input defines lookup scope for quotation resolution.
type Input struct {
	OrganizationID bson.ObjectID
	QuotationRef   string
}

// Output contains extracted canonical snapshots for execution.
type Output struct {
	QuotationRef   string
	IntentSnapshot model.PaymentIntent
	QuoteSnapshot  *model.PaymentQuoteSnapshot
}

// ResolveAllInput defines lookup scope for resolving all items in a batch quotation.
type ResolveAllInput struct {
	OrganizationRef bson.ObjectID
	QuotationRef    string
}

// ResolveAllOutput contains all resolved items from a batch quotation.
type ResolveAllOutput struct {
	QuotationRef string
	Items        []ResolvedItem
}

// ResolvedItem is one resolved intent-quote pair from a batch quotation.
type ResolvedItem struct {
	IntentRef      string
	IntentSnapshot model.PaymentIntent
	QuoteSnapshot  *model.PaymentQuoteSnapshot
}

// Dependencies configures quote resolver integrations.
type Dependencies struct {
	Logger mlogger.Logger
	Now    func() time.Time
}

func New(deps ...Dependencies) Resolver {
	var dep Dependencies
	if len(deps) > 0 {
		dep = deps[0]
	}
	logger := dep.Logger
	if logger == nil {
		logger = zap.NewNop()
	}
	now := dep.Now
	if now == nil {
		now = time.Now
	}
	return &svc{
		logger: logger.Named("quote_resolver"),
		now:    now,
	}
}
