"""Location app views."""
from django.contrib.postgres.fields.jsonb import KeyTextTransform
from rest_framework import generics, status
from rest_framework.response import Response
from rest_framework.views import APIView

from location import filters
from location import models, serializers
from location.filters import RegionFilter
from location.views import common
from utils.methods import get_permission_classes
from utils.models import get_current_locale
from utils.permissions import (
    IsGuest, IsEstablishmentManager, IsEstablishmentAdministrator
)


# Address
class AddressListCreateView(common.AddressViewMixin, generics.ListCreateAPIView):
    """Create view for model Address."""
    serializer_class = serializers.AddressDetailSerializer
    queryset = models.Address.objects.all()
    permission_classes = get_permission_classes(
        IsEstablishmentManager,
        IsEstablishmentAdministrator,
        IsGuest,
    )


class AddressRUDView(common.AddressViewMixin, generics.RetrieveUpdateDestroyAPIView):
    """RUD view for model Address."""
    serializer_class = serializers.AddressDetailSerializer
    queryset = models.Address.objects.all()
    permission_classes = get_permission_classes(
        IsEstablishmentManager,
        IsEstablishmentAdministrator,
        IsGuest,
    )


# City
class CityListCreateView(common.CityViewMixin, generics.ListCreateAPIView):
    """Create view for model City."""
    serializer_class = serializers.CityBaseSerializer
    queryset = models.City.objects.all()
    filter_class = filters.CityBackFilter
    permission_classes = get_permission_classes(
        IsEstablishmentManager,
        IsEstablishmentAdministrator,
        IsGuest,
    )

    def get_queryset(self):
        """Overridden method 'get_queryset'."""
        qs = models.City.objects.all().annotate(locale_name=KeyTextTransform(get_current_locale(), 'name'))\
            .order_by('locale_name').with_base_related()
        if self.request.country_code and self.request.query_params.get('country_code') is None:
            qs = qs.by_country_code(self.request.country_code)
        return qs


class CityListSearchView(common.CityViewMixin, generics.ListCreateAPIView):
    """Create view for model City."""
    serializer_class = serializers.CityBaseSerializer
    queryset = models.City.objects.all()\
        .annotate(locale_name=KeyTextTransform(get_current_locale(), 'name'))\
        .order_by('locale_name')
    filter_class = filters.CityBackFilter
    pagination_class = None
    permission_classes = get_permission_classes(
        IsEstablishmentManager,
        IsEstablishmentAdministrator,
        IsGuest,
    )


class CityRUDView(common.CityViewMixin, generics.RetrieveUpdateDestroyAPIView):
    """RUD view for model City."""
    serializer_class = serializers.CityDetailSerializer
    permission_classes = get_permission_classes(
        IsEstablishmentManager,
        IsEstablishmentAdministrator,
        IsGuest,
    )


# Region
class RegionListCreateView(common.RegionViewMixin, generics.ListCreateAPIView):
    """Create view for model Region"""
    pagination_class = None
    serializer_class = serializers.RegionSerializer
    # ordering_fields = 'name'
    filter_class = RegionFilter
    permission_classes = get_permission_classes(
        IsEstablishmentManager,
        IsEstablishmentAdministrator,
        IsGuest,
    )


class RegionRUDView(common.RegionViewMixin, generics.RetrieveUpdateDestroyAPIView):
    """Retrieve view for model Region"""
    serializer_class = serializers.RegionSerializer
    permission_classes = get_permission_classes(
        IsEstablishmentManager,
        IsEstablishmentAdministrator,
        IsGuest,
    )


# Country
class CountryBaseViewMixin:
    """Mixin for Country views."""
    queryset = models.Country.objects.all()
    permission_classes = get_permission_classes(
        IsEstablishmentManager,
        IsEstablishmentAdministrator,
        IsGuest,
    )


class CountryListCreateView(CountryBaseViewMixin, generics.ListCreateAPIView):
    """List/Create view for model Country."""
    queryset = (models.Country.objects.annotate(
        locale_name=KeyTextTransform(get_current_locale(), 'name')).order_by('locale_name'))
    serializer_class = serializers.CountryBackSerializer
    pagination_class = None


class CountryRUDView(CountryBaseViewMixin, generics.RetrieveUpdateDestroyAPIView):
    """RUD view for model Country."""
    serializer_class = serializers.CountryBackSerializer


class CountryCallingCodeListView(APIView):
    """
    ## Country codes view.
    ### Response
    ```
    [
      "+7",
      "+386",
      "+352"
    ]
    ```
    ### Description
    Return an array of unique country code for all countries in a database.
    """
    pagination_class = None
    permission_classes = get_permission_classes(
        IsEstablishmentManager,
        IsEstablishmentAdministrator,
        IsGuest,
    )

    def get(self, request, *args, **kwargs):
        """
        ## Country codes view.
        ### Response
        ```
        [
          "+7",
          "+386",
          "+352"
        ]
        ```
        ### Description
        Return an array of unique country code for all countries in a database.
        """
        return Response(data=models.Country.objects.aggregate_country_codes(),
                        status=status.HTTP_200_OK)
