package quote_computation_service

import (
	"context"
	"testing"

	"github.com/tech/sendico/payments/storage/model"
	paymenttypes "github.com/tech/sendico/pkg/payments/types"
)

func TestInferEndpointCurrencies_UsesEndpointAssets(t *testing.T) {
	svc := New(nil)
	out, err := svc.inferEndpointCurrencies(context.Background(), "org-1", model.PaymentIntent{
		Source: model.PaymentEndpoint{
			Type: model.EndpointTypeManagedWallet,
			ManagedWallet: &model.ManagedWalletEndpoint{
				ManagedWalletRef: "mw-src",
				Asset:            &paymenttypes.Asset{TokenSymbol: "USDT"},
			},
		},
		Destination: model.PaymentEndpoint{
			Type: model.EndpointTypeExternalChain,
			ExternalChain: &model.ExternalChainEndpoint{
				Asset: &paymenttypes.Asset{TokenSymbol: "RUB"},
			},
		},
	}, map[string]string{})
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if got, want := out.SourceCurrency, "USDT"; got != want {
		t.Fatalf("unexpected source currency: got=%q want=%q", got, want)
	}
	if got, want := out.DestinationCurrency, "RUB"; got != want {
		t.Fatalf("unexpected destination currency: got=%q want=%q", got, want)
	}
	if !out.SourceInferred || !out.DestinationInferred {
		t.Fatalf("expected both currencies inferred: %#v", out)
	}
}

func TestInferEndpointCurrencies_UsesLedgerResolver(t *testing.T) {
	resolver := &fakeLedgerCurrencyResolver{
		currencies: map[string]string{
			"ledger-src": "USDT",
			"ledger-dst": "RUB",
		},
	}
	svc := New(nil, WithLedgerAccountCurrencyResolver(resolver))
	out, err := svc.inferEndpointCurrencies(context.Background(), "org-1", model.PaymentIntent{
		Source: model.PaymentEndpoint{
			Type: model.EndpointTypeLedger,
			Ledger: &model.LedgerEndpoint{
				LedgerAccountRef: "ledger-src",
			},
		},
		Destination: model.PaymentEndpoint{
			Type: model.EndpointTypeLedger,
			Ledger: &model.LedgerEndpoint{
				LedgerAccountRef: "ledger-dst",
			},
		},
	}, map[string]string{})
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if got, want := out.SourceCurrency, "USDT"; got != want {
		t.Fatalf("unexpected source currency: got=%q want=%q", got, want)
	}
	if got, want := out.DestinationCurrency, "RUB"; got != want {
		t.Fatalf("unexpected destination currency: got=%q want=%q", got, want)
	}
	if resolver.calls != 2 {
		t.Fatalf("unexpected resolver calls: got=%d want=%d", resolver.calls, 2)
	}
}

type fakeLedgerCurrencyResolver struct {
	currencies map[string]string
	calls      int
}

func (f *fakeLedgerCurrencyResolver) ResolveLedgerAccountCurrency(_ context.Context, _ string, ledgerAccountRef string) (string, error) {
	f.calls++
	return f.currencies[ledgerAccountRef], nil
}
