from rest_framework import serializers  # type: ignore
from mama_care.models import *
from django.db.models import *  # type: ignore
import secrets
import phonenumbers  # type: ignore
from django.http import JsonResponse  # type: ignore
from mama_care_api.settings import languageKey
from datetime import datetime


# def getError(key, message):
#     return {key: message}


def validatePassword(password):
    return len(password) == 6 and password.isdigit()


def generateToken(len):
    token = secrets.token_hex(len)
    return token


def getParentId(self):
    if self.context.__contains__("request"):
        parentId = self.context["request"].query_params.get("parentId", None)
        return parentId


def validateParentId(self, parentIdData):
    errorMessage = ""
    parentIdRequest = getParentId(self)
    if parentIdRequest is not None:
        if parentIdData is not None:
            if parentIdData == int(parentIdRequest):
                return True
            else:
                errorMessage = "Parent Id is not matched"
        else:
            errorMessage = "Parent Id is Required"
    else:
        errorMessage = "Parent Id is Required"

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


def isValidData(self,selectedParentProfileId):
    if self.context.__contains__("request"):
        parentId = self.context["request"].query_params.get("parentId", None)
        childId = self.context["request"].query_params.get("childId", None)
        parentProfileId = self.context["request"].query_params.get("parentProfileId", None)
        errorMessage = ""
        if parentId is None:
            errorMessage = "Parent Id is required"
            
        elif childId is None:
            errorMessage = "Child Id is required"

        elif parentProfileId is None:
            errorMessage = "Parent Profile Id is required"

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

        isExistChild = Child.objects.filter(id = childId).exists()

        if isExistChild == True:
            selectedChild = Child.objects.get(id = childId)
            if selectedChild.parentId.id == int(parentId):
                isExistParentProfile = ParentProfile.objects.filter(childId = childId).exists()
                if isExistParentProfile == True:
                    selectedParentProfile = ParentProfile.objects.get(childId = childId)
                    if selectedParentProfile.childId.id == int(childId) and selectedParentProfile.childId.id == int(parentProfileId) :
                        if selectedParentProfileId == int(parentProfileId):
                            return True
                        else:
                            errorMessage = "Invalid Parent Profile Id"    
                    else:
                        errorMessage = "Invalid Parent Profile Id"
                else:
                    errorMessage = "Parent Profile Id does not exist"
            else:
                errorMessage = "Invalid Parent Id"
        else:
            errorMessage = "Child Id does not exits"

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


def getIsDashboard(self):
    if self.context.__contains__("request"):
        isDashboard = self.context["request"].headers.get("isDashboard", None)
    elif self.context.__contains__("isDashboard"):
        isDashboard = self.context["isDashboard"]
    else:
        isDashboard = None
    return isDashboard


def getLanguageRecord(languageId):
    if languageId is not None:
        selectedLanguage = Language.objects.get(id=languageId)
        if selectedLanguage.isEnabled:
            return selectedLanguage.id
    return None


def getLanguage(self):
    if self.context.__contains__("request"):
        languageId = self.context["request"].headers.get(languageKey, None)
    elif self.context.__contains__(languageKey):
        languageId = self.context[languageKey]
    else:
        languageId = None

    return getLanguageRecord(languageId)


# Token Type


class TokenTypeSerializer(serializers.ModelSerializer):
    class Meta:
        model = TokenType
        fields = [
            "id",
            "keyName",
            "tokenTypeLen",
            "createdDate",
            "updatedDate",
        ]

#Device OS Type

class DeviceOSTypeSerializer(serializers.ModelSerializer):
    class Meta:
        model = DeviceOSType
        fields = [
            "id",
            "keyName",
            "createdDate",
            "updatedDate",
        ]

# Language


class LanguageSerializer(serializers.ModelSerializer):
    class Meta:
        model = Language
        fields = [
            "id",
            "name",
            "countryCode",
            "isEnabled",
            "languageCode",
            "createdDate",
            "updatedDate",
        ]


# Gender


class GenderSerializer(serializers.ModelSerializer):
    name = serializers.SerializerMethodField()

    class Meta:
        model = Gender
        fields = ["id", "keyName", "name"]

    def get_name(self, instance):
        languageId = getLanguage(self)
        if languageId is not None:
            genderLanguageList = GenderLanguage.objects.filter(
                genderId=str(instance.id)
            ).filter(languageId=languageId)
            if genderLanguageList.__len__() > 0:
                return genderLanguageList[0].name


class GenderLanguageSerializer(serializers.ModelSerializer):
    class Meta:
        model = GenderLanguage
        fields = ["id", "name", "genderId", languageKey]


# Child Type
class ChildTypeSerializer(serializers.ModelSerializer):
    name = serializers.SerializerMethodField()

    class Meta:
        model = ChildType
        fields = ["id", "keyName", "name"]

    def get_name(self, instance):
        languageId = getLanguage(self)
        if languageId is not None:
            childTypeLanguageList = ChildTypeLanguage.objects.filter(
                childTypeId=str(instance.id)
            ).filter(languageId=languageId)
            if childTypeLanguageList.__len__() > 0:
                return childTypeLanguageList[0].name


class ChildTypeLanguageSerializer(serializers.ModelSerializer):
    class Meta:
        model = ChildTypeLanguage
        fields = ["id", "name", "childTypeId", languageKey]


