from rest_framework import serializers
from django.db.models import *
from snow_flake_payment.models import *
from snow_flake.serializers import *
import math

def getIsShowSessionPurchaseOrderDetail(self):
    if(self.context.__contains__('request')):
        isShowSessionPurchaseOrderDetail = self.context['request'].query_params.get('isShowSessionPurchaseOrderDetail', None)
    elif (self.context.__contains__('isShowSessionPurchaseOrderDetail')):
        isShowSessionPurchaseOrderDetail = self.context['isShowSessionPurchaseOrderDetail']
    else:
        isShowSessionPurchaseOrderDetail = None
    return isShowSessionPurchaseOrderDetail

def getIsShowSessionShippingItemDetail(self):
    if(self.context.__contains__('request')):
        isShowSessionShippingItemDetail = self.context['request'].query_params.get('isShowSessionShippingItemDetail', None)
    elif (self.context.__contains__('isShowSessionShippingItemDetail')):
        isShowSessionShippingItemDetail = self.context['isShowSessionShippingItemDetail']
    else:
        isShowSessionShippingItemDetail = None
    return isShowSessionShippingItemDetail

class SessionPurchaseOrderSerializer(serializers.ModelSerializer):
    paymentMethod = serializers.SerializerMethodField()
    orderFrom = serializers.SerializerMethodField()
    coupon = serializers.SerializerMethodField()
    client = serializers.SerializerMethodField()
    sessionShippingItemList = serializers.SerializerMethodField()
    trackOrderList = serializers.SerializerMethodField()
    sessionPurchaseOrderCost = serializers.SerializerMethodField()

    class Meta:
        model = SessionPurchaseOrder
        fields = [
            'id',
            'createdDate',
            'updatedDate',
            'sessionId',
            'sessionUrl',
            'status',
            'paymentMethodId',
            'orderFromId',
            'couponId',
            'clientId',
            'sessionPurchaseOrderCost',
            'paymentMethod',
            'orderFrom',
            'coupon',
            'client',
            'sessionShippingItemList',
            'trackOrderList',
        ]

    def get_sessionPurchaseOrderCost(self,instance):
        subTotal = 0
        delivery = 0

        sessionShippingItemList = SessionShippingItem.objects.filter(sessionPurchaseOrderId = instance.id)
        for x in sessionShippingItemList:
            sessionPurchaseShippingItemList = SessionPurchaseShippingItem.objects.filter(sessionShippingItemId = x.id)
            
            # Calculate Subtotal:
            for y in sessionPurchaseShippingItemList:
                skuCostList = SKUCost.objects.filter(id = y.skuCostId.id)
                skuCost = None
                if skuCostList.__len__() > 0:
                    skuCost = skuCostList[0]
                
                if skuCost is not None:
                    serviceCost = (y.skuPrice * skuCost.serviceCost) / 100
                    handlingCost = (y.skuPrice * skuCost.handlingCost) / 100
                    packingCost = (y.skuPrice * skuCost.packingCost) / 100
                    taxCost = ((serviceCost + handlingCost + packingCost + y.skuPrice) * skuCost.taxCost)/100
                    total = serviceCost + handlingCost + packingCost + taxCost + skuCost.transactionFixedCost + y.skuPrice
                    transactionFeeCost = (total * skuCost.transactionFeeCost ) / 100
                    overall = total + transactionFeeCost
                    overall = math.ceil(overall) * y.deliveredQuantity
                    subTotal = subTotal + overall
        
            # Calculate Delivery
            delivery = delivery + x.shippingCostId.price
            for y in sessionPurchaseShippingItemList:
                delivery = delivery + (x.shippingCostId.additionalPrice * y.deliveredQuantity)

        total = subTotal + delivery

        sessionPurchaseOrderCostDic = {
            "subTotal":subTotal,
            "delivery":delivery,
            "total":total,
        }
        return sessionPurchaseOrderCostDic

        #     for sessionPurchaseShippingItem in sessionPurchaseShippingItemList:
        #         spsis = SessionPurchaseShippingItemSerializer(sessionPurchaseShippingItem)
        #         self.sumQuantity = self.sumQuantity + sessionPurchaseShippingItem.deliveredQuantity
        #         self.subTotalMin = self.subTotalMin + (sessionPurchaseShippingItem.skuPrice * sessionPurchaseShippingItem.deliveredQuantity)
        #         self.subTotalMax = self.subTotalMax + (spsis.data['offeredPrice'] * sessionPurchaseShippingItem.deliveredQuantity)
        #         self.sumService = self.sumService + (spsis.data['service'] * sessionPurchaseShippingItem.deliveredQuantity)
        #         self.sumTaxes = self.sumTaxes + (spsis.data['taxes'] * sessionPurchaseShippingItem.deliveredQuantity)
        #         self.sumPaymentMethod = self.sumPaymentMethod + (spsis.data['paymentMethod'] * sessionPurchaseShippingItem.deliveredQuantity)
                
        #     if current.shippingCostId is not None:
        #         selectedShippingCost = ShippingCost.objects.get(id = str(current.shippingCostId.id))
        #         if selectedShippingCost is not None:
        #             self.sumDelivery = self.sumDelivery + selectedShippingCost.price

        # if instance.isDiscountOnMultipleProducts == True and self.sumQuantity > 1:
        #     self.total = (self.subTotalMin + self.subTotalMax) / 2
        # else:
        #     self.total = self.subTotalMax

        # self.total = self.total + self.sumDelivery

        # if instance.couponId is not None:
        #     self.total = self.total - instance.couponId.discount

    def get_paymentMethod(self, instance):
        languageId = getLanguage(self)
        paymentMethod = PaymentMethod.objects.get(id=str(instance.paymentMethodId.id))
        return PaymentMethodSerializer(paymentMethod,context={'languageId':languageId}).data
    
    def get_orderFrom(self, instance):
        languageId = getLanguage(self)
        orderFrom = OrderFrom.objects.get(id=str(instance.orderFromId.id))
        return OrderFromSerializer(orderFrom,context={'languageId':languageId}).data

    def get_coupon(self, instance):
        if instance.couponId is not None:
            coupon = Coupon.objects.get(id=str(instance.couponId.id))
            return CouponSerializer(coupon).data

    def get_client(self,instance):
        if instance.clientId is not None:
            client = Client.objects.get(id=str(instance.clientId.id))
            return ClientDisplaySerializer(client).data
    
    def get_sessionShippingItemList(self,instance):
        isShowSessionPurchaseOrderDetail = getIsShowSessionPurchaseOrderDetail(self)
        if isShowSessionPurchaseOrderDetail is not None:
            if int(isShowSessionPurchaseOrderDetail) == 1:
                languageId = getLanguage(self)
                isDashboard = getIsDashboard(self)
                isShowItem = getIsShowItem(self)
                isShowSessionShippingItemDetail = getIsShowSessionShippingItemDetail(self)
                sessionShippingItemList = SessionShippingItem.objects.filter(sessionPurchaseOrderId = instance.id)
                return SessionShippingItemSerializer(sessionShippingItemList,many=True,context={'languageId':languageId,'isDashboard':isDashboard,'isShowSessionShippingItemDetail':isShowSessionShippingItemDetail,'isShowItem':isShowItem,}).data
            else:
                return []
        else:
            return []

    def get_trackOrderList(self,instance):
        trackOrderList = TrackOrder.objects.filter(sessionId = instance.id)
        return TrackOrderSerializer(trackOrderList,many=True).data

