import json

from django.contrib.auth.models import User
from django.test import TestCase, Client
from django.utils import timezone

from .models import Tirage, Spectacle, Salle, CategorieSpectacle


class TestBdAViews(TestCase):
    def setUp(self):
        self.tirage = Tirage.objects.create(
            title="Test tirage",
            appear_catalogue=True,
            ouverture=timezone.now(),
            fermeture=timezone.now(),
        )
        self.category = CategorieSpectacle.objects.create(name="Category")
        self.location = Salle.objects.create(name="here")
        Spectacle.objects.bulk_create([
            Spectacle(
                title="foo", date=timezone.now(), location=self.location,
                price=0, slots=42, tirage=self.tirage, listing=False,
                category=self.category
            ),
            Spectacle(
                title="bar", date=timezone.now(), location=self.location,
                price=1, slots=142, tirage=self.tirage, listing=False,
                category=self.category
            ),
            Spectacle(
                title="baz", date=timezone.now(), location=self.location,
                price=2, slots=242, tirage=self.tirage, listing=False,
                category=self.category
            ),
        ])

        self.bda_user = User.objects.create_user(
            username="bda_user", password="bda4ever"
        )
        self.bda_user.profile.is_cof = True
        self.bda_user.profile.is_buro = True
        self.bda_user.profile.save()

    def bda_participants(self):
        """The BdA participants views can be queried"""
        client = Client()
        show = self.tirage.spectacle_set.first()

        client.login(self.bda_user.username, "bda4ever")
        tirage_resp = client.get("/bda/spectacles/{}".format(self.tirage.id))
        show_resp = client.get(
            "/bda/spectacles/{}/{}".format(self.tirage.id, show.id)
        )
        reminder_url = "/bda/mails-rappel/{}".format(show.id)
        reminder_get_resp = client.get(reminder_url)
        reminder_post_resp = client.post(reminder_url)
        self.assertEqual(200, tirage_resp.status_code)
        self.assertEqual(200, show_resp.status_code)
        self.assertEqual(200, reminder_get_resp.status_code)
        self.assertEqual(200, reminder_post_resp.status_code)

    def test_catalogue(self):
        """Test the catalogue JSON API"""
        client = Client()

        # The `list` hook
        resp = client.get("/bda/catalogue/list")
        self.assertJSONEqual(
            resp.content.decode("utf-8"),
            [{"id": self.tirage.id, "title": self.tirage.title}]
        )

        # The `details` hook
        resp = client.get(
            "/bda/catalogue/details?id={}".format(self.tirage.id)
        )
        self.assertJSONEqual(
            resp.content.decode("utf-8"),
            {
                "categories": [{
                    "id": self.category.id,
                    "name": self.category.name
                }],
                "locations": [{
                    "id": self.location.id,
                    "name": self.location.name
                }],
            }
        )

        # The `descriptions` hook
        resp = client.get(
            "/bda/catalogue/descriptions?id={}".format(self.tirage.id)
        )
        raw = resp.content.decode("utf-8")
        try:
            results = json.loads(raw)
        except ValueError:
            self.fail("Not valid JSON: {}".format(raw))
        self.assertEqual(len(results), 3)
        self.assertEqual(
            {(s["title"], s["price"], s["slots"]) for s in results},
            {("foo", 0, 42), ("bar", 1, 142), ("baz", 2, 242)}
        )
