package quote_computation_service

import (
	"testing"

	"github.com/tech/sendico/payments/quotation/internal/service/quotation/transfer_intent_hydrator"
	"github.com/tech/sendico/payments/storage/model"
	paymenttypes "github.com/tech/sendico/pkg/payments/types"
)

func TestEnsureDerivedFXIntent_DefaultsSideWhenEmpty(t *testing.T) {
	intent := &model.PaymentIntent{
		RequiresFX:         true,
		SettlementCurrency: "RUB",
		Amount:             &paymenttypes.Money{Amount: "100", Currency: "USDT"},
		FX:                 &model.FXIntent{},
	}

	ensureDerivedFXIntent(intent, "", "")

	if intent.FX == nil {
		t.Fatal("expected fx intent")
	}
	if got, want := intent.FX.Side, paymenttypes.FXSideSellBaseBuyQuote; got != want {
		t.Fatalf("unexpected side: got=%q want=%q", got, want)
	}
}

func TestEnsureDerivedFXIntent_DefaultsSideWhenUnspecified(t *testing.T) {
	intent := &model.PaymentIntent{
		RequiresFX:         true,
		SettlementCurrency: "RUB",
		Amount:             &paymenttypes.Money{Amount: "100", Currency: "USDT"},
		FX:                 &model.FXIntent{Side: paymenttypes.FXSideUnspecified},
	}

	ensureDerivedFXIntent(intent, "", "")

	if intent.FX == nil {
		t.Fatal("expected fx intent")
	}
	if got, want := intent.FX.Side, paymenttypes.FXSideSellBaseBuyQuote; got != want {
		t.Fatalf("unexpected side: got=%q want=%q", got, want)
	}
}

func TestEnsureDerivedFXIntent_PreservesExplicitSideFromHydratedIntent(t *testing.T) {
	hydrated := &transfer_intent_hydrator.QuoteIntent{
		Source: transfer_intent_hydrator.QuoteEndpoint{
			Type: transfer_intent_hydrator.QuoteEndpointTypeManagedWallet,
			ManagedWallet: &transfer_intent_hydrator.QuoteManagedWalletEndpoint{
				ManagedWalletRef: "mw-src",
				Asset:            &paymenttypes.Asset{TokenSymbol: "USDT"},
			},
		},
		Amount:             &paymenttypes.Money{Amount: "100", Currency: "USDT"},
		SettlementCurrency: "RUB",
		RequiresFX:         true,
		FX: &transfer_intent_hydrator.QuoteFXIntent{
			Pair: &paymenttypes.CurrencyPair{
				Base:  "RUB",
				Quote: "USDT",
			},
			Side: paymenttypes.FXSideBuyBaseSellQuote,
		},
	}

	intent := modelIntentFromQuoteIntent(hydrated)
	ensureDerivedFXIntent(&intent, "", "")

	if intent.FX == nil {
		t.Fatal("expected fx intent")
	}
	if got, want := intent.FX.Side, paymenttypes.FXSideBuyBaseSellQuote; got != want {
		t.Fatalf("unexpected side: got=%q want=%q", got, want)
	}
}

func TestEnsureDerivedFXIntent_ExplicitFXOverridesInferredCurrencies(t *testing.T) {
	intent := &model.PaymentIntent{
		RequiresFX:         false,
		SettlementCurrency: "EUR",
		Amount:             &paymenttypes.Money{Amount: "10", Currency: "EUR"},
		FX: &model.FXIntent{
			Pair: &paymenttypes.CurrencyPair{
				Base:  "USDT",
				Quote: "RUB",
			},
			Side: paymenttypes.FXSideSellBaseBuyQuote,
		},
	}

	out := ensureDerivedFXIntent(intent, "BTC", "EUR")

	if !out.ExplicitOverrideApplied {
		t.Fatalf("expected explicit override flag")
	}
	if !intent.RequiresFX {
		t.Fatalf("expected requires_fx=true")
	}
	if got, want := intent.SettlementCurrency, "RUB"; got != want {
		t.Fatalf("unexpected settlement currency: got=%q want=%q", got, want)
	}
	if intent.FX == nil || intent.FX.Pair == nil {
		t.Fatalf("expected fx pair")
	}
	if got, want := intent.FX.Pair.GetBase(), "USDT"; got != want {
		t.Fatalf("unexpected base currency: got=%q want=%q", got, want)
	}
	if got, want := intent.FX.Pair.GetQuote(), "RUB"; got != want {
		t.Fatalf("unexpected quote currency: got=%q want=%q", got, want)
	}
	if got, want := out.EffectiveSourceCurrency, "USDT"; got != want {
		t.Fatalf("unexpected effective source currency: got=%q want=%q", got, want)
	}
	if got, want := out.EffectiveDestinationCurrency, "RUB"; got != want {
		t.Fatalf("unexpected effective destination currency: got=%q want=%q", got, want)
	}
}
