"""Tests for PandasAdapter (guarded by pandas availability)."""
import pytest

pd = pytest.importorskip("pandas")

from kanoniv.adapters.pandas import PandasAdapter
from kanoniv.source import Source


class TestPandasAdapter:
    def test_schema_type_inference(self):
        df = pd.DataFrame(
            {
                "id": [1, 2, 3],
                "name": ["Alice", "Bob", "Charlie"],
                "score": [9.5, 8.0, 7.2],
                "active": [True, False, True],
            }
        )
        adapter = PandasAdapter(df)
        schema = adapter.schema()
        col_map = {c.name: c for c in schema.columns}
        assert col_map["id"].dtype == "number"
        assert col_map["name"].dtype == "string"
        assert col_map["score"].dtype == "number"
        assert col_map["active"].dtype == "boolean"

    def test_schema_datetime_inference(self):
        df = pd.DataFrame(
            {
                "created_at": pd.to_datetime(["2024-01-01", "2024-02-01"]),
            }
        )
        adapter = PandasAdapter(df)
        schema = adapter.schema()
        assert schema.columns[0].dtype == "date"

    def test_nan_handling(self):
        df = pd.DataFrame(
            {
                "name": ["Alice", None, "Charlie"],
                "score": [1.0, float("nan"), 3.0],
            }
        )
        adapter = PandasAdapter(df)
        rows = list(adapter.iter_rows())
        assert rows[1]["name"] == ""
        assert rows[1]["score"] == ""

    def test_iter_rows_matches_dataframe(self):
        df = pd.DataFrame(
            {
                "id": [10, 20],
                "name": ["X", "Y"],
            }
        )
        adapter = PandasAdapter(df)
        rows = list(adapter.iter_rows())
        assert len(rows) == 2
        assert rows[0]["id"] == "10"
        assert rows[1]["name"] == "Y"

    def test_row_count(self):
        df = pd.DataFrame({"a": range(50)})
        adapter = PandasAdapter(df)
        assert adapter.row_count() == 50

    def test_source_from_pandas(self):
        df = pd.DataFrame(
            {"id": [1, 2], "email": ["a@b.com", "c@d.com"]}
        )
        src = Source.from_pandas("test", df, primary_key="id")
        entities = src.to_entities("customer")
        assert len(entities) == 2
        assert entities[0]["data"]["email"] == "a@b.com"

    def test_invalid_input_raises(self):
        with pytest.raises(TypeError, match="DataFrame"):
            PandasAdapter({"not": "a dataframe"})

    def test_nullable_detection(self):
        df = pd.DataFrame(
            {
                "a": [1, 2, 3],
                "b": [1, None, 3],
            }
        )
        adapter = PandasAdapter(df)
        schema = adapter.schema()
        col_map = {c.name: c for c in schema.columns}
        assert col_map["a"].nullable is False
        assert col_map["b"].nullable is True
