import json

from rest_framework.test import APITestCase
from account.models import User
from rest_framework import status
from http.cookies import SimpleCookie

from location.models import City, Region, Country, Language
from django.contrib.gis.geos import Point
from account.models import Role, UserRole


class BaseTestCase(APITestCase):
    def setUp(self):
        self.username = 'sedragurda'
        self.password = 'sedragurdaredips19'
        self.email = 'sedragurda@desoz.com'
        self.newsletter = True
        self.user = User.objects.create_user(
            username=self.username, email=self.email, password=self.password)

        tokens = User.create_jwt_tokens(self.user)

        self.client.cookies = SimpleCookie(
            {'access_token': tokens.get('access_token'),
             'refresh_token': tokens.get('refresh_token')})

        self.lang, created = Language.objects.get_or_create(
            title='Russia',
            locale='ru-RU'
        )

        self.country_ru, created = Country.objects.get_or_create(
            name={"en-GB": "Russian"}
        )

        self.role = Role.objects.create(role=Role.COUNTRY_ADMIN,
                                        country=self.country_ru)
        self.role.save()

        self.user_role = UserRole.objects.create(user=self.user, role=self.role)

        self.user_role.save()


class CountryTests(BaseTestCase):
    def setUp(self):
        super().setUp()

    def test_country_CRUD(self):
        data = {
            'name': {"ru-RU": "NewCountry"},
            'code': 'test1'
        }

        response = self.client.post('/api/back/location/countries/', data=data, format='json')
        response_data = response.json()
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

        country = Country.objects.get(pk=response_data["id"])
        role = Role.objects.create(role=Role.COUNTRY_ADMIN, country=country)
        role.save()

        user_role = UserRole.objects.create(user=self.user, role=role)

        user_role.save()

        response = self.client.get('/api/back/location/countries/', format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        response = self.client.get(f'/api/back/location/countries/{response_data["id"]}/', format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        update_data = {
            'name': json.dumps({"ru-RU": "Test new country"})
        }

        response = self.client.patch(f'/api/back/location/countries/{response_data["id"]}/', data=update_data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        response = self.client.delete(f'/api/back/location/countries/{response_data["id"]}/', format='json')
        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)


class RegionTests(BaseTestCase):

    def setUp(self):
        super().setUp()
        self.country = Country.objects.create(
            name=json.dumps({"en-GB": "Test country"}),
            code="test"
        )

        role = Role.objects.create(role=Role.COUNTRY_ADMIN, country=self.country)
        role.save()

        user_role = UserRole.objects.create(user=self.user, role=role)

        user_role.save()

    def test_region_CRUD(self):
        response = self.client.get('/api/back/location/regions/', format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        data = {
            'name': 'Test country',
            'code': 'test',
            'country_id': self.country.id
        }

        response = self.client.post('/api/back/location/regions/', data=data, format='json')
        response_data = response.json()
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

        response = self.client.get(f'/api/back/location/regions/{response_data["id"]}/', format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        update_data = {
            'name': json.dumps({"en-GB": "Test new country"})
        }

        response = self.client.patch(f'/api/back/location/regions/{response_data["id"]}/', data=update_data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        response = self.client.delete(f'/api/back/location/regions/{response_data["id"]}/', format='json')
        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)


class CityTests(BaseTestCase):

    def setUp(self):
        super().setUp()

        self.country = Country.objects.create(
            name=json.dumps({"en-GB": "Test country"}),
            code="test"
        )

        self.region = Region.objects.create(
            name="Test region",
            code="812",
            country=self.country
        )

        role = Role.objects.create(role=Role.COUNTRY_ADMIN, country=self.country)
        role.save()

        user_role = UserRole.objects.create(user=self.user, role=role)

        user_role.save()

    def test_city_CRUD(self):
        response = self.client.get('/api/back/location/cities/', format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        data = {
            'name': 'Test country',
            'code': 'test',
            'country_id': self.country.id,
            'region_id': self.region.id
        }

        response = self.client.post('/api/back/location/cities/', data=data, format='json')
        response_data = response.json()
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

        response = self.client.get(f'/api/back/location/cities/{response_data["id"]}/', format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        update_data = {
            'name': json.dumps({"en-GB": "Test new country"})
        }

        response = self.client.patch(f'/api/back/location/cities/{response_data["id"]}/', data=update_data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        response = self.client.delete(f'/api/back/location/cities/{response_data["id"]}/', format='json')
        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)


class AddressTests(BaseTestCase):

    def setUp(self):
        super().setUp()


        self.country = Country.objects.create(
            name=json.dumps({"en-GB": "Test country"}),
            code="test"
        )

        self.region = Region.objects.create(
            name="Test region",
            code="812",
            country=self.country
        )

        self.city = City.objects.create(
            name="Test region",
            code="812",
            region=self.region,
            country=self.country
        )

        role = Role.objects.create(role=Role.COUNTRY_ADMIN, country=self.country)
        role.save()

        user_role = UserRole.objects.create(user=self.user, role=role)

        user_role.save()

    def test_address_CRUD(self):
        response = self.client.get('/api/back/location/addresses/', format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        data = {
            'city_id': self.city.id,
            'number': '+79999999',
            "latitude": 37.0625,
            "longitude": -95.677068,
            "geo_lon": -95.677068,
            "geo_lat": 37.0625
        }

        response = self.client.post('/api/back/location/addresses/', data=data, format='json')
        response_data = response.json()
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

        response = self.client.get(f'/api/back/location/addresses/{response_data["id"]}/', format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        update_data = {
            'number': '+79999991'
        }

        response = self.client.patch(f'/api/back/location/addresses/{response_data["id"]}/', data=update_data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        response = self.client.delete(f'/api/back/location/addresses/{response_data["id"]}/', format='json')
        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