# Symptom Type
class SymptomTypeSerializer(serializers.ModelSerializer):
    name = serializers.SerializerMethodField()

    class Meta:
        model = SymptomType
        fields = [
            "id",
            "keyName",
            "image",
            "createdDate",
            "updatedDate",
            "name",
        ]

    def get_name(self, instance):
        languageId = getLanguage(self)
        if languageId is not None:
            symptomTypeLanguageList = SymptomTypeLanguage.objects.filter(
                symptomTypeId=str(instance.id)
            ).filter(languageId=languageId)
            if symptomTypeLanguageList.__len__() > 0:
                return symptomTypeLanguageList[0].name


class SymptomTypeLanguageSerializer(serializers.ModelSerializer):
    class Meta:
        model = SymptomTypeLanguage
        fields = [
            "id",
            "name",
            "symptomTypeId",
            languageKey,
        ]


# Kick Tracker Status
class KickTrackerStatusSerializer(serializers.ModelSerializer):
    name = serializers.SerializerMethodField()

    class Meta:
        model = KickTrackerStatus
        fields = [
            "id",
            "keyName",
            "count",
            "color",
            "createdDate",
            "updatedDate",
            "name",
        ]

    def get_name(self, instance):
        languageId = getLanguage(self)
        if languageId is not None:
            kickTrackerStatusLanguageList = KickTrackerStatusLanguage.objects.filter(
                kickTrackerStatusId=str(instance.id)
            ).filter(languageId=languageId)
            if kickTrackerStatusLanguageList.__len__() > 0:
                return kickTrackerStatusLanguageList[0].name


class KickTrackerStatusLanguageSerializer(serializers.ModelSerializer):
    class Meta:
        model = KickTrackerStatusLanguage
        fields = [
            "id",
            "name",
            "description",
            "kickTrackerStatusId",
            languageKey,
        ]


# BMI Cases
class BMICaseTypeSerializer(serializers.ModelSerializer):
    name = serializers.SerializerMethodField()
    caseList = serializers.SerializerMethodField()

    class Meta:
        model = BMICaseType
        fields = [
            "id",
            "keyName",
            "createdDate",
            "updatedDate",
            "name",
            "caseList",
        ]

    def get_name(self, instance):
        languageId = getLanguage(self)
        if languageId is not None:
            BMICaseTypeLanguageList = BMICaseTypeLanguage.objects.filter(
                bmiCaseTypeId=str(instance.id)
            ).filter(languageId=languageId)
            if BMICaseTypeLanguageList.__len__() > 0:
                return BMICaseTypeLanguageList[0].name

    def get_caseList(self, instance):
        languageId = getLanguage(self)
        bmiCaseList = BMICase.objects.filter(bmiCaseTypeId=instance.id)
        return BMICaseSerializer(
            bmiCaseList, context={languageKey: languageId}, many=True
        ).data


class BMICaseTypeLanguageSerializer(serializers.ModelSerializer):
    class Meta:
        model = BMICaseTypeLanguage
        fields = [
            "id",
            "name",
            "bmiCaseTypeId",
            languageKey,
        ]


class BMICaseSerializer(serializers.ModelSerializer):
    name = serializers.SerializerMethodField()
    rangeType = serializers.SerializerMethodField()
    weightGainList = serializers.SerializerMethodField()

    class Meta:
        model = BMICase
        fields = [
            "id",
            "keyName",
            "min",
            "max",
            "createdDate",
            "updatedDate",
            "bmiCaseTypeId",
            "name",
            "rangeType",
            "weightGainList",
        ]

    def get_name(self, instance):
        languageId = getLanguage(self)
        if languageId is not None:
            BMICaseLanguageList = BMICaseLanguage.objects.filter(
                bmiCaseId=str(instance.id)
            ).filter(languageId=languageId)
            if BMICaseLanguageList.__len__() > 0:
                return BMICaseLanguageList[0].name

    def get_rangeType(self, instance):
        val = 0
        if instance.min == 0:
            val = 1
        elif instance.max == 0:
            val = 2
        return val

    def get_weightGainList(self, instance):
        weightGainList = BMICaseWeightGain.objects.filter(bmiCaseId=instance.id)
        return BMICaseWeightGainSerializer(weightGainList, many=True).data


class BMICaseLanguageSerializer(serializers.ModelSerializer):
    class Meta:
        model = BMICaseLanguage
        fields = [
            "id",
            "name",
            "bmiCaseId",
            languageKey,
        ]


class BMICaseWeightGainSerializer(serializers.ModelSerializer):
    class Meta:
        model = BMICaseWeightGain
        fields = [
            "id",
            "min",
            "max",
            "bmiCaseId",
            "createdDate",
            "updatedDate",
        ]


class CalculationMethodSerializer(serializers.ModelSerializer):
    name = serializers.SerializerMethodField()

    class Meta:
        model = CalculationMethod
        fields = [
            "id",
            "keyName",
            "createdDate",
            "updatedDate",
            "name",
        ]

    def get_name(self, instance):
        languageId = getLanguage(self)
        if languageId is not None:
            calculationMethodLanguageList = CalculationMethodLanguage.objects.filter(
                calculationMethodId=str(instance.id)
            ).filter(languageId=languageId)
            if calculationMethodLanguageList.__len__() > 0:
                return calculationMethodLanguageList[0].name


class CalculationMethodLanguageSerializer(serializers.ModelSerializer):
    class Meta:
        model = CalculationMethodLanguage
        fields = [
            "id",
            "name",
            "calculationMethodId",
            languageKey,
        ]

#Pregnancy Week

