package quote_computation_service

import (
	"context"
	"strings"

	"github.com/tech/sendico/payments/storage/model"
)

type endpointCurrencyInference struct {
	SourceCurrency      string
	DestinationCurrency string
	SourceInferred      bool
	DestinationInferred bool
}

func (s *QuoteComputationService) inferEndpointCurrencies(
	ctx context.Context,
	organizationRef string,
	intent model.PaymentIntent,
	ledgerCurrencyCache map[string]string,
) (endpointCurrencyInference, error) {
	sourceCurrency, sourceInferred, err := s.inferEndpointCurrency(
		ctx,
		organizationRef,
		intent.Source,
		ledgerCurrencyCache,
	)
	if err != nil {
		return endpointCurrencyInference{}, err
	}
	destinationCurrency, destinationInferred, err := s.inferEndpointCurrency(
		ctx,
		organizationRef,
		intent.Destination,
		ledgerCurrencyCache,
	)
	if err != nil {
		return endpointCurrencyInference{}, err
	}
	return endpointCurrencyInference{
		SourceCurrency:      sourceCurrency,
		DestinationCurrency: destinationCurrency,
		SourceInferred:      sourceInferred,
		DestinationInferred: destinationInferred,
	}, nil
}

func (s *QuoteComputationService) inferEndpointCurrency(
	ctx context.Context,
	organizationRef string,
	endpoint model.PaymentEndpoint,
	ledgerCurrencyCache map[string]string,
) (string, bool, error) {
	if token := sourceAssetToken(endpoint); token != "" {
		return token, true, nil
	}
	if endpoint.Ledger == nil {
		return "", false, nil
	}
	ledgerAccountRef := strings.TrimSpace(endpoint.Ledger.LedgerAccountRef)
	if ledgerAccountRef == "" {
		return "", false, nil
	}
	if cached := normalizeAsset(ledgerCurrencyCache[ledgerAccountRef]); cached != "" {
		return cached, true, nil
	}
	if s == nil || s.ledgerAccountCurrencyResolver == nil {
		return "", false, nil
	}
	currency, err := s.ledgerAccountCurrencyResolver.ResolveLedgerAccountCurrency(
		ctx,
		strings.TrimSpace(organizationRef),
		ledgerAccountRef,
	)
	if err != nil {
		return "", false, err
	}
	currency = normalizeAsset(currency)
	if currency == "" {
		return "", false, nil
	}
	if ledgerCurrencyCache != nil {
		ledgerCurrencyCache[ledgerAccountRef] = currency
	}
	return currency, true, nil
}
