from django.views import View
from django.shortcuts import redirect
from django.conf import settings
from rest_framework import pagination
from rest_framework import generics
from rest_framework import filters as searchfilter
from django_filters import rest_framework as filters
from django_filters.rest_framework import DjangoFilterBackend
from snow_flake_payment.serializers import *
from rest_framework.exceptions import NotFound
from django.http import JsonResponse
from datetime import datetime
import json
import stripe

stripe.api_key = settings.STRIPE_SECRET_KEY

class StandardSetPagination(pagination.PageNumberPagination):
    page_size = 20 # default amount records in current page
    page_size_query_param = 'page_size'
    max_page_size = 1000 # max number of records in current page by using query param above

#Session Purchase Order Stripe

class ApplySessionPurchaseOrderPayment:
    def convertToLineItems(self,id,total,description):
        priceData = {
                "price_data":{
                    "currency":"gbp",
                    "unit_amount_decimal":round((float(total) * 100)),
                    "product_data":{
                        "name":'Total',
                        "description":description + ' ' + str(id),
                    }
                },
                "quantity":1
            }
        
        lineItems = [
            priceData
        ]

        return lineItems
    
    def pay(self,id,isMobile,successURL,cancelURL):
        if id is not None:
            total = 0
            selected = SessionPurchaseOrder.objects.get(id = id)
            if selected is not None:
                selectedSerializer = SessionPurchaseOrderSerializer(selected).data
                total = round(selectedSerializer["sessionPurchaseOrderCost"]['total'],2)
            else:
                raise NotFound({"Error":"Record Not Found"})
                
            lineItems = self.convertToLineItems(id,total,'Order Number')
                    
            checkoutSession = stripe.checkout.Session.create(
                            payment_method_types=["card"],
                            line_items=lineItems,
                            mode="payment",
                            success_url=successURL + '&sessionpurchaseorderid='+str(id),
                            cancel_url=cancelURL + '&sessionpurchaseorderid='+str(id),
                        )
                    
            selected.sessionId = checkoutSession.id
            selected.sessionUrl = checkoutSession.url
            selected.save()
            #redirect(checkoutSession.url)
            return JsonResponse({"sessionPurchaseOrderId":id,"isMobile":isMobile,"url":checkoutSession.url,"isSuccess":True,"message":"Stripe Checkout created"},safe=False)
        else:
            raise NotFound({"Error":"Invalid Request"})

    def expire(self,sessionPurchaseOrderId):
        selected = None
        checkoutSession = None
        isCheck = False

        if sessionPurchaseOrderId is not None:
            selected = SessionPurchaseOrder.objects.get(id = sessionPurchaseOrderId)
        
        if selected is not None:
            checkoutSession = stripe.checkout.Session.expire(selected.sessionId)

        if checkoutSession is not None:
            if checkoutSession['status'] == 'expired':
                isCheck = True
        
        if isCheck == True:
            selected.status = "expired"
            selected.updatedDate = datetime.now()
            selected.save()
            return True
        
        return False

class CreateStripeCheckoutSessionPurchaserOrderView(View):
    def post(self,request,*args,**kwargs):

        sessionPurchaseOrderId = None
        isMobile = False
        jsonData = json.loads(request.body)

        if jsonData.__len__() > 0:
            if "sessionPurchaseOrderId" in jsonData:
                sessionPurchaseOrderId = jsonData["sessionPurchaseOrderId"]
            
            if "isMobile" in jsonData:
                isMobile = jsonData["isMobile"]
        
        applyPayment = ApplySessionPurchaseOrderPayment()
        
        if sessionPurchaseOrderId is not None:
            if isMobile == True:
                return applyPayment.pay(sessionPurchaseOrderId,isMobile,settings.PAYMENT_SUCCESS_PURCHASE_ORDER_MOBILE_URL,settings.PAYMENT_CANCEL_PURCHASE_ORDER_MOBILE_URL,)
            else:
                return applyPayment.pay(sessionPurchaseOrderId,isMobile,settings.PAYMENT_SUCCESS_PURCHASE_ORDER_WEB_URL,settings.PAYMENT_CANCEL_PURCHASE_ORDER_WEB_URL)