class PregnancyWeekBasicSerializer(serializers.ModelSerializer):
    fetalDevelopment = serializers.SerializerMethodField()
    babySize = serializers.SerializerMethodField()

    class Meta:
        model = PregnancyWeek
        fields = [
            "id",
            "image",
            "fetalDevelopment",
            "babySize",
        ]

    def get_fetalDevelopment(self, instance):
        languageId = getLanguage(self)
        if languageId is not None:
            pregnancyWeekLanguageList = PregnancyWeekLanguage.objects.filter(
                pregnancyWeekId=str(instance.id)
            ).filter(languageId=languageId)
            if pregnancyWeekLanguageList.__len__() > 0:
                return pregnancyWeekLanguageList[0].fetalDevelopment
    
    def get_babySize(self,instance):
        languageId = getLanguage(self)
        dataList = PregnancyBabySize.objects.filter(pregnancyWeekId = instance.id)
        if dataList.__len__() > 0:
            return PregnancyBabySizeBasicSerializer(dataList[0],context={languageKey: languageId}).data
        return None
  
class PregnancyWeekDetailSerializer(serializers.ModelSerializer):
    fetalDevelopment = serializers.SerializerMethodField()
    babySize = serializers.SerializerMethodField()
    symptomList = serializers.SerializerMethodField()
    checkList = serializers.SerializerMethodField()
    nutritionList = serializers.SerializerMethodField()
    monthlyTip = serializers.SerializerMethodField()

    class Meta:
        model = PregnancyWeek
        fields = [
            "id",
            "keyName",
            "weekNumber",
            "trimester",
            "image",
            "createdDate",
            "updatedDate",
            "fetalDevelopment",
            "babySize",
            "symptomList",
            "checkList",
            "nutritionList",
            "monthlyTip",
        ]

    def get_fetalDevelopment(self, instance):
        languageId = getLanguage(self)
        if languageId is not None:
            pregnancyWeekLanguageList = PregnancyWeekLanguage.objects.filter(
                pregnancyWeekId=str(instance.id)
            ).filter(languageId=languageId)
            if pregnancyWeekLanguageList.__len__() > 0:
                return pregnancyWeekLanguageList[0].fetalDevelopment
    
    def get_babySize(self,instance):
        languageId = getLanguage(self)
        dataList = PregnancyBabySize.objects.filter(pregnancyWeekId = instance.id)
        if dataList.__len__() > 0:
            return PregnancyBabySizeDetailSerializer(dataList[0],context={languageKey: languageId}).data
        return None
    
    def get_symptomList(self,instance):
        languageId = getLanguage(self)
        dataList = PregnancySymptom.objects.filter(pregnancyWeekId = instance.id)
        return PregnancySymptomSerializer(dataList,context={languageKey: languageId},many=True).data
    
    def get_checkList(self,instance):
        languageId = getLanguage(self)
        dataList = PregnancyCheckList.objects.filter(pregnancyWeekId = instance.id)
        return PregnancyCheckListSerializer(dataList,context={languageKey: languageId},many=True).data

    def get_nutritionList(self,instance):
        languageId = getLanguage(self)
        dataList = PregnancyNutrition.objects.filter(pregnancyWeekId = instance.id)
        return PregnancyNutritionSerializer(dataList,context={languageKey: languageId},many=True).data
    
    def get_monthlyTip(self,instance):
        languageId = getLanguage(self)
        month = 0
        if instance.weekNumber <= 4:
            month = 1
        elif instance.weekNumber <= 8:
            month = 2
        elif instance.weekNumber <= 13:
            month = 3
        elif instance.weekNumber <= 17:
            month = 4
        elif instance.weekNumber <= 22:
            month = 5
        elif instance.weekNumber <= 27:
            month = 6
        elif instance.weekNumber <= 31:
            month = 7
        elif instance.weekNumber <= 35:
            month = 8
        else:
            month = 9
        
        selected = MonthlyTip.objects.filter(monthNumber = month)
        if selected.__len__() > 0:
            return MonthlyTipSerializer(selected[0],context={languageKey: languageId}).data
        return None

class PregnancyWeekLanguageSerializer(serializers.ModelSerializer):
    class Meta:
        model = PregnancyWeekLanguage
        fields = [
            "id",
            "fetalDevelopment",
            "createdDate",
            "updatedDate",
            "pregnancyWeekId",
            languageKey,
        ]

#Pregnancy Baby Size

class PregnancyBabySizeBasicSerializer(serializers.ModelSerializer):
    description = serializers.SerializerMethodField()
    class Meta:
        model = PregnancyBabySize
        fields = [
            "image",
            "description",
        ]
    def get_description(self, instance):
        languageId = getLanguage(self)
        if languageId is not None:
            pregnancyBabySizeLanguage = PregnancyBabySizeLanguage.objects.filter(
                pregnancyBabySizeId=str(instance.id)
            ).filter(languageId=languageId)
            if pregnancyBabySizeLanguage.__len__() > 0:
                return pregnancyBabySizeLanguage[0].description


class PregnancyBabySizeDetailSerializer(serializers.ModelSerializer):
    description = serializers.SerializerMethodField()
    class Meta:
        model = PregnancyBabySize
        fields = [
            "id",
            "keyName",
            "image",
            "createdDate",
            "updatedDate",
            "pregnancyWeekId",
            "description",
        ]
    def get_description(self, instance):
        languageId = getLanguage(self)
        if languageId is not None:
            pregnancyBabySizeLanguage = PregnancyBabySizeLanguage.objects.filter(
                pregnancyBabySizeId=str(instance.id)
            ).filter(languageId=languageId)
            if pregnancyBabySizeLanguage.__len__() > 0:
                return pregnancyBabySizeLanguage[0].description


class PregnancyBabySizeLanguageSerializer(serializers.ModelSerializer):
    class Meta:
        model = PregnancyBabySizeLanguage
        fields = [
            "id",
            "description",
            "createdDate",
            "updatedDate",
            "pregnancyBabySizeId",
            languageKey,
        ]

