"""Tests for REMOVE clause."""

import pytest
import networkx as nx

from nxcypher import NXCypher


class TestRemoveProperty:
    """Tests for REMOVE property functionality."""

    def test_remove_single_property(self):
        """REMOVE removes a single property from a node."""
        host = nx.MultiDiGraph()
        host.add_node("Alice", name="Alice", age=30, city="NYC")

        qry = """
        MATCH (n {name: "Alice"})
        REMOVE n.age
        RETURN n.name, n.age
        """
        res = NXCypher(host).run(qry)
        assert res["n.name"] == ["Alice"]
        assert res["n.age"] == [None]  # Property removed
        # Verify in the graph
        assert "age" not in host.nodes["Alice"]

    def test_remove_multiple_properties(self):
        """REMOVE removes multiple properties from a node."""
        host = nx.MultiDiGraph()
        host.add_node("Alice", name="Alice", age=30, city="NYC")

        qry = """
        MATCH (n {name: "Alice"})
        REMOVE n.age, n.city
        RETURN n.name, n.age, n.city
        """
        res = NXCypher(host).run(qry)
        assert res["n.name"] == ["Alice"]
        assert res["n.age"] == [None]
        assert res["n.city"] == [None]
        # Verify in the graph
        assert "age" not in host.nodes["Alice"]
        assert "city" not in host.nodes["Alice"]

    def test_remove_nonexistent_property(self):
        """REMOVE on a nonexistent property is a no-op."""
        host = nx.MultiDiGraph()
        host.add_node("Alice", name="Alice")

        qry = """
        MATCH (n {name: "Alice"})
        REMOVE n.nonexistent
        RETURN n.name
        """
        res = NXCypher(host).run(qry)
        assert res["n.name"] == ["Alice"]


class TestRemoveLabel:
    """Tests for REMOVE label functionality."""

    def test_remove_single_label(self):
        """REMOVE removes a label from a node."""
        host = nx.MultiDiGraph()
        host.add_node("Alice", __labels__={"Person", "Employee"}, name="Alice")

        qry = """
        MATCH (n {name: "Alice"})
        REMOVE n:Employee
        RETURN LABELS(n)
        """
        res = NXCypher(host).run(qry)
        assert res["LABELS(n)"] == [["Person"]]
        # Verify in the graph
        assert "Employee" not in host.nodes["Alice"]["__labels__"]

    def test_remove_nonexistent_label(self):
        """REMOVE on a nonexistent label is a no-op."""
        host = nx.MultiDiGraph()
        host.add_node("Alice", __labels__={"Person"}, name="Alice")

        qry = """
        MATCH (n {name: "Alice"})
        REMOVE n:Nonexistent
        RETURN LABELS(n)
        """
        res = NXCypher(host).run(qry)
        assert res["LABELS(n)"] == [["Person"]]


class TestRemoveWithMatch:
    """Tests for REMOVE with various MATCH patterns."""

    def test_remove_with_relationship_match(self):
        """REMOVE works with relationship patterns."""
        host = nx.MultiDiGraph()
        host.add_node("Alice", name="Alice", age=30)
        host.add_node("Bob", name="Bob", age=25)
        host.add_edge("Alice", "Bob", __labels__={"KNOWS"})

        qry = """
        MATCH (a)-[:KNOWS]->(b)
        REMOVE a.age
        RETURN a.name, a.age
        """
        res = NXCypher(host).run(qry)
        assert res["a.name"] == ["Alice"]
        assert res["a.age"] == [None]
        # Bob's age is untouched
        assert host.nodes["Bob"]["age"] == 25

    def test_remove_from_multiple_nodes(self):
        """REMOVE affects all matched nodes."""
        host = nx.MultiDiGraph()
        host.add_node("Alice", name="Alice", temp="x")
        host.add_node("Bob", name="Bob", temp="y")
        host.add_edge("Alice", "Bob", __labels__={"KNOWS"})

        qry = """
        MATCH (a)-[:KNOWS]->(b)
        REMOVE a.temp, b.temp
        RETURN a.name, a.temp, b.name, b.temp
        """
        res = NXCypher(host).run(qry)
        assert res["a.name"] == ["Alice"]
        assert res["a.temp"] == [None]
        assert res["b.name"] == ["Bob"]
        assert res["b.temp"] == [None]
        # Verify in the graph
        assert "temp" not in host.nodes["Alice"]
        assert "temp" not in host.nodes["Bob"]
