from unittest.mock import MagicMock, patch

import pytest

from GramAddict.core.behaviors.carousel_browsing import CarouselBrowsingPlugin


@pytest.fixture
def carousel_plugin():
    return CarouselBrowsingPlugin()


@pytest.fixture
def mock_context():
    ctx = MagicMock()
    ctx.configs = MagicMock()
    ctx.configs.args.carousel_percentage = 100
    ctx.configs.args.carousel_count = "2-2"
    ctx.configs.get_plugin_config.return_value = {"percentage": 100, "count": "2-2"}
    ctx.context_xml = '<xml><node content-desc="carousel_indicator"/></xml>'
    ctx.device = MagicMock()
    ctx.device.get_info.return_value = {"displayWidth": 1080, "displayHeight": 2400}
    ctx.sleep_mod = 1.0
    return ctx


class TestCarouselBrowsingPlugin:
    @patch("GramAddict.core.behaviors.carousel_browsing.has_carousel_in_view", return_value=True)
    def test_can_activate_enabled(self, mock_has_carousel, carousel_plugin, mock_context):
        assert carousel_plugin.can_activate(mock_context) is True

    def test_can_activate_disabled_via_config(self, carousel_plugin, mock_context):
        mock_context.configs.get_plugin_config.return_value = {"percentage": 0, "count": "2-2"}
        assert carousel_plugin.can_activate(mock_context) is False

    @patch("GramAddict.core.behaviors.carousel_browsing.has_carousel_in_view", return_value=False)
    def test_can_activate_no_carousel(self, mock_has_carousel, carousel_plugin, mock_context):
        assert carousel_plugin.can_activate(mock_context) is False

    @patch("GramAddict.core.behaviors.carousel_browsing.random.random", return_value=0.1)  # 0.1 < 1.0 (100%)
    @patch("GramAddict.core.behaviors.carousel_browsing.humanized_horizontal_swipe")
    @patch("GramAddict.core.behaviors.carousel_browsing.sleep")
    def test_execute_success(self, mock_sleep, mock_swipe, mock_random, carousel_plugin, mock_context):
        result = carousel_plugin.execute(mock_context)

        assert result.executed is True
        assert result.interactions == 2

        # It should swipe 2 times based on "2-2" config
        assert mock_swipe.call_count == 2

        # Verify swipe arguments
        mock_swipe.assert_any_call(
            mock_context.device, start_x=1080 * 0.8, end_x=1080 * 0.2, y=2400 * 0.5, duration_ms=250
        )