#Pregnancy Symptom

class PregnancySymptomSerializer(serializers.ModelSerializer):
    description = serializers.SerializerMethodField()
    class Meta:
        model = PregnancySymptom
        fields = [
            "id",
            "createdDate",
            "updatedDate",
            "pregnancyWeekId",
            "description",
        ]
    def get_description(self, instance):
        languageId = getLanguage(self)
        if languageId is not None:
            pregnancySymptomLanguage = PregnancySymptomLanguage.objects.filter(
                pregnancySymptomId=str(instance.id)
            ).filter(languageId=languageId)
            if pregnancySymptomLanguage.__len__() > 0:
                return pregnancySymptomLanguage[0].description


class PregnancySymptomLanguageSerializer(serializers.ModelSerializer):
    class Meta:
        model = PregnancySymptomLanguage
        fields = [
            "id",
            "description",
            "createdDate",
            "updatedDate",
            "pregnancySymptomId",
            languageKey,
        ]

#Pregnancy Checklist

class PregnancyCheckListSerializer(serializers.ModelSerializer):
    description = serializers.SerializerMethodField()
    class Meta:
        model = PregnancyCheckList
        fields = [
            "id",
            "createdDate",
            "updatedDate",
            "pregnancyWeekId",
            "description",
        ]

    def get_description(self, instance):
        languageId = getLanguage(self)
        if languageId is not None:
            pregnancyCheckListLanguage = PregnancyCheckListLanguage.objects.filter(
                pregnancyCheckListId=str(instance.id)
            ).filter(languageId=languageId)
            if pregnancyCheckListLanguage.__len__() > 0:
                return pregnancyCheckListLanguage[0].description


class PregnancyCheckListLanguageSerializer(serializers.ModelSerializer):
    class Meta:
        model = PregnancyCheckListLanguage
        fields = [
            "id",
            "description",
            "createdDate",
            "updatedDate",
            "pregnancyCheckListId",
            languageKey,
        ]

#Pregnancy Nutrition

class PregnancyNutritionSerializer(serializers.ModelSerializer):
    description = serializers.SerializerMethodField()
    class Meta:
        model = PregnancyNutrition
        fields = [
            "id",
            "pregnancyWeekId",
            "createdDate",
            "updatedDate",
            "description",
        ]
    
    def get_description(self, instance):
        languageId = getLanguage(self)
        if languageId is not None:
            pregnancyNutritionLanguage = PregnancyNutritionLanguage.objects.filter(
                pregnancyNutritionId=str(instance.id)
            ).filter(languageId=languageId)
            if pregnancyNutritionLanguage.__len__() > 0:
                return pregnancyNutritionLanguage[0].description


class PregnancyNutritionLanguageSerializer(serializers.ModelSerializer):
    class Meta:
        model = PregnancyNutritionLanguage
        fields = [
            "id",
            "description",
            "createdDate",
            "updatedDate",
            "pregnancyNutritionId",
            languageKey,
        ]

# Monthly Tips

class MonthlyTipSerializer(serializers.ModelSerializer):
    title = serializers.SerializerMethodField()
    description = serializers.SerializerMethodField()
    inspiration = serializers.SerializerMethodField()
    tipList = serializers.SerializerMethodField()
    class Meta:
        model = MonthlyTip
        fields = [
            "id",
            "monthNumber",
            "createdDate",
            "updatedDate",
            "title",
            "description",
            "inspiration",
            "tipList"
        ]

    def get_title(self, instance):
        languageId = getLanguage(self)
        if languageId is not None:
            monthlyTipLanguage = MonthlyTipLanguage.objects.filter(
                monthlyTipId=str(instance.id)
            ).filter(languageId=languageId)
            if monthlyTipLanguage.__len__() > 0:
                return monthlyTipLanguage[0].title

    def get_description(self, instance):
        languageId = getLanguage(self)
        if languageId is not None:
            monthlyTipLanguage = MonthlyTipLanguage.objects.filter(
                monthlyTipId=str(instance.id)
            ).filter(languageId=languageId)
            if monthlyTipLanguage.__len__() > 0:
                return monthlyTipLanguage[0].description

    def get_inspiration(self, instance):
        languageId = getLanguage(self)
        if languageId is not None:
            monthlyTipLanguage = MonthlyTipLanguage.objects.filter(
                monthlyTipId=str(instance.id)
            ).filter(languageId=languageId)
            if monthlyTipLanguage.__len__() > 0:
                return monthlyTipLanguage[0].inspiration
    
    def get_tipList(self,instance):
        languageId = getLanguage(self)
        selectedList = Tip.objects.filter(monthlyTipId = instance.id).filter(tip_tiplanguage__languageId = languageId)
        return TipSerializer(selectedList,many=True,context={languageKey: languageId}).data


class MonthlyTipLanguageSerializer(serializers.ModelSerializer):
    class Meta:
        model = MonthlyTipLanguage
        fields = [
            "id",
            "title",
            "description",
            "inspiration",
            "createdDate",
            "updatedDate",
            "monthlyTipId",
            languageKey,
        ]
# Tip
class TipSerializer(serializers.ModelSerializer):
    description = serializers.SerializerMethodField()
    class Meta:
        model = Tip
        fields = [
            "id",
            "monthlyTipId",
            "createdDate",
            "updatedDate",
            "description"
        ]

    def get_description(self, instance):
        languageId = getLanguage(self)
        if languageId is not None:
            tipLanguage = TipLanguage.objects.filter(
                tipId=str(instance.id)
            ).filter(languageId=languageId)
            if tipLanguage.__len__() > 0:
                return tipLanguage[0].description


