import pytest

from flyway.domain.errors import BusinessError
from flyway.domain.units import merge_quantity, parse_units, pick_unit_for_remaining, validate_units


def test_parse_units():
    assert parse_units("1, 6,12") == [1, 6, 12]
    assert parse_units(None) == []
    with pytest.raises(BusinessError):
        parse_units("6,x")


def test_units_must_be_multiples_of_smallest():
    validate_units(6, "12,24")
    with pytest.raises(BusinessError) as e:
        validate_units(6, "10")
    assert e.value.field == "available_unit"


def test_merge_quantity_uses_smaller_unit():
    assert merge_quantity(2, 6, 3, 1) == (15, 1)


@pytest.mark.parametrize(
    "remaining,default,available,expected",
    [
        (24, 6, [6, 12], (4, 6, 0)),     # 能被默认单位整除
        (36, 10, [6, 12], (3, 12, 0)),   # 否则用能整除的最大可用单位
        (25, 10, [6, 12], (4, 6, 1)),    # 都不能整除：第一个不大于剩余的可用单位，余数 1 被遗漏（旧行为）
        (5, 10, [6, 12], None),          # 没有可用单位
        (0, 1, [], None),
    ],
)
def test_pick_unit_for_remaining(remaining, default, available, expected):
    assert pick_unit_for_remaining(remaining, default, available) == expected


def test_merge_quantity_never_loses_stock():
    # 1×6 + 1×4 = 10：较小单位 4 除不尽，改用 2（两单位的最大公约数）
    assert merge_quantity(1, 6, 1, 4) == (5, 2)
