"""Tests for uncovered branches in topic module."""

from local_deep_research.advanced_search_system.findings.topic import (
    Topic,
    TopicGraph,
)


class TestTopicRejectSource:
    def test_reject_source_not_in_supporting(self):
        """Rejecting a source not in supporting_sources only adds to rejected."""
        topic = Topic(
            id="t1",
            title="Test",
            lead_source={"url": "lead"},
            supporting_sources=[{"url": "s1"}],
        )
        new_source = {"url": "new"}
        topic.reject_source(new_source)

        # Should NOT remove anything from supporting
        assert {"url": "s1"} in topic.supporting_sources
        # Should add to rejected
        assert new_source in topic.rejected_sources

    def test_reject_source_in_supporting(self):
        """Rejecting a source in supporting_sources removes it and adds to rejected."""
        source = {"url": "s1"}
        topic = Topic(
            id="t1",
            title="Test",
            lead_source={"url": "lead"},
            supporting_sources=[source],
        )
        topic.reject_source(source)

        assert source not in topic.supporting_sources
        assert source in topic.rejected_sources


class TestTopicGraphLinkTopics:
    def test_link_topics_one_missing(self):
        """link_topics should be a no-op when one topic doesn't exist."""
        graph = TopicGraph()
        t1 = Topic(id="t1", title="T1", lead_source={"url": "a"})
        graph.add_topic(t1)

        graph.link_topics("t1", "nonexistent")

        assert t1.related_topic_ids == []

    def test_link_topics_both_missing(self):
        """link_topics should be a no-op when both topics don't exist."""
        graph = TopicGraph()
        graph.link_topics("x", "y")
        assert len(graph.topics) == 0


class TestTopicGraphSetParentChild:
    def test_set_parent_child_parent_missing(self):
        """set_parent_child should be a no-op when parent doesn't exist."""
        graph = TopicGraph()
        child = Topic(id="c1", title="Child", lead_source={"url": "c"})
        graph.add_topic(child)

        graph.set_parent_child("nonexistent", "c1")

        assert child.parent_topic_id is None

    def test_set_parent_child_child_missing(self):
        """set_parent_child should be a no-op when child doesn't exist."""
        graph = TopicGraph()
        parent = Topic(id="p1", title="Parent", lead_source={"url": "p"})
        graph.add_topic(parent)

        graph.set_parent_child("p1", "nonexistent")

        assert parent.child_topic_ids == []


class TestTopicGraphMergeTopics:
    def test_merge_with_children_and_parent_refs(self):
        """merge_topics transfers topic2's children to topic1."""
        graph = TopicGraph()
        t1 = Topic(id="t1", title="T1", lead_source={"url": "a"})
        t2 = Topic(id="t2", title="T2", lead_source={"url": "b"})
        child = Topic(
            id="child",
            title="Child",
            lead_source={"url": "c"},
            parent_topic_id="t2",
        )
        graph.add_topic(t1)
        graph.add_topic(t2)
        graph.add_topic(child)
        graph.set_parent_child("t2", "child")

        result = graph.merge_topics("t1", "t2")

        assert result is not None
        assert "child" in result.child_topic_ids
        assert child.parent_topic_id == "t1"
        assert "t2" not in graph.topics

    def test_merge_with_parent_topic_id_reference(self):
        """After merge, topics referencing topic2 as parent get updated to topic1."""
        graph = TopicGraph()
        t1 = Topic(id="t1", title="T1", lead_source={"url": "a"})
        t2 = Topic(id="t2", title="T2", lead_source={"url": "b"})
        orphan = Topic(
            id="orphan",
            title="Orphan",
            lead_source={"url": "o"},
            parent_topic_id="t2",
        )
        graph.add_topic(t1)
        graph.add_topic(t2)
        graph.add_topic(orphan)

        graph.merge_topics("t1", "t2")

        assert orphan.parent_topic_id == "t1"

    def test_merge_with_duplicate_rejected_sources(self):
        """Rejected sources already in topic1 are not duplicated."""
        shared_rejected = {"url": "rejected"}
        t1 = Topic(
            id="t1",
            title="T1",
            lead_source={"url": "a"},
            rejected_sources=[shared_rejected],
        )
        t2 = Topic(
            id="t2",
            title="T2",
            lead_source={"url": "b"},
            rejected_sources=[shared_rejected, {"url": "other_rejected"}],
        )
        graph = TopicGraph()
        graph.add_topic(t1)
        graph.add_topic(t2)

        result = graph.merge_topics("t1", "t2")

        assert result is not None
        # shared_rejected should appear only once
        count = result.rejected_sources.count(shared_rejected)
        assert count == 1
        # other_rejected should be present
        assert {"url": "other_rejected"} in result.rejected_sources

    def test_merge_nonexistent_topic_returns_none(self):
        """merge_topics returns None when one topic doesn't exist."""
        graph = TopicGraph()
        t1 = Topic(id="t1", title="T1", lead_source={"url": "a"})
        graph.add_topic(t1)

        assert graph.merge_topics("t1", "nonexistent") is None
        assert graph.merge_topics("nonexistent", "t1") is None