class TipLanguageSerializer(serializers.ModelSerializer):
    class Meta:
        model = TipLanguage
        fields = [
            "id",
            "description",
            "createdDate",
            "updatedDate",
            "tipId",
            languageKey,
        ]

# Forget or Change Password
class ForgetOrChangePasswordSerializer(serializers.Serializer):
    flag = serializers.CharField()
    phone = serializers.CharField()
    newPassword = serializers.CharField()
    confirmPassword = serializers.CharField()
    oldPassword = serializers.CharField(default="")

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

        phone = None
        if "phone" in data:
            phone = data["phone"]
        else:
            errorMessage = "Phone is required"

        newPassword = None
        if "newPassword" in data:
            newPassword = data["newPassword"]
            if validatePassword(newPassword) != True:
                errorMessage = "newPassword", "Password must consists of 6 digits only"
        else:
            errorMessage = "newPassword", "New Password is required"

        confirmPassword = None
        if "confirmPassword" in data:
            confirmPassword = data["confirmPassword"]
        else:
            errorMessage = "confirmPassword", "Confirm Password is required"

        oldPassword = None
        flag = None
        if "flag" in data:
            flag = data["flag"]
            if flag == "change":
                if "oldPassword" in data:
                    oldPassword = data["oldPassword"]
                else:
                    errorMessage = "oldPassword", "Old Password is required"
        else:
            errorMessage = "Flag is required"

        if newPassword != confirmPassword:
            errorMessage = "confirmPassword", "Mismatch Password"

        parentDetailList = ParentDetail.objects.filter(parentId__phone=phone)
        if parentDetailList.__len__() > 0:
            selected = parentDetailList[0]
            if flag == "change":
                if oldPassword is not None:
                    if selected.password != oldPassword:
                       errorMessage = "OldPassword", "Invalid old Password"
        else:
            errorMessage = "phone", "No records found by phone"

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

        return data

    def create(self, validated_data):
        errorMessage = ""
        phone = validated_data["phone"]
        newPassword = validated_data["newPassword"]
        parentDetailList = ParentDetail.objects.filter(parentId__phone=phone)
        if parentDetailList.__len__() > 0:
            selected = parentDetailList[0]
            if selected is not None:
                selected.password = newPassword
                selected.save()
        else:
            errorMessage = "No records found by phone"
            raise serializers.ValidationError(
                {"error":[errorMessage]}
            )
        return JsonResponse({})

# Parent
# Main Serializer
class ParentSerializer(serializers.ModelSerializer):
    token = serializers.SerializerMethodField()
    parentDetail = serializers.SerializerMethodField()

    class Meta:
        model = Parent
        fields = [
            "id",
            "phone",
            "isTryingToBePregnant",
            "createdDate",
            "updatedDate",
            languageKey,
            "token",
            "parentDetail",
        ]

    def validatePhone(self, phone):
        isParsed = True
        try:
            parsed_number = phonenumbers.parse(phone, None)
        except:
            isParsed = False

        if isParsed:
            if phonenumbers.is_valid_number(parsed_number):
                return True
        return False

    def checkPhoneIsExists(self, phone):
        count = Parent.objects.filter(phone=phone).count()
        if count > 0:
            return False
        return True

    def validate(self, data):
        request = self.context.get("request")

        dataJson = request.data

        errorMessage = ""
        if "phone" in dataJson:
            phone = dataJson["phone"]
            if self.validatePhone(phone) != True:
                errorMessage = "Invalid Phone"
            elif request.method == "POST":
                if self.checkPhoneIsExists(phone) != True:
                    errorMessage = "phone", "Phone is already registered"
        else:
            errorMessage = "Phone is required"

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

    def get_token(self, instance):
        tokenList = ParentToken.objects.filter(parentId=instance.id)
        if tokenList.__len__() > 0:
            return ParentTokenSerializer(tokenList[0]).data
        else:
            selectedList = TokenType.objects.filter(keyName="parent")
            if selectedList.__len__() > 0:
                parentTokenMap = {}
                parentTokenMap["token"] = generateToken(selectedList[0].tokenTypeLen)
                parentTokenMap["createdDate"] = datetime.now()
                parentTokenMap["updatedDate"] = datetime.now()
                parentTokenMap["tokenTypeId"] = selectedList[0].id
                parentTokenMap["parentId"] = instance.id
                parentTokenSerializer = ParentTokenSerializer(data=parentTokenMap)
                if parentTokenSerializer.is_valid():
                    parentTokenSerializer.save()
                    return parentTokenSerializer.data

        return None

    def get_parentDetail(self,instance):
        isExists = ParentDetail.objects.filter(parentId = instance.id).exists()
        if isExists == True:
            selected = ParentDetail.objects.get(parentId = instance.id)
            return ParentDetailSerializer(selected).data
        return None

# Parent Detail
class ParentDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = ParentDetail
        exclude=["password"]

    def validate(self, data):
        request = self.context.get("request")

        dataJson = request.data

        errorMessage = ""

        if request.method == "POST":
            if "password" in dataJson:
                password = dataJson["password"]
                if validatePassword(password) != True:
                    errorMessage = "password", "Password must consists of 6 digits only"
                else:
                    data["password"] = password
            else:
                errorMessage = "password", "Password is required"

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

        return data

# Parent Token
class ParentTokenSerializer(serializers.ModelSerializer):
    class Meta:
        model = ParentToken
        fields = [
            "parentId",
            "token",
            "createdDate",
            "updatedDate",
            "tokenTypeId"
        ]


