from datetime import timedelta

from django.test import TestCase
from django.utils import timezone
from rest_framework.test import APIClient

from .models import APIKey, City, Engagement, Spot, SpotImage, Tag, Ward


class APIContractTests(TestCase):
    def setUp(self):
        self.client = APIClient()
        _, self.raw_key = APIKey.create_key("Test Client")
        self.city = City.objects.create(name="Pune", region="Maharashtra")
        self.ward = Ward.objects.create(
            city=self.city, ward="Ward 13", name="Baner - Sus - Mahalunge", rank=1,
            score=9.2, trend=12, volunteers=34, kendras=2, partnerships=4,
            total_spots=1, center=[73.756, 18.55651],
            boundary=[[73.76244, 18.57465], [73.76259, 18.57196]],
            photos=["https://cdn.shahar.city/wards/ward-13/1.jpg"],
        )
        self.spot = Spot.objects.create(
            ward=self.ward, spot_id="2284561749", spot=135, kind="spot",
            category="garbage", status="in-progress", lon=73.7561, lat=18.5563,
            address="Sus Gaon, Baner, Pune", score=7.4, trend=8,
        )
        SpotImage.objects.create(spot=self.spot, image_type="reality", url="https://cdn.shahar.city/reality.jpg")
        self.anchor = Spot.objects.create(
            ward=self.ward, spot_id="2109384756", spot=1, kind="anchor", status="completed",
            lon=73.756, lat=18.55651, spot_name="Baner Anchor", address="Baner - Sus - Mahalunge, Pune",
            score=9.1, trend=11, shortlisted=True, transformation_at=timezone.now(),
        )
        for image_type in ("reality", "potential", "transformation"):
            SpotImage.objects.create(spot=self.anchor, image_type=image_type, url=f"https://cdn.shahar.city/{image_type}.jpg")
        self.anchor.tags.add(Tag.objects.create(name="public-space"))
        Engagement.objects.create(city=self.city, spot=self.spot, occurred_at=timezone.now(), engagement_type="citizen")

    def auth(self):
        return {"HTTP_AUTHORIZATION": f"Bearer {self.raw_key}"}

    def test_wards(self):
        response = self.client.get("/api/v1/cities/Pune/wards/", **self.auth())
        self.assertEqual(response.status_code, 200)
        self.assertTrue(response.json()["success"])
        self.assertEqual(response.json()["data"]["city"], "Pune")

    def test_spot_detail(self):
        response = self.client.get("/api/v1/spot-detail/2284561749/", **self.auth())
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json()["data"]["kind"], "spot")

    def test_reality_potential(self):
        response = self.client.get("/api/v1/reality-potential/?shortlisted=true&tags=public-space", **self.auth())
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json()["data"]["total_records"], 1)
        self.assertEqual(response.json()["data"]["spots"][0]["shortlisted_yes_no"], True)

    def test_summary(self):
        response = self.client.get("/api/v1/summary/?region=Pune", **self.auth())
        self.assertEqual(response.status_code, 200)
        data = response.json()["data"]
        self.assertEqual(data["total_spots_mapped"], 2)
        self.assertEqual(data["citizen_stakeholders_engaged"], 1)
        self.assertEqual(data["spots_transformed"], 1)

    def test_requires_api_key(self):
        response = self.client.get("/api/v1/summary/")
        self.assertEqual(response.status_code, 401)
        self.assertFalse(response.json()["success"])
