package gateway

import (
	"context"

	gatewayoutbox "github.com/tech/sendico/gateway/common/outbox"
	"github.com/tech/sendico/pkg/db/transaction"
	me "github.com/tech/sendico/pkg/messaging/envelope"
)

type outboxProvider interface {
	Outbox() gatewayoutbox.Store
}

type transactionProvider interface {
	TransactionFactory() transaction.Factory
}

func (p *cardPayoutProcessor) outboxStore() gatewayoutbox.Store {
	provider, ok := p.store.(outboxProvider)
	if !ok || provider == nil {
		return nil
	}
	return provider.Outbox()
}

func (p *cardPayoutProcessor) startOutboxReliableProducer() error {
	if p == nil || p.outbox == nil {
		return nil
	}
	return p.outbox.Start(p.logger, p.producer, p.outboxStore(), p.msgCfg)
}

func (p *cardPayoutProcessor) sendWithOutbox(ctx context.Context, env me.Envelope) error {
	if err := p.startOutboxReliableProducer(); err != nil {
		return err
	}
	if p.outbox == nil {
		return nil
	}
	return p.outbox.Send(ctx, env)
}

func (p *cardPayoutProcessor) executeTransaction(ctx context.Context, cb transaction.Callback) (any, error) {
	provider, ok := p.store.(transactionProvider)
	if !ok || provider == nil || provider.TransactionFactory() == nil {
		return cb(ctx)
	}
	return provider.TransactionFactory().CreateTransaction().Execute(ctx, cb)
}