# Child
class ChildSerializer(serializers.ModelSerializer):
    gender = serializers.SerializerMethodField()
    childType = serializers.SerializerMethodField()
    parentProfile = serializers.SerializerMethodField()

    class Meta:
        model = Child
        fields = [
            "id",
            "isSelected",
            "name",
            "dateOfBirth",
            "weight",
            "length",
            "head",
            "createdDate",
            "updatedDate",
            "childTypeId",
            "genderId",
            "parentId",
            "childType",
            "gender",
            "parentProfile",
        ]

    def validate(self, data):
        isCheck = False
        if "parentId" in data:
            isCheck = validateParentId(self,data["parentId"].id)
        else:
            errorMessage = "parentId", "Parent Id does not exit"
        
        if isCheck == True:
            return data
        
        elif len(errorMessage) > 0:
            raise serializers.ValidationError({"error":[errorMessage]})

    def get_childType(self, instance):
        languageId = getLanguage(self)
        isExists = ChildType.objects.filter(id=instance.childTypeId.id).exists()
        if isExists == True:
            selectedChildType = ChildType.objects.get(id=instance.childTypeId.id)
            return ChildTypeSerializer(
                selectedChildType, context={languageKey: languageId}
            ).data
        return None

    def get_gender(self, instance):
        languageId = getLanguage(self)
        isExists = Gender.objects.filter(id=instance.genderId.id).exists()
        if isExists == True:
            selectedGender = Gender.objects.get(id=instance.genderId.id)
            return GenderSerializer(
                selectedGender, context={languageKey: languageId}
            ).data
        return None

    def get_parentProfile(self,instance):
        isExists = ParentProfile.objects.filter(childId = instance.id).exists()
        if isExists == True:
            selected = ParentProfile.objects.get(childId = instance.id)
            return ParentProfileSerializer(selected).data
        else:
            parentProfileMap={
                "createdDate":datetime.now(),
                "updatedDate":datetime.now(),
                "childId":instance.id
            }
            parentProfileSerializer = ParentProfileSerializer(data=parentProfileMap)
            if parentProfileSerializer.is_valid():
                parentProfileSerializer.save()
                return parentProfileSerializer.data
    

# Emergency Contact
class EmergencyContactSerializer(serializers.ModelSerializer):
    class Meta:
        model = EmergencyContact
        fields = [
            "id",
            "fullName",
            "phone",
            "createdDate",
            "updatedDate",
            "parentId",
        ]      

    def validate(self, data):
        errorMessage = ""
        isCheck = False
        if "parentId" in data:
            isCheck = validateParentId(self,data["parentId"].id)
        else:
            errorMessage = "parentId", "Parent Id does not exit"
        
        if isCheck == True:
            return data
        
        elif len(errorMessage) > 0:
            raise serializers.ValidationError({"error":[errorMessage]})

# Parent Profile
class ParentProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = ParentProfile
        fields = [
            "createdDate",
            "updatedDate",
            "childId",
        ]

# Tools


# Symptom Group
class SymptomGroupSerializer(serializers.ModelSerializer):
    isAuthorized = serializers.SerializerMethodField()
    symptomRowList = serializers.SerializerMethodField()

    class Meta:
        model = SymptomGroup
        fields = [
            "id",
            "date",
            "note",
            "createdDate",
            "updatedDate",
            "parentProfileId",
            "symptomRowList",
            "isAuthorized",
        ]

    def get_isAuthorized(self,instance):
        if isValidData(self,instance.parentProfileId.childId.id):
            return True

    def validate(self, data):
        errorMessage = ""
        isCheck = False
        if "parentProfileId" in data:
            isCheck = validateParentId(self,data["parentProfileId"].childId.parentId.id)
        else:
            errorMessage = "parentId", "Parent Id does not exit"
        
        if isCheck == True:
            return data
        
        elif len(errorMessage) > 0:
            raise serializers.ValidationError({"error":[errorMessage]})

    def get_symptomRowList(self, instance):
        languageId = getLanguage(self)
        dataList = SymptomRow.objects.filter(symptomGroupId=instance.id)
        return SymptomRowSerializer(
            dataList, many=True, context={languageKey: languageId}
        ).data


# Symptom Row
class SymptomRowSerializer(serializers.ModelSerializer):
    isAuthorized= serializers.SerializerMethodField()
    symptomType = serializers.SerializerMethodField()

    class Meta:
        model = SymptomRow
        fields = [
            "id",
            "createdDate",
            "updatedDate",
            "symptomTypeId",
            "symptomGroupId",
            "symptomType",
            "isAuthorized",
        ]

    def get_isAuthorized(self,instance):
        if isValidData(self,instance.symptomGroupId.parentProfileId.childId.id):
            return True

    def validate(self, data):
        errorMessage = ""
        isCheck = False
        if "symptomGroupId" in data:
            isCheck = validateParentId(self,data["symptomGroupId"].parentProfileId.childId.parentId.id)
        else:
            errorMessage = "parentId", "Parent Id does not exit"
        
        if isCheck == True:
            return data
        
        elif len(errorMessage) > 0:
            raise serializers.ValidationError({"error":[errorMessage]})

    def get_symptomType(self, instance):
        languageId = getLanguage(self)
        val = SymptomType.objects.filter(id=instance.symptomTypeId.id).exists()
        if val:
            selected = SymptomType.objects.get(id=instance.symptomTypeId.id)
            return SymptomTypeSerializer(
                selected, context={languageKey: languageId}
            ).data
        return None


