package domain

import (
	"math/big"
	"testing"
)

func TestRoundRationalMinorUnitsModes(t *testing.T) {
	t.Parallel()

	policy := DefaultRoundingPolicy("EUR")
	policy.CashRoundingIncrementMinorUnits = 1

	policy.Mode = RoundingModeFloor
	got, err := RoundRationalMinorUnits(big.NewInt(125), big.NewInt(10), policy)
	if err != nil {
		t.Fatalf("floor rounding failed: %v", err)
	}
	if got != 12 {
		t.Fatalf("floor rounding = %d, want 12", got)
	}

	policy.Mode = RoundingModeHalfUp
	got, err = RoundRationalMinorUnits(big.NewInt(125), big.NewInt(10), policy)
	if err != nil {
		t.Fatalf("half-up rounding failed: %v", err)
	}
	if got != 13 {
		t.Fatalf("half-up rounding = %d, want 13", got)
	}

	policy.Mode = RoundingModeHalfEven
	got, err = RoundRationalMinorUnits(big.NewInt(125), big.NewInt(10), policy)
	if err != nil {
		t.Fatalf("half-even rounding failed: %v", err)
	}
	if got != 12 {
		t.Fatalf("half-even rounding = %d, want 12", got)
	}
}

func TestConvertMinorUnitsHandlesMinorUnitDifferences(t *testing.T) {
	t.Parallel()

	from := DefaultRoundingPolicy("EUR")
	to := DefaultRoundingPolicy("JPY")

	got, err := ConvertMinorUnits(10_000, 163_500_000, from, to)
	if err != nil {
		t.Fatalf("EUR->JPY conversion failed: %v", err)
	}
	if got != 16_350 {
		t.Fatalf("EUR->JPY conversion = %d, want 16350", got)
	}

	from = DefaultRoundingPolicy("JPY")
	to = DefaultRoundingPolicy("EUR")
	got, err = ConvertMinorUnits(16_350, 6_116, from, to)
	if err != nil {
		t.Fatalf("JPY->EUR conversion failed: %v", err)
	}
	if got != 10_000 {
		t.Fatalf("JPY->EUR conversion = %d, want 10000", got)
	}
}

func TestConvertMinorUnitsCashIncrement(t *testing.T) {
	t.Parallel()

	from := DefaultRoundingPolicy("EUR")
	to := DefaultRoundingPolicy("CHF")
	to.CashRoundingIncrementMinorUnits = 5

	got, err := ConvertMinorUnits(100, 1_023_000, from, to)
	if err != nil {
		t.Fatalf("cash increment conversion failed: %v", err)
	}
	if got != 100 {
		t.Fatalf("cash increment conversion = %d, want 100", got)
	}
}
