"""Tests for UNWIND clause."""

import pytest
import networkx as nx

from nxcypher import NXCypher


class TestUnwindLiteral:
    """Tests for UNWIND with literal lists."""

    def test_unwind_literal_integers(self):
        """UNWIND a literal list of integers."""
        host = nx.MultiDiGraph()
        host.add_node("A", name="A")  # Need at least one node for graph

        qry = """
        UNWIND [1, 2, 3] AS x
        RETURN x
        """
        res = NXCypher(host).run(qry)
        assert res["x"] == [1, 2, 3]

    def test_unwind_literal_strings(self):
        """UNWIND a literal list of strings."""
        host = nx.MultiDiGraph()
        host.add_node("A", name="A")

        qry = """
        UNWIND ["a", "b", "c"] AS letter
        RETURN letter
        """
        res = NXCypher(host).run(qry)
        assert res["letter"] == ["a", "b", "c"]


class TestUnwindWithCollect:
    """Tests for UNWIND combined with COLLECT."""

    def test_unwind_collected_names(self):
        """UNWIND a collected list of names."""
        host = nx.MultiDiGraph()
        host.add_node("Alice", name="Alice")
        host.add_node("Bob", name="Bob")
        host.add_node("Charlie", name="Charlie")
        host.add_edge("Alice", "Bob", __labels__={"KNOWS"})
        host.add_edge("Alice", "Charlie", __labels__={"KNOWS"})

        qry = """
        MATCH (a)-[:KNOWS]->(b)
        WITH a.name AS person, COLLECT(b.name) AS friends
        UNWIND friends AS friend
        RETURN friend
        """
        res = NXCypher(host).run(qry)
        assert set(res["friend"]) == {"Bob", "Charlie"}

    def test_unwind_preserves_all_values(self):
        """UNWIND preserves duplicates if they exist."""
        host = nx.MultiDiGraph()
        host.add_node("Alice", name="Alice")
        host.add_node("Bob", name="Bob")
        host.add_edge("Alice", "Bob", __labels__={"KNOWS"})
        host.add_edge("Alice", "Bob", __labels__={"LIKES"})

        qry = """
        MATCH (a)-[]->(b)
        WITH COLLECT(b.name) AS names
        UNWIND names AS name
        RETURN name
        """
        res = NXCypher(host).run(qry)
        # Bob appears twice because there are two edges to Bob
        assert res["name"] == ["Bob", "Bob"]


class TestUnwindEmpty:
    """Tests for UNWIND with empty lists."""

    def test_unwind_empty_list(self):
        """UNWIND an empty list returns no rows."""
        host = nx.MultiDiGraph()
        host.add_node("A", name="A")

        qry = """
        MATCH (a)-[:NONEXISTENT]->(b)
        WITH COLLECT(b.name) AS names
        UNWIND names AS name
        RETURN name
        """
        res = NXCypher(host).run(qry)
        # Empty result since no matches
        assert res.get("name", []) == []