# Kick Tracker Group
class KickTrackerGroupSerializer(serializers.ModelSerializer):
    isAuthorized= serializers.SerializerMethodField()
    kickTrackerRowSummary = serializers.SerializerMethodField()

    class Meta:
        model = KickTrackerGroup
        fields = [
            "id",
            "date",
            "createdDate",
            "updatedDate",
            "parentProfileId",
            "kickTrackerRowSummary",
            "isAuthorized",
        ]
    def get_isAuthorized(self,instance):
        if isValidData(self,instance.parentProfileId.childId.id):
            return True
        
    def validate(self, data):
        errorMessage = ""
        isCheck = False
        if "parentProfileId" in data:
            isCheck = validateParentId(self,data["parentProfileId"].childId.parentId.id)
        else:
            errorMessage = "parentId", "Parent Id does not exit"
        
        if isCheck == True:
            return data
        
        elif len(errorMessage) > 0:
            raise serializers.ValidationError({"error":[errorMessage]})

    def get_kickTrackerRowSummary(self, instance):
        count = KickTrackerRow.objects.filter(kickTrackerGroupId=instance.id).count()
        if count > 0:
            kickCounts = KickTrackerRow.objects.filter(
                kickTrackerGroupId=instance.id
            ).aggregate(totalKicks=Sum("kicks"), totalSeconds=Sum("seconds"))
            if kickCounts is not None:
                hours, remainder = divmod(kickCounts["totalSeconds"], 3600)
                minutes, seconds = divmod(remainder, 60)
                return {
                    "totalKicks": kickCounts["totalKicks"],
                    "hours": hours,
                    "minutes": minutes,
                    "seconds": seconds,
                }
        return None


# Kick Tracker Row
class KickTrackerRowSerializer(serializers.ModelSerializer):
    isAuthorized= serializers.SerializerMethodField()
    class Meta:
        model = KickTrackerRow
        fields = [
            "id",
            "date",
            "seconds",
            "kicks",
            "createdDate",
            "updatedDate",
            "kickTrackerGroupId",
            "isAuthorized",
        ]
    
    def get_isAuthorized(self,instance):
        if isValidData(self,instance.kickTrackerGroupId.parentProfileId.childId.id):
            return True

    def validate(self, data):
        errorMessage = ""
        isCheck = False
        if "kickTrackerGroupId" in data:
            isCheck = validateParentId(self,data["kickTrackerGroupId"].parentProfileId.childId.parentId.id)
        else:
            errorMessage = "parentId", "Parent Id does not exit"
        
        if isCheck == True:
            return data
        
        elif len(errorMessage) > 0:
            raise serializers.ValidationError({"error":[errorMessage]})


# Weight Gain
class WeightGainSerializer(serializers.ModelSerializer):
    isAuthorized = serializers.SerializerMethodField()
    bmi = serializers.SerializerMethodField()
    bmiCategory = serializers.SerializerMethodField()
    gain = serializers.SerializerMethodField()
    recommendedMin = serializers.SerializerMethodField()
    recommendedMax = serializers.SerializerMethodField()
    statusId = serializers.SerializerMethodField()
    status = serializers.SerializerMethodField()

    class Meta:
        model = WeightGain
        fields = [
            "id",
            "height",
            "prePregnancyWeight",
            "currentWeight",
            "currentWeek",
            "createdDate",
            "updatedDate",
            "bmiCaseId",
            "parentProfileId",
            "bmi",
            "bmiCategory",
            "gain",
            "recommendedMin",
            "recommendedMax",
            "statusId",
            "status",
            "isAuthorized",
        ]

    def get_isAuthorized(self,instance):
        if isValidData(self,instance.parentProfileId.childId.id):
            return True
        
    def validate(self, data):
        errorMessage = ""
        isCheck = False
        if "parentProfileId" in data:
            isCheck = validateParentId(self,data["parentProfileId"].childId.parentId.id)
        else:
            errorMessage = "parentId", "Parent Id does not exit"
        
        if isCheck == True:
            return data
        
        elif len(errorMessage) > 0:
            raise serializers.ValidationError({"error":[errorMessage]})

    def get_bmi(self, instance):
        return round(instance.prePregnancyWeight / pow((instance.height / 100), 2), 2)

    def get_bmiCategory(self, instance):
        languageId = getLanguage(self)
        langList = BMICaseLanguage.objects.filter(bmiCaseId=instance.bmiCaseId).filter(
            languageId=languageId
        )
        if langList.__len__() > 0:
            return langList[0].name
        return ""

    def getGain(self, instance):
        return instance.currentWeight - instance.prePregnancyWeight

    def get_gain(self, instance):
        return self.getGain(instance)

    def getTotalMinMax(self, instance):
        minVal = 0
        maxVal = 0
        bmiCaseWeightGainList = BMICaseWeightGain.objects.filter(
            bmiCaseId=instance.bmiCaseId
        )
        if bmiCaseWeightGainList.__len__() > 0:
            minVal = bmiCaseWeightGainList[0].min
            maxVal = bmiCaseWeightGainList[0].max
        result = max(0, min(instance.currentWeek, 40)) / 40.0

        totalMin = minVal * result
        totalMax = maxVal * result

        return totalMin, totalMax

    def get_recommendedMin(self, instance):
        recoMin, recoMax = self.getTotalMinMax(instance)
        return round(recoMin, 2)

    def get_recommendedMax(self, instance):
        recoMin, recoMax = self.getTotalMinMax(instance)
        return round(recoMax, 2)

    def getStatus(self, instance):
        totalMin, totalMax = self.getTotalMinMax(instance)
        statusId = -1
        status = ""
        gain = self.getGain(instance)
        if gain < totalMin - 0.1:
            statusId = 1
            status = "Below"
        elif gain > totalMax + 0.1:
            statusId = 3
            status = "Above"
        else:
            statusId = 2
            status = "Within"
        return statusId, status

    def get_statusId(self, instance):
        statusId, status = self.getStatus(instance)
        return statusId

    def get_status(self, instance):
        statusId, status = self.getStatus(instance)
        return status


