"""Tests for join, schema validation, and auto-version helpers."""

from soigia.datatable import DataTable


def test_join_helpers_work():
    left = DataTable({"id": [1, 2, 3], "name": ["alice", "bob", "carol"]})
    right = DataTable({"id": [1, 2, 4], "city": ["hn", "sg", "dn"]})

    inner = left.inner_join(right, on="id")
    left_join = left.left_join(right, on="id")
    anti = left.anti_join(right, on="id")
    qs_join = left.objects.inner_join(right, on="id").to_df()

    assert list(inner["id"]) == [1, 2]
    assert list(inner["city"]) == ["hn", "sg"]
    assert list(left_join["id"]) == [1, 2, 3]
    assert list(anti["id"]) == [3]
    assert list(qs_join["name"]) == ["alice", "bob"]


def test_schema_helpers_work():
    table = DataTable({"name": ["alice"], "age": ["19"], "email": ["alice@example.com"]})

    ensured = table.ensure_columns("city", "country", fill_value="VN")
    coerced = table.coerce_types({"age": "int64"})
    validated = coerced.validate_schema(
        {
            "name": {"type": str, "nullable": False},
            "age": {"type": int, "min": 18, "max": 65, "nullable": False},
            "email": {"regex": r"@"},
            "city": {"required": False},
        }
    )

    assert list(ensured.columns) == ["name", "age", "email", "city", "country"]
    assert ensured["city"].iloc[0] == "VN"
    assert coerced["age"].dtype.kind in {"i", "u"}
    assert validated is coerced


def test_schema_validation_fails_for_bad_data():
    table = DataTable({"name": ["alice"], "age": [17]})

    try:
        table.validate_schema({"age": {"type": int, "min": 18}})
    except ValueError as exc:
        assert "minimum" in str(exc)
    else:  # pragma: no cover - defensive
        raise AssertionError("Expected schema validation to fail")


def test_auto_version_tracks_helper_transforms():
    table = DataTable({"name": ["alice"], "age": [19]})
    table.init_versions("initial")
    table.auto_version("auto")

    updated = table.fill_missing(0)
    ensured = updated.ensure_columns("city", fill_value="vn")

    assert table.is_auto_versioning() is True
    assert updated.version_count() == 2
    assert ensured.version_count() == 3
    assert updated.current_version()["label"] == "auto"
    assert ensured.current_version()["label"] == "auto"
    assert isinstance(ensured, DataTable)


def test_objects_delegate_new_helpers():
    table = DataTable({"id": [1, 2], "name": ["alice", "bob"], "age": ["19", "24"]})

    qs = table.objects.ensure_columns("city", fill_value="hn").coerce_types({"age": "int64"})
    materialized = qs.to_df()

    assert list(materialized["city"]) == ["hn", "hn"]
    assert materialized["age"].dtype.kind in {"i", "u"}
