package idem

import (
	"context"

	"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 payment store contract required for idempotency handling.
type Store interface {
	Create(ctx context.Context, payment *model.Payment) error
	GetByIdempotencyKey(ctx context.Context, orgRef bson.ObjectID, idempotencyKey string) (*model.Payment, error)
}

// Service handles execute-payment idempotency concerns for v2 orchestrator flow.
type Service interface {
	Fingerprint(in FPInput) (string, error)
	TryReuse(ctx context.Context, store Store, in ReuseInput) (*model.Payment, bool, error)
	CreateOrReuse(ctx context.Context, store Store, in CreateInput) (*model.Payment, bool, error)
}

// FPInput is the business payload used for idempotency fingerprinting.
type FPInput struct {
	OrganizationRef  string
	QuotationRef     string
	IntentRef        string
	ClientPaymentRef string
}

// ReuseInput defines lookup and comparison inputs for idempotency reuse checks.
type ReuseInput struct {
	OrganizationRef bson.ObjectID
	IdempotencyKey  string
	Fingerprint     string
}

// CreateInput wraps create operation with reuse-check context for duplicate races.
type CreateInput struct {
	Payment *model.Payment
	Reuse   ReuseInput
}

// Dependencies configures idempotency service integrations.
type Dependencies struct {
	Logger mlogger.Logger
}

func New(deps ...Dependencies) Service {
	var dep Dependencies
	if len(deps) > 0 {
		dep = deps[0]
	}
	logger := dep.Logger
	if logger == nil {
		logger = zap.NewNop()
	}
	return &svc{logger: logger.Named("idempotency")}
}