#Ovulation
class OvulationSerializer(serializers.ModelSerializer):
    isAuthorized = serializers.SerializerMethodField()
    class Meta:
        model = Ovulation
        fields = [
            "id",
            "lastMenstrualPeriod",
            "cycleLength",
            "nextPeriod",
            "ovulationDay",
            "fertileStart",
            "fertileEnd",
            "expectedDueDate",
            "createdDate",
            "updatedDate",
            "parentProfileId",
            "isAuthorized",
        ]

    def get_isAuthorized(self,instance):
        if isValidData(self,instance.parentProfileId.childId.id):
            return True
    
    def validate(self, data):
        errorMessage = ""
        isCheck = False
        if "parentProfileId" in data:
            isCheck = validateParentId(self,data["parentProfileId"].childId.parentId.id)
        else:
            errorMessage = "parentId", "Parent Id does not exit"
        
        if isCheck == True:
            return data
        
        elif len(errorMessage) > 0:
            raise serializers.ValidationError({"error":[errorMessage]})

#Due Date Calculator
class DueDateCalculatorSerializer(serializers.ModelSerializer):
    isAuthorized = serializers.SerializerMethodField()
    calculationMethod = serializers.SerializerMethodField()

    class Meta:
        model = DueDateCalculator
        fields = [
            "id",
            "lastMenstrualPeriod",
            "cycleLength",
            "conceiveDate",
            "dateOfTransfer",
            "numOfDays",
            "ultrasoundDate",
            "weeks",
            "days",
            "expectedDueDate",
            "createdDate",
            "updatedDate",
            "parentProfileId",
            "calculationMethodId",
            "calculationMethod",
            "isAuthorized",
        ]

    def get_isAuthorized(self,instance):
        if isValidData(self,instance.parentProfileId.childId.id):
            return True

    def validate(self, data):
        errorMessage = ""
        isCheck = False
        if "parentProfileId" in data:
            isCheck = validateParentId(self,data["parentProfileId"].childId.parentId.id)
        else:
            errorMessage = "parentId", "Parent Id does not exit"
        
        if isCheck == True:
            return data
        
        elif len(errorMessage) > 0:
            raise serializers.ValidationError({"error":[errorMessage]})
    
    def get_calculationMethod(self,instance):
        languageId = getLanguage(self)
        val =  CalculationMethod.objects.filter(id = instance.calculationMethodId.id).exists()
        if val:
            selected = CalculationMethod.objects.get(id = instance.calculationMethodId.id)
            return CalculationMethodSerializer(selected,context={languageKey: languageId}).data
        
        return None

# Notes
class NotesSerializer(serializers.ModelSerializer):
    isAuthorized = serializers.SerializerMethodField()
    class Meta:
        model = Notes
        fields = [
            "id",
            "title",
            "description",
            "createdDate",
            "updatedDate",
            "parentProfileId",
            "isAuthorized",
        ]

    def get_isAuthorized(self,instance):
        if isValidData(self,instance.parentProfileId.childId.id):
            return True
    
    def validate(self, data):
        errorMessage = ""
        isCheck = False
        if "parentProfileId" in data:
            isCheck = validateParentId(self,data["parentProfileId"].childId.parentId.id)
        else:
            errorMessage = "parentId", "Parent Id does not exit"
        
        if isCheck == True:
            return data
        
        elif len(errorMessage) > 0:
            raise serializers.ValidationError({"error":[errorMessage]})

class AppointmentSerializer(serializers.ModelSerializer):
    isAuthorized = serializers.SerializerMethodField()
    class Meta:
        model = Appointment
        fields = [
            "id",
            "title",
            "doctorName",
            "speciality",
            "date",
            "dateTime",
            "isDone",
            "createdDate",
            "updatedDate",
            "parentProfileId",
            "isAuthorized",
        ]

    def get_isAuthorized(self,instance):
        if isValidData(self,instance.parentProfileId.childId.id):
            return True
    
    def validate(self, data):
        errorMessage = ""
        isCheck = False
        if "parentProfileId" in data:
            isCheck = validateParentId(self,data["parentProfileId"].childId.parentId.id)
        else:
            errorMessage = "parentId", "Parent Id does not exit"
        
        if isCheck == True:
            return data
        
        elif len(errorMessage) > 0:
            raise serializers.ValidationError({"error":[errorMessage]})


#Calender

#Todo
class TodoSerializer(serializers.ModelSerializer):
    isAuthorized = serializers.SerializerMethodField()
    class Meta:
        model = Todo
        fields = [
            "id",
            "title",
            "date",
            "dateTime",
            "isDone",
            "createdDate",
            "updatedDate",
            "parentProfileId",
            "isAuthorized",
        ]

    def get_isAuthorized(self,instance):
        if isValidData(self,instance.parentProfileId.childId.id):
            return True

    def validate(self, data):
        errorMessage = ""
        isCheck = False
        if "parentProfileId" in data:
            isCheck = validateParentId(self,data["parentProfileId"].childId.parentId.id)
        else:
            errorMessage = "parentId", "Parent Id does not exit"
        
        if isCheck == True:
            return data
        
        elif len(errorMessage) > 0:
            raise serializers.ValidationError({"error":[errorMessage]})

