package trading

import (
	"testing"
	"time"

	"git.toki-labs.com/toki/alt/packages/domain/market"
)

func TestBrokerCapabilitySupportsVenueAndOrderType(t *testing.T) {
	now := time.Now()
	cap := BrokerCapability{
		Broker:         BrokerKIS,
		Markets:        map[market.Market]bool{market.MarketKR: true, market.MarketUS: true},
		Venues:         map[market.Venue]bool{market.VenueKRX: true},
		OrderTypes:     []OrderType{OrderTypeMarket, OrderTypeLimit},
		SupportsCancel: true,
		CheckedAt:      now,
	}

	if !cap.HasMarket(market.MarketKR) {
		t.Fatal("expected capability to include KR market")
	}
	if cap.HasMarket(market.Market("JP")) {
		t.Fatal("expected capability to not include JP market")
	}

	if !cap.HasVenue(market.VenueKRX) {
		t.Fatal("expected capability to include KRX venue")
	}
	if cap.HasVenue(market.VenueNASDAQ) {
		t.Fatal("expected capability to not include NASDAQ venue")
	}

	if !cap.HasOrderType(OrderTypeMarket) {
		t.Fatal("expected capability to include market order type")
	}
	if cap.HasOrderType(OrderType("iceberg")) {
		t.Fatal("expected capability to not include iceberg order type")
	}

	if !cap.SupportsCancel {
		t.Fatal("expected capability to support cancel")
	}
	if cap.CheckedAt != now {
		t.Fatal("expected CheckedAt to match")
	}
}

func TestLiveOrderIntentKeepsCustomBrokerOrderType(t *testing.T) {
	intent := OrderIntent{
		InstrumentID: "005930.KS",
		Side:         OrderSideBuy,
		Quantity:     market.Quantity{}, // zero is fine for this test
		Type:         OrderType("kis_best_limit"),
	}

	if got := intent.OrderType(); got != OrderType("kis_best_limit") {
		t.Fatalf("expected custom order type 'kis_best_limit', got %q", got)
	}

	// Empty type defaults to market.
	intentEmpty := OrderIntent{}
	if got := intentEmpty.OrderType(); got != OrderTypeMarket {
		t.Fatalf("expected empty type to default to market, got %q", got)
	}
}

func TestAccountSnapshotRequiresNoFloatMath(t *testing.T) {
	// Verify that AccountSnapshot uses market.Decimal for all monetary
	// fields and contains no float fields. This is a compile-time +
	// structural check: if a field were float64, the struct layout would
	// differ, but the real guarantee is in the type itself.
	snap := AccountSnapshot{
		Broker:           BrokerKIS,
		AccountID:        "test",
		Cash:             market.Decimal{},
		TotalEquity:      market.Decimal{},
		Available_margin: market.Decimal{},
		SnapshotTime:     time.Now(),
	}
	// Compile-time assurance: these fields must be market.Decimal.
	_ = snap.Cash
	_ = snap.TotalEquity
	_ = snap.Available_margin

	// Similarly, PositionSnapshot.PnL uses market.Decimal.
	pos := PositionSnapshot{
		InstrumentID: "005930.KS",
		Side:         OrderSideBuy,
		MarketValue:  market.Decimal{},
		PnL:          market.Decimal{},
		AvgPrice:     market.Price{},
		CurrentPrice: market.Price{},
	}
	_ = pos.PnL
	_ = pos.MarketValue
	_ = pos.CurrentPrice
	_ = pos.AvgPrice
}
