from django.shortcuts import render
from rest_framework.generics import GenericAPIView, DestroyAPIView, RetrieveUpdateAPIView, CreateAPIView, \
    ListCreateAPIView, ListAPIView
from rest_framework.parsers import MultiPartParser
from sale import serializers as saleSerializers
from django.views.generic import TemplateView
from rest_framework.response import Response
from core import filters as custom_filters
from setting import models as settingModel
from rest_framework.views import APIView
from rest_framework import permissions
from sale import models as saleModel
from user import models as userModel
from . import models as sellerModel
from core import models as coreModel
from django.http import HttpResponse
from django.template.loader import get_template
from user import exceptions as ex
from django.utils import timezone
from rest_framework import status
from django.db.models import Q
from core import paginations
from . import serializers
from . import permission
import re


class CreateProfile(CreateAPIView):
    permission_classes = [permissions.AllowAny]
    serializer_class = serializers.ProfileSerializer


class RetrieveUpdateProfile(RetrieveUpdateAPIView):
    serializer_class = serializers.ProfileUpdateSerializer
    queryset = sellerModel.Seller.objects.all()
    permission_classes = [permission.IsRelatedSeller]

    def get_serializer_class(self):
        if self.request.method == 'GET':
            return serializers.ProfileSerializer
        return serializers.ProfileUpdateSerializer


class RetrieveUpdateCompany(RetrieveUpdateAPIView):
    serializer_class = serializers.CompanySerializer
    queryset = sellerModel.Company.objects.all()
    permission_classes = [permission.IsRelatedSeller]


class ListCreateWarehouse(ListCreateAPIView):
    serializer_class = serializers.WarehouseSerializer

    def get_queryset(self):
        if self.request.user.id == self.kwargs.get('seller'):
            return sellerModel.Warehouse.objects.filter(seller_id=self.kwargs['seller'])
        raise ex.ForbiddenException

    def perform_create(self, serializer):
        if self.request.user.id == self.kwargs.get('seller'):
            serializer.save(seller_id=self.request.user.id)


class RetrieveUpdateWarehouse(RetrieveUpdateAPIView):
    serializer_class = serializers.WarehouseSerializer
    queryset = sellerModel.Warehouse.objects.all()
    permission_classes = [permission.IsRelatedSeller]


class RetrieveSellerFields(APIView):
    def get(self, request, seller):
        if self.request.user.id == seller:
            seller = sellerModel.Seller.objects.get(id=seller)
            cars = list(seller.car.values_list('id', flat=True))
            product = list(seller.product.values_list('id', flat=True))
            data = {'cars': cars, 'products': product}
            return Response(data)
        raise ex.ForbiddenException


class ListCreateSellerFields(ListCreateAPIView):
    serializer_class = serializers.FieldsSerializer

    # def get_queryset(self):
        # if self.request.user.id == self.kwargs.get('seller'):
        # return sellerModel.Seller.objects.filter(id=self.kwargs['seller'])
        # raise ex.ForbiddenException

    def post(self, request, *args, **kwargs):
        if self.request.user.id == self.kwargs.get('seller'):
            seller = sellerModel.Seller.objects.get(id=self.kwargs['seller'])
            serializer = serializers.FieldsSerializer(data=request.data)
            serializer.is_valid()
            related_cars = coreModel.Car.objects.filter(id__in=request.data["cars"])
            related_products = coreModel.Product.objects.filter(id__in=request.data["products"])
            seller.car.clear()
            seller.car.set(related_cars)
            seller.product.clear()
            seller.product.set(related_products)
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
        raise ex.ForbiddenException

    # def get_serializer_class(self):
    #     if self.request.method == 'GET':
    #         return serializers.FieldsDetailSerializer
        # return serializers.FieldsSerializer


class ListCreateDocuments(ListCreateAPIView):
    serializer_class = serializers.DocumentsSerializer
    parser_classes = (MultiPartParser,)

    def get_queryset(self):
        if self.request.user.id == self.kwargs.get('seller'):
            return sellerModel.Documents.objects.filter(seller_id=self.kwargs['seller'])
        raise ex.ForbiddenException

    def perform_create(self, serializer):
        if self.request.user.id == self.kwargs.get('seller'):
            serializer.save(seller_id=self.request.user.id)


class DeleteDocument(DestroyAPIView):
    serializer_class = serializers.DocumentsSerializer

    def get_queryset(self):
        if self.request.user.id == self.kwargs.get('seller'):
            queryset = sellerModel.Documents.objects.filter(id=self.kwargs['pk'], seller_id=self.kwargs.get('seller'))
            return queryset
        raise ex.ForbiddenException


class ListNotifications(ListAPIView):
    serializer_class = saleSerializers.NotificationSerializer

    def get_queryset(self):
        if self.request.user.id == self.kwargs.get('seller'):
            return saleModel.SuggestedPrices.objects.filter(seller_id=self.kwargs.get('seller'), status='waiting',
                                                            inquiry__inquiry_box__created__gte=
                                                            timezone.now() - timezone.timedelta(minutes=settingModel.SiteSetting.get_solo().inquiry_time)).order_by('-id')
        raise ex.ForbiddenException


