from django.test import TestCase
from django.urls import reverse
from django.utils.translation import gettext_lazy as _

from newsreader.accounts.tests.factories import UserFactory
from newsreader.news.collection.models import CollectionRule
from newsreader.news.collection.tests.factories import FeedFactory


class CollectionRuleBulkViewTestCase:
    def setUp(self):
        self.redirect_url = reverse("news:collection:rules")

        self.user = UserFactory()
        self.client.force_login(self.user)


class CollectionRuleBulkEnableViewTestCase(CollectionRuleBulkViewTestCase, TestCase):
    def setUp(self):
        super().setUp()

        self.url = reverse("news:collection:rules-enable")

        self.rules = FeedFactory.create_batch(size=5, user=self.user, enabled=False)

    def test_simple(self):
        response = self.client.post(
            self.url, {"rules": [rule.pk for rule in self.rules]}, follow=True
        )

        self.assertRedirects(response, self.redirect_url)

        rules = CollectionRule.objects.filter(user=self.user)

        for rule in rules:
            with self.subTest(rule=rule):
                self.assertEqual(rule.enabled, True)

        self.assertNotContains(response, _("The form contains errors, try again later"))

    def test_empty_rules(self):
        response = self.client.post(self.url, {"rules": []}, follow=True)

        self.assertRedirects(response, self.redirect_url)

        rules = CollectionRule.objects.filter(user=self.user)

        for rule in rules:
            with self.subTest(rule=rule):
                self.assertEqual(rule.enabled, False)

        self.assertContains(response, _("The form contains errors, try again later"))

    def test_rule_from_other_user(self):
        other_user = UserFactory()
        other_rules = FeedFactory.create_batch(size=5, user=other_user, enabled=False)

        response = self.client.post(
            self.url,
            {"rules": [other_rule.pk for other_rule in other_rules]},
            follow=True,
        )

        self.assertRedirects(response, self.redirect_url)

        rules = CollectionRule.objects.filter(user=other_user)

        for rule in rules:
            with self.subTest(rule=rule):
                self.assertEqual(rule.enabled, False)

        self.assertContains(response, _("The form contains errors, try again later"))

    def test_unauthenticated(self):
        self.client.logout()

        response = self.client.post(
            self.url, {"rules": [rule.pk for rule in self.rules]}, follow=True
        )

        self.assertRedirects(
            response,
            f"{reverse('accounts:login')}?next={reverse('news:collection:rules-enable')}",
        )

        rules = CollectionRule.objects.filter(user=self.user)

        for rule in rules:
            with self.subTest(rule=rule):
                self.assertEqual(rule.enabled, False)


class CollectionRuleBulkDisableViewTestCase(CollectionRuleBulkViewTestCase, TestCase):
    def setUp(self):
        super().setUp()

        self.url = reverse("news:collection:rules-disable")

        self.rules = FeedFactory.create_batch(size=5, user=self.user, enabled=True)

    def test_simple(self):
        response = self.client.post(
            self.url, {"rules": [rule.pk for rule in self.rules]}, follow=True
        )

        self.assertRedirects(response, self.redirect_url)

        rules = CollectionRule.objects.filter(user=self.user)

        for rule in rules:
            with self.subTest(rule=rule):
                self.assertEqual(rule.enabled, False)

        self.assertNotContains(response, _("The form contains errors, try again later"))

    def test_empty_rules(self):
        response = self.client.post(self.url, {"rules": []}, follow=True)

        self.assertRedirects(response, self.redirect_url)

        rules = CollectionRule.objects.filter(user=self.user)

        for rule in rules:
            with self.subTest(rule=rule):
                self.assertEqual(rule.enabled, True)

        self.assertContains(response, _("The form contains errors, try again later"))

    def test_rule_from_other_user(self):
        other_user = UserFactory()
        other_rules = FeedFactory.create_batch(size=5, user=other_user, enabled=True)

        response = self.client.post(
            self.url,
            {"rules": [other_rule.pk for other_rule in other_rules]},
            follow=True,
        )

        self.assertRedirects(response, self.redirect_url)

        rules = CollectionRule.objects.filter(user=other_user)

        for rule in rules:
            with self.subTest(rule=rule):
                self.assertEqual(rule.enabled, True)

        self.assertContains(response, _("The form contains errors, try again later"))

    def test_unauthenticated(self):
        self.client.logout()

        response = self.client.post(
            self.url, {"rules": [rule.pk for rule in self.rules]}, follow=True
        )

        self.assertRedirects(
            response,
            f"{reverse('accounts:login')}?next={reverse('news:collection:rules-disable')}",
        )

        rules = CollectionRule.objects.filter(user=self.user)

        for rule in rules:
            with self.subTest(rule=rule):
                self.assertEqual(rule.enabled, True)


class CollectionRuleBulkDeleteViewTestCase(CollectionRuleBulkViewTestCase, TestCase):
    def setUp(self):
        super().setUp()

        self.url = reverse("news:collection:rules-delete")

        self.rules = FeedFactory.create_batch(size=5, user=self.user)

    def test_simple(self):
        response = self.client.post(
            self.url, {"rules": [rule.pk for rule in self.rules]}, follow=True
        )

        self.assertRedirects(response, self.redirect_url)

        rules = CollectionRule.objects.filter(user=self.user)

        self.assertCountEqual(rules, [])

        self.assertNotContains(response, _("The form contains errors, try again later"))

    def test_empty_rules(self):
        response = self.client.post(self.url, {"rules": []}, follow=True)

        self.assertRedirects(response, self.redirect_url)

        rules = CollectionRule.objects.filter(user=self.user)

        self.assertCountEqual(rules, self.rules)

        self.assertContains(response, _("The form contains errors, try again later"))

    def test_rule_from_other_user(self):
        other_user = UserFactory()
        other_rules = FeedFactory.create_batch(size=5, user=other_user, enabled=True)

        response = self.client.post(
            self.url,
            {"rules": [other_rule.pk for other_rule in other_rules]},
            follow=True,
        )

        self.assertRedirects(response, self.redirect_url)

        rules = CollectionRule.objects.filter(user=other_user)

        self.assertCountEqual(rules, other_rules)

        self.assertContains(response, _("The form contains errors, try again later"))

    def test_unauthenticated(self):
        self.client.logout()

        response = self.client.post(
            self.url, {"rules": [rule.pk for rule in self.rules]}, follow=True
        )

        self.assertRedirects(
            response,
            f"{reverse('accounts:login')}?next={reverse('news:collection:rules-delete')}",
        )

        rules = CollectionRule.objects.filter(user=self.user)

        self.assertCountEqual(rules, self.rules)
