from unittest.mock import MagicMock, patch

import pytest

from GramAddict.core.behaviors.profile_guard import ProfileGuardPlugin


@pytest.fixture
def profile_guard_plugin():
    return ProfileGuardPlugin()


@pytest.fixture
def mock_context():
    ctx = MagicMock()
    ctx.configs = MagicMock()
    ctx.configs.args.ignore_close_friends = True
    ctx.configs.args.visual_vibe_check_percentage = 0

    ctx.session_state = MagicMock()
    ctx.session_state.my_username = "test_bot"

    ctx.context_xml = '<xml><node content-desc="profile_header"/></xml>'
    ctx.device = MagicMock()
    ctx.username = "target_user"

    nav_graph = MagicMock()
    nav_graph.current_state = "ProfileView"
    ctx.cognitive_stack = {"nav_graph": nav_graph}
    return ctx


class TestProfileGuardPlugin:
    def test_can_activate_enabled(self, profile_guard_plugin, mock_context):
        assert profile_guard_plugin.can_activate(mock_context) is True

    def test_can_activate_wrong_screen(self, profile_guard_plugin, mock_context):
        mock_context.cognitive_stack["nav_graph"].current_state = "HomeFeed"
        assert profile_guard_plugin.can_activate(mock_context) is False

    def test_can_activate_no_username(self, profile_guard_plugin, mock_context):
        mock_context.username = None
        assert profile_guard_plugin.can_activate(mock_context) is False

    def test_execute_guard_self_profile(self, profile_guard_plugin, mock_context):
        mock_context.username = "test_bot"
        result = profile_guard_plugin.execute(mock_context)

        assert result.executed is True
        assert result.should_skip is True
        assert result.metadata["reason"] == "self_profile"

    def test_execute_guard_private(self, profile_guard_plugin, mock_context):
        mock_context.context_xml = "<xml>this account is private</xml>"
        result = profile_guard_plugin.execute(mock_context)

        assert result.executed is True
        assert result.should_skip is True
        assert result.metadata["reason"] == "private"

    def test_execute_guard_empty(self, profile_guard_plugin, mock_context):
        mock_context.context_xml = "<xml>no posts yet</xml>"
        result = profile_guard_plugin.execute(mock_context)

        assert result.executed is True
        assert result.should_skip is True
        assert result.metadata["reason"] == "empty"

    def test_execute_guard_close_friend(self, profile_guard_plugin, mock_context):
        mock_context.context_xml = "<xml>close friend</xml>"
        result = profile_guard_plugin.execute(mock_context)

        assert result.executed is True
        assert result.should_skip is True
        assert result.metadata["reason"] == "close_friend"

    def test_execute_guard_pass(self, profile_guard_plugin, mock_context):
        # Normal profile, no red flags
        result = profile_guard_plugin.execute(mock_context)

        assert result.executed is False

    @patch("random.random", return_value=0.1)  # 0.1 < 1.0
    def test_execute_guard_vibe_check_fail(self, mock_random, profile_guard_plugin, mock_context):
        mock_context.configs.args.visual_vibe_check_percentage = 100
        mock_telepathic = MagicMock()
        mock_telepathic.evaluate_profile_vibe.return_value = {
            "quality_score": 3,
            "matches_niche": False,
            "reason": "Bad vibes",
        }
        mock_context.cognitive_stack["telepathic"] = mock_telepathic

        result = profile_guard_plugin.execute(mock_context)

        assert result.executed is True
        assert result.should_skip is True
        assert result.metadata["reason"] == "vibe_check_failed"

    @patch("random.random", return_value=0.1)
    def test_execute_guard_vibe_check_pass(self, mock_random, profile_guard_plugin, mock_context):
        mock_context.configs.args.visual_vibe_check_percentage = 100
        mock_telepathic = MagicMock()
        mock_telepathic.evaluate_profile_vibe.return_value = {"quality_score": 8, "matches_niche": True}
        mock_context.cognitive_stack["telepathic"] = mock_telepathic

        result = profile_guard_plugin.execute(mock_context)

        # Passes vibe check, continues execution
        assert result.executed is False
