from .models import *
from rest_framework import serializers
from django.db.models import *
from common.common import isValidData,validateParentId
from datetime import datetime, timezone,date
from django.http import JsonResponse


# Subscription Order


class SubscriptionOrderSerializer(serializers.ModelSerializer):
    class Meta:
        model = SubscriptionOrder
        fields = [
            "id",
            "price",
            "currency",
            "startDate",
            "endDate",
            "isExpired",
            "createdDate",
            "updatedDate",
            "subscriptionPlanId",
            "deviceOSTypeId",
            "financialProfileId",
        ]

    def get_isAuthorized(self, instance):
        if isValidData(self, instance.financialProfileId.parentId.id):
            return True

    def validate(self, data):
        errorMessage = ""
        isCheck = False

        if "financialProfileId" in data:
            isCheck = validateParentId(
                self, data["financialProfileId"].parentId.id
            )
        else:
            errorMessage = "Parent Id does not exit"

        selectedPlanList = SubscriptionPlan.objects.filter(
            id=data["subscriptionPlanId"].id
        )
        if selectedPlanList.__len__() == 0:
            isCheck = False
            errorMessage = "Subscription Plan does not exit"
        else:
            selectedPlan = selectedPlanList[0]
            if selectedPlan.isUnLimited == False:
                isCheck = False
                errorMessage = (
                    "Free Subscription Plan is not allowed for Subscription Order"
                )

        price = data.get("price", None)
        if price is not None and price <= 0:
            isCheck = False
            errorMessage = "Price must be greater than zero"

        if isCheck == True:
            return data

        elif len(errorMessage) > 0:
            raise serializers.ValidationError({"error": [errorMessage]})


# Subscription Transaction


class SubscriptionTransactionSerializer(serializers.ModelSerializer):
    class Meta:
        model = SubscriptionTransaction
        fields = [
            "subscriptionOrderId",
            "price",
            "currency",
            "productId",
            "transactionId",
            "purchaseDate",
            "expirationDate",
            "revocationDate",
            "createdDate",
            "updatedDate",
        ]

    def get_isAuthorized(self, instance):
        if isValidData(
            self, instance.subscriptionOrderId.financialProfileId.parentId.id
        ):
            return True

    def validate(self, data):
        errorMessage = ""
        isCheck = False
        if "subscriptionOrderId" in data:
            isCheck = validateParentId(
                self, data["subscriptionOrderId"].financialProfileId.parentId.id
            )
        else:
            errorMessage = "Parent Id does not exit"

        if isCheck == True:
            return data

        elif len(errorMessage) > 0:
            raise serializers.ValidationError({"error": [errorMessage]})


# Subscription Order Transaction


