"""The answer shapes: the union discriminates on `kind`, a scalar's `number`
is derived from its printed `value`, and 'not present' stays distinguishable
from zero without reading English."""

from decimal import Decimal

from quber.playground.answers.shapes import Answer, Point, Scalar, Unanswerable


def test_union_discriminates_on_kind():
    a = Answer.model_validate({"payload": {"kind": "scalar", "value": "$14.47"}})
    assert isinstance(a.payload, Scalar)
    b = Answer.model_validate({"payload": {"kind": "unanswerable", "reason": "not printed"}})
    assert isinstance(b.payload, Unanswerable)
    c = Answer.model_validate({"payload": {"kind": "prose", "text": "because"}})
    assert c.payload.kind == "prose"


def test_scalar_number_follows_value():
    s = Scalar(value="$ (10,550)")
    assert s.number == Decimal("-10550")
    assert Scalar(value="6.7 %").number == Decimal("6.7")
    assert Scalar(value="n/a").number is None


def test_number_serializes_with_the_model():
    dumped = Scalar(value="65%").model_dump(mode="json")
    assert dumped["number"] == "65"


def test_point_number_reads_like_a_scalar():
    assert Point(label="Q1", value="(0.06)").number == Decimal("-0.06")


def test_unanswerable_is_not_a_zero_scalar():
    zero = Answer.model_validate({"payload": {"kind": "scalar", "value": "0"}})
    absent = Answer.model_validate({"payload": {"kind": "unanswerable", "reason": "absent"}})
    assert zero.payload.kind == "scalar" and zero.payload.number == 0
    assert absent.payload.kind == "unanswerable"
    assert not hasattr(absent.payload, "number")