class ListPriceBasis(ListAPIView):
    serializer_class = saleSerializers.PriceBasisSerializer

    def get_queryset(self):
        if self.request.user.id == self.kwargs.get('seller'):
            return saleModel.PriceBasis.objects.filter(suggested__seller_id=self.kwargs.get('seller'), stock=None, expired__gte=timezone.now()).order_by('-id')
        raise ex.ForbiddenException


class CreateCompetition(CreateAPIView):
    serializer_class = saleSerializers.CompetitionSerializer

    def perform_create(self, serializer):
        if self.request.user.id == self.kwargs.get('seller'):
            serializer.save(seller_id=self.request.user.id, base_id=self.kwargs.get('base'))
        else:
            raise ex.ForbiddenException


class ListInquiries(ListAPIView):
    """
        query should be one of these words:
        waiting : Not priced and not rejected
        priced : Answered inquiries
        rejected : Rejected inquiries from seller
        accepted : Accepted suggestions
        not-accepted : Not accepted suggestions
    """
    filter_backends = (custom_filters.SimpleFilterBackend,)
    serializer_class = saleSerializers.InquiriesSerializer
    pagination_class = paginations.Set15ForPagination

    def get_queryset(self):
        if self.request.user.id == self.kwargs.get('seller'):
            queryset = saleModel.SuggestedPrices.objects.filter(seller_id=self.kwargs.get('seller'))
            query = self.request.query_params.get('query')
            if query is not None:
                if query == 'accepted' or query == 'not-accepted':
                    queryset = queryset.filter(status='priced', accepted=True if query == 'accepted' else False). \
                        order_by('-id')
                else:
                    queryset = queryset.filter(status=query).order_by('-id')
            return queryset
        raise ex.ForbiddenException


class ListOrderDetails(ListAPIView):
    """
        query should be one of these words:
        waiting : Not received from the seller
        sent : In tookapoot center
        delivered : Sent or delivered to the customer
        cleared : Payed the product price to the seller
        not-cleared : Not paid to the seller
        all : All orders
    """
    filter_backends = (custom_filters.SimpleFilterBackend,)
    serializer_class = saleSerializers.ListOrderDetailsSerializer
    pagination_class = paginations.Set15ForPagination

    def get_queryset(self):
        if self.request.user.id == self.kwargs.get('seller'):
            queryset = saleModel.OrderDetails.objects.filter(~Q(order__status='cancelled'), ~Q(order__status=''),
                                                             suggested__seller_id=self.kwargs.get('seller'))
            query = self.request.query_params.get('query')
            if query is not None and query != 'all':
                if query == 'waiting':
                    queryset = queryset.filter(Q(order__status='payed') | Q(order__status='preparing')).order_by('-id')
                elif query == 'sent':
                    queryset = queryset.filter(Q(order__status='warehouse') | Q(order__status='quality')).order_by(
                        '-id')
                elif query == 'delivered':
                    queryset = queryset.filter(Q(order__status='sent') | Q(order__status='delivered')).order_by('-id')
                elif query == 'cleared' or query == 'not-cleared':
                    queryset = queryset.filter(cleared=True if query == 'cleared' else False).order_by('-id')
            return queryset
        raise ex.ForbiddenException


class CheckDuplication(GenericAPIView):
    permission_classes = [permissions.AllowAny]
    serializer_class = serializers.DuplicationSerializer

    def post(self, request):
        serializer = serializers.DuplicationSerializer(data=self.request.data)
        if serializer.is_valid():
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class RetrieveContract(APIView):
    def get(self, request, seller):
        if self.request.user.id == seller:
            contract = settingModel.SiteSetting.get_solo().contract
            contract = re.sub('%[a-z_]*%', self._convert_case, contract)
            data = {'contract': contract}
            return render(request, "seller/contract.html", data)
        raise ex.ForbiddenException

    def _convert_case(self, match_obj):
        seller = sellerModel.Seller.objects.get(id=self.request.user.id)
        address = userModel.Address.objects.filter(user_id=seller.id).first()
        if match_obj.group() is not None:
            match_obj = match_obj.group()[1:len(match_obj.group()) - 1]
            if match_obj == 'name':
                match_obj = seller.get_full_name()
            elif match_obj == 'identifier':
                match_obj = seller.identifier
            elif match_obj == 'nationality_code':
                match_obj = seller.nationality_code
            elif match_obj == 'address':
                match_obj = address.full_address() if address else ''
            elif match_obj == 'zipcode':
                match_obj = address.zipcode if address else ''
            elif match_obj == 'mobile':
                match_obj = seller.mobile
            elif match_obj == 'email':
                match_obj = seller.email
            elif match_obj == 'start_date':
                match_obj = seller.jalali_contract_start_date()
            elif match_obj == 'end_date':
                match_obj = seller.jalali_contract_end_date()
            return match_obj
