from django.conf import settings
from django_filters.rest_framework import DjangoFilterBackend
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import generics, viewsets, status
from rest_framework.decorators import action, api_view
from rest_framework.permissions import AllowAny
from rest_framework.response import Response

from utils.views import CustomOrderingFilter, RewardFilter
from utils.web_helper import login_event, verification_event, profile_event
from . import models
from . import serializers


class CustomerViewSet(viewsets.ModelViewSet):
    """
    A simple ViewSet for viewing and editing customers.
    """
    permission_classes = (AllowAny,)
    queryset = models.Customer.objects.all()
    serializer_class = serializers.CustomerListSerializer
    filter_backends = [CustomOrderingFilter, DjangoFilterBackend]
    ordering_fields = ('created_at', 'full_name')
    ordering = ('-created_at',)
    filterset_fields = ('mobile', 'business', 'country_code',)
    lookup_field = 'id'

    def get_serializer_class(self):
        if self.action in ['list', 'retrieve']:
            return serializers.CustomerRetrieveSerializer
        return super().get_serializer_class()

    @swagger_auto_schema(request_body=serializers.VerifySerializer,
                         responses={status.HTTP_200_OK: serializers.CustomerRetrieveSerializer})
    @action(detail=False, methods=['post'])
    def verify(self, request):
        val_code = request.data.get('validation_code')
        if val_code is None:
            return Response(dict(detail="not found!"), status=status.HTTP_400_BAD_REQUEST)
        customer = serializers.Customer.objects.filter(validation_code=val_code).first()
        if customer:
            if not customer.phone_verification:
                verification_event(customer)
            customer.validation_code = models._generate_validation_code()
            customer.phone_verification = True
            customer.save()
        else:
            return Response(dict(detail="not found!"), status=status.HTTP_404_NOT_FOUND)
        return Response(serializers.CustomerRetrieveSerializer(customer, context={"request": request}).data)

    @swagger_auto_schema(request_body=serializers.CustomerLoginSerializer,
                         responses={status.HTTP_200_OK: ''})
    @action(detail=False, methods=['post'])
    def login(self, request):
        mobile = request.data.get('mobile')
        country_code = request.data.get('country_code')
        if mobile is None:
            return Response(dict(detail="mobile is required!"), status=status.HTTP_400_BAD_REQUEST)
        if country_code is None:
            return Response(dict(detail="country_code is required!"), status=status.HTTP_400_BAD_REQUEST)
        customer = serializers.Customer.objects.filter(mobile=mobile, country_code=country_code).first()
        if customer:
            login_event(customer)
        else:
            return Response(dict(detail="Not found."), status=status.HTTP_404_NOT_FOUND)
        return Response(dict(detail="Magic code has been sent!"))

    @swagger_auto_schema(
        manual_parameters=[
            openapi.Parameter(
                'is_profile',
                openapi.IN_QUERY,
                description="",
                type=openapi.TYPE_BOOLEAN,
            ),
        ],
    )
    def retrieve(self, request, *args, **kwargs):
        if self.request.query_params.get('is_profile', 'false') in ['true', '1', 'True', 'TRUE', 'yes', 'Yes', 'YES']:
            profile_event(self.get_object())
        return super().retrieve(request, *args, **kwargs)


class RewardsListView(generics.ListAPIView):
    permission_classes = (AllowAny,)
    queryset = models.Reward.objects.filter(is_enabled=True).exclude(business__loyalty_model=0).all()
    serializer_class = serializers.RewardSerializer
    filter_backends = (CustomOrderingFilter, DjangoFilterBackend)
    ordering_fields = ('created_at', 'name', 'price')
    ordering = ('pk',)

    filterset_class = RewardFilter


class RedeemViewSet(viewsets.ModelViewSet):
    """
    A simple ViewSet for viewing and editing Redeem.
    """
    permission_classes = (AllowAny,)
    queryset = models.Redeem.objects.all()
    serializer_class = serializers.RedeemCreateSerializer
    filter_backends = [CustomOrderingFilter, DjangoFilterBackend]
    ordering_fields = ('created_at')
    ordering = ('-pk',)
    filterset_fields = ('customer', 'reward', 'customer__business')

    def get_serializer_class(self):
        if self.action in ['list', 'retrieve']:
            return serializers.RedeemListSerializer
        return super().get_serializer_class()


class ProductListView(generics.ListAPIView):
    permission_classes = (AllowAny,)
    queryset = models.Product.objects.all()
    serializer_class = serializers.ProductSerializer
    filter_backends = [CustomOrderingFilter, DjangoFilterBackend]
    ordering_fields = ('created_at',)
    ordering = ('-created_at',)
    filterset_fields = ('industry__business__customer', 'industry__business',)


# region Sale


class SaleView(generics.RetrieveUpdateDestroyAPIView):
    permission_classes = (AllowAny,)
    serializer_class = serializers.SaleSerializer
    queryset = models.SaleRecord.objects.all()

    def get_serializer_class(self):
        if self.request.method == 'GET':
            return serializers.SaleRetrieveSerializer
        return super().get_serializer_class()


class SaleListView(generics.ListCreateAPIView):
    permission_classes = (AllowAny,)
    queryset = models.SaleRecord.objects.filter(rate__isnull=False)
    serializer_class = serializers.SaleSerializer
    filter_backends = [CustomOrderingFilter, DjangoFilterBackend]
    ordering_fields = ('created_at', 'full_name')
    ordering = ('-created_at',)
    filterset_fields = ('customer', 'customer__business', 'business')

    def get_serializer_class(self):
        if self.request.method == 'GET':
            return serializers.SaleRetrieveSerializer
        return super().get_serializer_class()


class SaleCustomerView(generics.CreateAPIView):
    permission_classes = (AllowAny,)
    serializer_class = serializers.SaleCustomerSerializer


# endregion


class BusinessView(generics.RetrieveAPIView):
    permission_classes = (AllowAny,)
    queryset = models.Business.objects.all()
    serializer_class = serializers.BusinessSerializer


@swagger_auto_schema(method='head',
                     responses={status.HTTP_200_OK: ''})
@api_view(['HEAD'])
def business_code(request, pk):
    link = None
    business = models.Business.objects.filter(pk=pk).first()
    if business:
        link = f'{settings.APP_BASE_URL}survey?business={pk}&customer=unknown&approval={business.approval_code}'
    return Response(headers={"X-Link": link})