class SessionShippingItemSerializer(serializers.ModelSerializer):
    shippingCost = serializers.SerializerMethodField()
    sessionShippingAddress = serializers.SerializerMethodField()
    sessionPurchaseShippingItemList = serializers.SerializerMethodField()
    class Meta:
        model = SessionShippingItem
        fields = [
            'id',
            'createdDate',
            'updatedDate',
            'shippingCostId',
            'sessionPurchaseOrderId',
            'shippingCost',
            'sessionShippingAddress',
            'sessionPurchaseShippingItemList',
        ]

    def get_shippingCost(self, instance):
        if ShippingCost.objects.filter(id=str(instance.shippingCostId.id)).exists():
            languageId = getLanguage(self)
            shippingCost = ShippingCost.objects.get(id = str(instance.shippingCostId.id))
            return ShippingCostSerializer(shippingCost,context={'languageId':languageId}).data

    def get_sessionShippingAddress(self, instance):
        if SessionShippingAddress.objects.filter(sessionShippingItemId=str(instance.id)).exists():
            languageId = getLanguage(self)
            sessionShippingAddress = SessionShippingAddress.objects.get(sessionShippingItemId=str(instance.id))
            return SessionShippingAddressSerializer(sessionShippingAddress,context={'languageId':languageId}).data

    def get_sessionPurchaseShippingItemList(self,instance):
        isShowSessionShippingItemDetail = getIsShowSessionShippingItemDetail(self)
        if isShowSessionShippingItemDetail is not None:
            if int(isShowSessionShippingItemDetail) == 1:
                languageId = getLanguage(self)
                isDashboard = getIsDashboard(self)
                isShowItem = getIsShowItem(self)
                sessionPurchaseShippingItemList = SessionPurchaseShippingItem.objects.filter(sessionShippingItemId = instance.id)
                return SessionPurchaseShippingItemSerializer(sessionPurchaseShippingItemList,many=True,context={'languageId':languageId,'isDashboard':isDashboard,'isShowItem':isShowItem,}).data