class ExpireStripeCheckoutSessionPurchaseOrderView(View):
    def post(self,request,*args,**kwargs):
        
        sessionPurchaseOrderId = None
            
        jsonData = json.loads(request.body)
        
        if jsonData.__len__() > 0:
            if "sessionPurchaseOrderId" in jsonData:
                sessionPurchaseOrderId = jsonData["sessionPurchaseOrderId"]

        applyPayment = ApplySessionPurchaseOrderPayment()
        
        isSuccess = applyPayment.expire(sessionPurchaseOrderId)

        if isSuccess:
            return JsonResponse({"sessionPurchaseOrderId":sessionPurchaseOrderId,"isSuccess":True,"message":"Session is expired",},safe=False,)
        
        return JsonResponse({"sessionPurchaseOrderId":sessionPurchaseOrderId,"isSuccess":False,"message":"Session can not be expired",},safe=False,)

#Session Purchase Order

class SessionPurchaseOrderList(generics.ListCreateAPIView):
    queryset = SessionPurchaseOrder.objects.all().order_by('-id')
    serializer_class = SessionPurchaseOrderSerializer
    pagination_class = StandardSetPagination
    filter_backends =[searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_fields = ['paymentMethodId','orderFromId','couponId','clientId','sessionId','id']
    search_fields = ['id']

class SessionPurchaseOrderDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SessionPurchaseOrder.objects.all()
    serializer_class = SessionPurchaseOrderSerializer

class SessionShippingItemList(generics.ListCreateAPIView):
    queryset = SessionShippingItem.objects.all().order_by('-id')
    serializer_class = SessionShippingItemSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['sessionPurchaseOrderId']

class SessionShippingItemDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SessionShippingItem.objects.all()
    serializer_class = SessionShippingItemSerializer

class SessionShippingAddressList(generics.ListCreateAPIView):
    queryset = SessionShippingAddress.objects.all().order_by('-sessionShippingItemId')
    serializer_class = SessionShippingAddressSerializer
    pagination_class = StandardSetPagination
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['sessionShippingItemId']

class SessionShippingAddressDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SessionShippingAddress.objects.all().order_by('-sessionShippingItemId')
    serializer_class = SessionShippingAddressSerializer

class SessionPurchaseShippingItemList(generics.ListCreateAPIView):
    queryset = SessionPurchaseShippingItem.objects.all().order_by('id')
    serializer_class = SessionPurchaseShippingItemSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['sessionShippingItemId','skuId']

class SessionPurchaseShippingItemDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SessionPurchaseShippingItem.objects.all()
    serializer_class = SessionPurchaseShippingItemSerializer

class TrackOrderList(generics.ListCreateAPIView):
    queryset = TrackOrder.objects.all().order_by('-id')
    serializer_class = TrackOrderSerializer
    pagination_class = StandardSetPagination
    filter_backends =[DjangoFilterBackend]
    filterset_fields = ['sessionId','purchaseOrderId']

class TrackOrderDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = TrackOrder.objects.all()
    serializer_class = TrackOrderSerializer

#Session Recharge Stripe

class ApplySessionRechargePayment:
    def convertToLineItems(self,id,total,description):
        priceData = {
                "price_data":{
                    "currency":"gbp",
                    "unit_amount_decimal":round((float(total) * 100)),
                    "product_data":{
                        "name":'Total',
                        "description":description + ' ' + str(id),
                    }
                },
                "quantity":1
            }
        
        lineItems = [
            priceData
        ]

        return lineItems
    
    def pay(self,id,successURL,cancelURL):
        if id is not None:
            total = 0
            selected = SessionRecharge.objects.get(id = id)
            if selected is not None:
                selectedSerializer = SessionRechargeSerializer(selected).data
                total = round(selectedSerializer['total'],2)
            else:
               raise NotFound({"Error":"Record Not Found"})
            
            lineItems = self.convertToLineItems(id,total,'Recharge Number')
            
            checkoutSession = stripe.checkout.Session.create(
                        payment_method_types=["card"],
                        line_items=lineItems,
                        mode="payment",
                        success_url=successURL + '&sessionrechargeid='+str(id),
                        cancel_url=cancelURL + '&sessionrechargeid='+str(id),
                    )
                
            selected.sessionId = checkoutSession.id
            selected.sessionUrl = checkoutSession.url
            selected.save()
            return redirect(checkoutSession.url)

        return JsonResponse({"isSuccess":False},safe=False,)
    
    def expire(self,sessionRechargeId):
        selected = None
        checkoutSession = None
        isCheck = False

        if sessionRechargeId is not None:
            selected = SessionRecharge.objects.get(id = id)
        
        if selected is not None:
            checkoutSession = stripe.checkout.Session.expire(selected.sessionId)

        if checkoutSession is not None:
            if checkoutSession['status'] == 'expired':
                isCheck = True
        
        if isCheck == True:
            selected.status = "expired"
            selected.updatedDate = datetime.now()
            selected.save()
            return True
        
        return False

class CreateStripeCheckoutSessionRechargeView(View):
    def post(self,request,*args,**kwargs):

        sessionRechargeId = None
        isMobile = False
        
        jsonData = json.loads(request.body)
        
        if jsonData.__len__() > 0:
            if "sessionRechargeId" in jsonData:
                sessionRechargeId = jsonData["sessionRechargeId"]
            
            if "isMobile" in jsonData:
                isMobile = jsonData["isMobile"]

        applyPayment = ApplySessionRechargePayment()
        if sessionRechargeId is not None:
            if isMobile == True:
                return applyPayment.pay(sessionRechargeId,settings.PAYMENT_SUCCESS_RECHARGE_MOBILE_URL,settings.PAYMENT_CANCEL_RECHARGE_MOBILE_URL)
            else:
                return applyPayment.pay(sessionRechargeId,settings.PAYMENT_SUCCESS_RECHARGE_WEB_URL,settings.PAYMENT_CANCEL_RECHARGE_WEB_URL)
    

class ExpireStripeCheckoutSessionRechargeView(View):
    def post(self,request,*args,**kwargs):

        sessionRechargeId = None
        
        jsonData = json.loads(request.body)
        
        if jsonData.__len__() > 0:
            if "sessionRechargeId" in jsonData:
                sessionRechargeId = jsonData["sessionRechargeId"]

        applyPayment = ApplySessionRechargePayment()
        
        isSuccess = applyPayment.expire(sessionRechargeId)
        if isSuccess:
            return JsonResponse({"isSuccess":True,"message":"Session is expired",},safe=False,)
        
        return JsonResponse({"isSuccess":False,"message":"Session can not be expired",},safe=False,)

#Session Recharge

class SessionRechargeFilter(filters.FilterSet):
    startDate = filters.DateTimeFilter(field_name='createdDate', lookup_expr='gte')
    endDate = filters.DateTimeFilter(field_name='createdDate', lookup_expr='lte')
    
    class Meta:
        model = SessionRecharge
        fields = [
            #'taxesId',
            'paymentMethodId',
            'description',
            'startDate',
            'endDate',
            ]

class SessionRechargeList(generics.ListCreateAPIView):
    queryset = SessionRecharge.objects.all().order_by('-id')
    serializer_class = SessionRechargeSerializer
    pagination_class = StandardSetPagination
    filter_backends =[searchfilter.SearchFilter,DjangoFilterBackend]
    filterset_class = SessionRechargeFilter
    search_fields = ['description']

class SessionRechargeDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = SessionRecharge.objects.all()
    serializer_class = SessionRechargeSerializer