from unittest.mock import patch

import pytest
from django.urls import reverse

from pricemon.models import PriceWatcher


@pytest.fixture
def watcher():
    with patch('pricemon.tasks.schedule_watcher'):
        return PriceWatcher.objects.create(
            name='Test product',
            url='https://example.com/product',
            css_selector='.price',
        )


@pytest.mark.django_db
class TestPriceMonitorToggle:
    def test_dashboard_shows_disable_action_for_enabled_watcher(self, client, watcher):
        response = client.get(reverse('pricemon-dashboard'))

        assert response.status_code == 200
        assert reverse('pricemon-toggle-enabled', args=[watcher.pk]) in response.content.decode()
        assert 'Disable monitoring' in response.content.decode()
        assert response.context['enabled_watchers_count'] == 1

    def test_toggle_disables_watcher_and_unschedules_job(self, client, watcher):
        with patch('pricemon.tasks.unschedule_watcher') as unschedule_watcher:
            response = client.post(reverse('pricemon-toggle-enabled', args=[watcher.pk]))

        watcher.refresh_from_db()
        assert response.status_code == 302
        assert response.url == reverse('pricemon-dashboard')
        assert watcher.enabled is False
        unschedule_watcher.assert_called_once()

    def test_toggle_enables_paused_watcher_and_schedules_job(self, client, watcher):
        with patch('pricemon.tasks.unschedule_watcher'):
            watcher.enabled = False
            watcher.save(update_fields=['enabled'])

        with patch('pricemon.tasks.schedule_watcher') as schedule_watcher:
            response = client.post(reverse('pricemon-toggle-enabled', args=[watcher.pk]))

        watcher.refresh_from_db()
        assert response.status_code == 302
        assert watcher.enabled is True
        schedule_watcher.assert_called_once()

    def test_toggle_rejects_get_requests(self, client, watcher):
        response = client.get(reverse('pricemon-toggle-enabled', args=[watcher.pk]))

        assert response.status_code == 405