class SessionShippingAddressSerializer(serializers.ModelSerializer):
    country = serializers.SerializerMethodField()
    state = serializers.SerializerMethodField()
    city = serializers.SerializerMethodField()
    class Meta:
        model = SessionShippingAddress
        fields = [
            'sessionShippingItemId',
            'address1',
            'address2',
            'zipCode',
            'countryId',
            'stateId',
            'cityId',
            'createdDate',
            'updatedDate',
            'country',
            'state',
            'city',
        ]
    def get_country(self,instance):
        return getCountry(self,instance)

    def get_state(self,instance):
        return getState(self,instance)

    def get_city(self,instance):
        return getCity(self,instance)

class SessionPurchaseShippingItemSerializer(serializers.ModelSerializer):
    sku = serializers.SerializerMethodField()
    totalPrice = serializers.SerializerMethodField()
    class Meta:
        model = SessionPurchaseShippingItem
        fields = [
            'id',
            'totalPrice',
            'skuPrice',
            'skuDiscount',
            'deliveredQuantity',
            'createdDate',
            'updatedDate',
            'skuCostId',  
            'skuId',
            'sessionShippingItemId',
            'sku',
        ]
  
    def get_totalPrice(self,instance):
        price,skuCostId = calculatePrice(instance.skuPrice,instance.skuCostId)
        return math.ceil(price) * instance.deliveredQuantity

    def get_sku(self, instance):
        return getSKU(self,instance)

class TrackOrderSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = TrackOrder
        fields = [
            'id',
            'sessionId',
            'purchaseOrderId',
            'createdDate',
            'updatedDate',
        ]

class SessionRechargeSerializer(serializers.ModelSerializer):
    #taxes = serializers.SerializerMethodField()
    paymentMethod = serializers.SerializerMethodField()
    
    sumTaxes = 0
    transactionFees = 0
    total = 0
    
    class Meta:
        model = SessionRecharge
        fields = [
            'id',
            'subTotal',
            'service',
            'sessionId',
            'sessionUrl',
            'status',
            'description',
            'createdDate',
            'updatedDate',
            'rechargeCostId',
            'paymentMethodId',
            'paymentMethod',
        ]

    # def get_taxes(self,instance):
    #     return getTaxes(self,instance)

    def get_paymentMethod(self,instance):
        return getPaymentMethod(self,instance)

    def to_representation(self, instance):
        ret = super().to_representation(instance)
        
        self.sumTaxes = 0
        self.transactionFees = 0
        self.total = 0
        
        if instance.service > 0:
            self.total = instance.subTotal + instance.service
        else:
            self.total = instance.subTotal
        
        if instance.taxesId is not None:
            currentValue = 0
            if instance.service > 0:
                currentValue = instance.service
            else:
                currentValue = self.total
            
            self.sumTaxes = self.sumTaxes + ((currentValue * instance.taxesId.price) / 100)
            self.total = self.total + self.sumTaxes
        
        if instance.paymentMethodId is not None:
            if instance.paymentMethodId.isPercentage == True:
                preTotal = self.total + instance.paymentMethodId.fixedPrice
                preTotal = preTotal / (1 - (instance.paymentMethodId.price / 100))
                self.transactionFees = preTotal - self.total
            else:
                self.transactionFees  = self.transactionFees + instance.paymentMethodId.price
            
            self.total = self.total + self.transactionFees

        ret['sumTaxes'] = self.sumTaxes
        ret['transactionFees'] = self.transactionFees
        ret['total'] = self.total
        return ret