class SubscriptionOrderTransactionSerializer(serializers.Serializer):
    price = serializers.FloatField()
    currency = serializers.CharField()
    productId = serializers.CharField()
    transactionId = serializers.CharField()
    startDate = serializers.DateTimeField()
    currentDate = serializers.DateTimeField()
    expirationDate = serializers.DateTimeField()
    purchaseDate = serializers.DateTimeField()
    revocationDate = serializers.DateTimeField(allow_null=True, required=False)
    deviceOSTypeId = serializers.IntegerField()
    financialProfileId = serializers.IntegerField()

    def validate(self, data):

        errorMessage = ""
        if "financialProfileId" in data:
            dataList = FinancialProfile.objects.filter(
                parentId=data["financialProfileId"]
            )
        else:
            errorMessage = "Financial Profile Id does not exit"

        isCheck = False
        if dataList.__len__() == 0:
            errorMessage = "Financial Profile does not exit"
        else:
            isCheck = validateParentId(self, dataList[0].parentId.id)

        if isCheck == False:
            errorMessage = "Parent Id invalid"

        if "price" in data:
            if data["price"] <= 0:
                errorMessage = "Price must be greater than zero"
        else:
            errorMessage = "Price is required"

        if "currency" not in data:
            errorMessage = "Currency is required"

        if "transactionId" not in data:
            errorMessage = "Transaction Id is required"
        
        if "productId" not in data:
            errorMessage = "Product Id is required"

        if "currentDate" not in data:
            errorMessage = "Current Date is required"

        if "deviceOSTypeId" in data:
            dataList = DeviceOSType.objects.filter(id=data["deviceOSTypeId"])
            if dataList.__len__() == 0:
                errorMessage = "Device OS Type is invalid"
        else:
            errorMessage = "Device OS Type is required"

        if len(errorMessage) > 0:
            raise serializers.ValidationError({"error": [errorMessage]})

        return data

    def create(self, validated_data):
        errorMessage = ""
        financialProfile = None
        if "financialProfileId" in validated_data:
            financialProfile = FinancialProfile.objects.get(
                parentId=validated_data["financialProfileId"]
            )

        if financialProfile is None:
            errorMessage = "Financial Profile does not exit"
            raise serializers.ValidationError({"error": [errorMessage]})

        planList = SubscriptionPlan.objects.filter(keyName=validated_data["productId"])
        selectedPlan = None
        if planList.__len__() > 0:
            selectedPlan = planList[0]
        
        deviceOSTypeList = DeviceOSType.objects.filter(id=validated_data["deviceOSTypeId"])
        selectedDeviceOSType = None
        if deviceOSTypeList.__len__() > 0:
            selectedDeviceOSType = deviceOSTypeList[0]

        current_date = validated_data["currentDate"]

        if isinstance(current_date, date) and not isinstance(current_date, datetime):
            current_date = timezone.make_aware(
                datetime.combine(current_date, datetime.min.time())
            )

        orderList = SubscriptionOrder.objects.filter(
            subscriptionPlanId=selectedPlan.id,
            financialProfileId=financialProfile.parentId.id,
            deviceOSTypeId = selectedDeviceOSType.id,
            endDate__gt=current_date,
            isExpired=False,
        ).order_by("endDate")

        if orderList.__len__() == 0:
            
            SubscriptionOrder.objects.filter(
                financialProfileId=financialProfile
            ).update(isExpired=True)

            subscriptionOrder = SubscriptionOrder(
                price=selectedPlan.price,
                currency="GBP",
                startDate=validated_data["startDate"],
                endDate=validated_data["expirationDate"],
                isExpired=False,
                createdDate=datetime.now(),
                updatedDate=datetime.now(),
                subscriptionPlanId=selectedPlan,
                financialProfileId=financialProfile,
                deviceOSTypeId=selectedDeviceOSType,
            )
            subscriptionOrder.save()

            subscriptionTransaction = SubscriptionTransaction(
                subscriptionOrderId=subscriptionOrder,
                price=validated_data["price"],
                currency=validated_data["currency"],
                productId=validated_data["productId"],
                transactionId=validated_data["transactionId"],
                purchaseDate=validated_data["purchaseDate"],
                expirationDate=validated_data["expirationDate"],
                revocationDate=validated_data.get(
                    "revocationDate", validated_data["expirationDate"]
                ),
                createdDate=datetime.now(),
                updatedDate=datetime.now(),
            )
            subscriptionTransaction.save()

            return JsonResponse(
                {
                    "status": "ok",
                    "message": "Transaction created successfully",
                    "price": validated_data["price"],
                    "currency": validated_data["currency"],
                    "productId": validated_data["productId"],
                    "transactionId": validated_data["transactionId"],
                    "purchaseDate": validated_data["purchaseDate"],
                    "startDate": validated_data["startDate"],
                    "expirationDate": validated_data["expirationDate"],
                    "financialProfileId": validated_data[
                        "financialProfileId"
                    ],
                }
            )
        else:
            return JsonResponse(
                {
                    "status": "exists",
                    "message": "Transaction already exists",
                    "price": validated_data["price"],
                    "currency": validated_data["currency"],
                    "productId": validated_data["productId"],
                    "transactionId": validated_data["transactionId"],
                    "purchaseDate": validated_data["purchaseDate"],
                    "startDate": validated_data["startDate"],
                    "expirationDate": validated_data["expirationDate"],
                    "financialProfileId": validated_data[
                        "financialProfileId"
                    ],
                }
            )
