"""Tests for spatial filtering methods."""

import pytest
from shapely.geometry import Point, Polygon
from walkingpandas import WalkFrame


def test_passing_through(sample_walkframe):
    """Test passing_through filter (integer node ID)."""
    filtered = sample_walkframe.passing_through(0)
    result = filtered.compute()
    assert all(result['node_id'] == 0)


def test_passing_through_multiple(sample_walkframe):
    """Test passing_through with multiple nodes."""
    filtered = sample_walkframe.passing_through([0, 1])
    result = filtered.compute()
    assert all(result['node_id'].isin([0, 1]))


def test_within_bounds(sample_walkframe):
    """Test within_bounds filter."""
    bbox = (-0.5, -0.5, 1.5, 1.5)
    filtered = sample_walkframe.within_bounds(bbox)
    result = filtered.compute()
    assert isinstance(result, type(filtered.compute()))


def test_intersecting(sample_walkframe):
    """Test intersecting filter."""
    poly = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])
    filtered = sample_walkframe.intersecting(poly)
    result = filtered.compute()
    assert isinstance(result, type(filtered.compute()))


def test_near_point(sample_walkframe):
    """Test near_point filter (buffer around point)."""
    pt = Point(0.5, 0.5)
    filtered = sample_walkframe.near_point(pt, distance=2.0)
    result = filtered.compute()
    assert isinstance(result, type(sample_walkframe.compute()))


def test_within_bounds_empty_result(sample_walkframe):
    """Test within_bounds with bbox that contains no nodes returns empty."""
    bbox = (100, 100, 101, 101)
    filtered = sample_walkframe.within_bounds(bbox)
    result = filtered.compute()
    assert len(result) == 0


def test_passing_through_with_string_mapping():
    """Test passing_through resolves string IDs through network mapping."""
    import pandas as pd
    from walkingpandas import Network, WalkFrame

    network = Network()
    network.add_nodes(pd.DataFrame({"node_id": ["A", "B", "C"]}))
    network.add_edges(pd.DataFrame({
        "source_node": ["A", "B"],
        "target_node": ["B", "C"],
    }))

    walks_df = pd.DataFrame({
        "walk_id": ["w1", "w1", "w1"],
        "sequence_idx": [0, 1, 2],
        "node_id": ["A", "B", "C"],
    })
    wf = WalkFrame.from_dataframe(walks_df, network=network)
    filtered = wf.passing_through("B").compute(decode=True)
    assert len(filtered) > 0
    assert "B" in filtered["node_id"].values


def test_intersecting_no_matches(sample_walkframe):
    """Test intersecting with geometry far from any data returns empty."""
    poly = Polygon([(100, 100), (101, 100), (101, 101), (100, 101)])
    filtered = sample_walkframe.intersecting(poly)
    result = filtered.compute()
    assert len(result) == 0
