from rest_framework import serializers
from datetime import date
import random
import string
from .models import User, UserImage, UserInterest, UserLanguage, Enquiry, UserBlock, UserFavourite, UserReport, Plan, UserTransaction
from master.models import Master, AppSetting
from django.db import transaction


class AlluserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'

class SendOtpSerializer(serializers.Serializer):
    country_code = serializers.CharField(max_length=20)
    mobile = serializers.CharField(max_length=20)

class VerifyOtpSerializer(serializers.Serializer):
    country_code = serializers.CharField(max_length=20)
    mobile = serializers.CharField(max_length=20)
    otp = serializers.CharField(max_length=10)

class UserInterestSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserInterest
        fields = ['user', 'interest']

class UserLanguageSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserLanguage
        fields = ['user', 'language']

class UserImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserImage
        fields = ['id', 'user', 'image']

class UserRegistrationSerializer(serializers.ModelSerializer):
    referral_code = serializers.CharField(read_only=True)
    referred_by_code = serializers.CharField(write_only=True, required=False, allow_blank=True)

    class Meta:
        model = User
        fields = [
            'id','gender', 'display_name', 'real_name', 'email', 'country_code', 'mobile', 'dob',
            'about', 'language_id', 'referral_code', 'call_type', 'referred_by_code'
        ]

    def generate_referral_code(self):
        prefix = "harmoni"
        suffix = ''.join(random.choices(string.digits, k=8))
        return prefix + suffix

    def calculate_age(self, dob):
        today = date.today()
        return today.year - dob.year - ((today.month, today.day) < (dob.month, dob.day))

    def assign_default_image(self, gender):
        if gender == 1:
            default_images = Master.objects.filter(type=8, status=True)
        elif gender == 2:
            default_images = Master.objects.filter(type=9, status=True)
        else:
            default_images = []
        if default_images:
            return random.choice(default_images).value1
        return None

    def create(self, validated_data):
        referred_by_code = self.initial_data.get('referred_by_code')
        validated_data.pop('referred_by_code', None)

        dob = validated_data.get('dob')
        age = self.calculate_age(dob)
        validated_data['age'] = age

        gender = validated_data.get('gender')
        default_image = self.assign_default_image(gender)
        validated_data['default_image'] = default_image
        validated_data['display_image'] = default_image

        if gender == 1:
            validated_data['status'] = 1
            validated_data['admin_status'] = 1

        validated_data['referral_code'] = self.generate_referral_code()

        referer = None
        if referred_by_code:
            try:
                referer = User.objects.get(referral_code=referred_by_code)
                validated_data['referer_id'] = referer
            except User.DoesNotExist:
                raise serializers.ValidationError({"message": "Invalid referral code."})

        with transaction.atomic():
            user = super().create(validated_data)

            if referer and gender == 1:

                referred_to_coins = AppSetting.objects.filter(code='referred_to_coins').first()
                referer_coins = AppSetting.objects.filter(code='referer_coins').first()

                if referred_to_coins:
                    user.available_coins += int(referred_to_coins.value)
                    user.save(update_fields=['available_coins'])

                if referer.gender == 1 and referer_coins:
                    referer.available_coins += int(referer_coins.value)
                    referer.save(update_fields=['available_coins'])

            elif gender == 2:

                pass


        return user


class UserDisplayImageUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['display_image']

class UserImageUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['default_image', 'profile_image', 'display_image']

class UpdateLanguageSerializer(serializers.ModelSerializer):
    language_id = serializers.PrimaryKeyRelatedField(queryset=Master.objects.all())

    class Meta:
        model = User
        fields = ['language_id']


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = [
            'id', 'country_code', 'mobile', 'gender', 'display_name', 'referral_code',
            'real_name', 'about', 'email', 'dob', 'age', 'language_id', 'display_image',
            'default_image', 'profile_image', 'available_coins', 'available_minutes', 'status',
            'user_type', 'admin_status', 'call_type', 'deleted_at', 'first_offer_used','referral_min_used'
        ]

class FemalrequestSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = [
            'id', 'country_code', 'mobile', 'gender', 'display_name',
            'real_name', 'about', 'email', 'dob', 'age', 'language_id', 'display_image',
            'default_image', 'profile_image', 'available_coins', 'available_minutes', 'status',
            'user_type', 'admin_status', 'created_at'
        ]
class EditUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = [
            'country_code', 'mobile', 'gender', 'display_name',
            'real_name', 'about', 'email', 'dob', 'language_id',
            'default_image', 'profile_image', 'available_coins', 'available_minutes', 'status',
        ]

class ProfileupdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = [
            'country_code', 'mobile', 'gender', 'display_name',
            'real_name', 'about', 'email', 'dob', 'status', 'call_type'
        ]
    
    def calculate_age(self, dob):
        """Calculate age based on the date of birth."""
        today = date.today()
        age = today.year - dob.year - ((today.month, today.day) < (dob.month, dob.day))
        return age
    
    def update(self, instance, validated_data):
        dob = validated_data.get('dob', instance.dob)
        if dob:
            instance.age = self.calculate_age(dob)

        for attr, value in validated_data.items():
            setattr(instance, attr, value)

        instance.save()
        return instance


class UserStatusUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['status', 'admin_status']

class FemaleVerifySerializer(serializers.ModelSerializer):
    id = serializers.IntegerField()

    class Meta:
        model = User
        fields = ['id', 'admin_status']


class UsertypeUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['user_type']
        
class EnquirySerializer(serializers.ModelSerializer):
    class Meta:
        model = Enquiry
        fields = ['id', 'user', 'subject', 'description', 'admin_description', 'status', 'created_at', 'updated_at']
        read_only_fields = ['id', 'created_at', 'updated_at']

class UserEnquirySerializer(serializers.ModelSerializer):
    class Meta:
        model = Enquiry
        fields = ['id', 'user', 'subject', 'description', 'status', 'created_at', 'updated_at']
        read_only_fields = ['id', 'created_at', 'updated_at']

class UserBlockSerializer(serializers.ModelSerializer):
    blocked_user_name = serializers.CharField(source='blocked_user.display_name', read_only=True)
    blocked_user_ai_image = serializers.CharField(source='blocked_user.default_image', read_only=True)
    blocked_user_profile_image = serializers.CharField(source='blocked_user.profile_image', read_only=True)
    blocked_user_display_image = serializers.CharField(source='blocked_user.display_image', read_only=True)
    created_at = serializers.DateTimeField(read_only=True)

    class Meta:
        model = UserBlock
        fields = ['id', 'user', 'blocked_user', 'blocked_user_name', 'blocked_user_ai_image', 'blocked_user_profile_image', 'blocked_user_display_image','created_at']

    def validate(self, attrs):
        user = attrs['user']
        blocked_user = attrs['blocked_user']

        if user == blocked_user:
            raise serializers.ValidationError("User cannot block themselves.")

        if UserBlock.objects.filter(user=user, blocked_user=blocked_user).exists():
            raise serializers.ValidationError("This user is already blocked.")

        return attrs


class UserFavouriteSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserFavourite
        fields = ['id', 'user', 'favourite_user']

    def validate(self, attrs):
        user = attrs['user']
        favourite_user = attrs['favourite_user']

        if user == favourite_user:
            raise serializers.ValidationError("User cannot favourite themselves.")

        if UserFavourite.objects.filter(user=user, favourite_user=favourite_user).exists():
            raise serializers.ValidationError("This user is already marked as favourite.")

        return attrs
    

class UsergetInterestSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(source='interest.id', read_only=True)
    name = serializers.CharField(source='interest.name', read_only=True)
    value1 = serializers.CharField(source='interest.value1', read_only=True)

    class Meta:
        model = UserInterest
        fields = ['id', 'name', 'value1']


class UsergetLanguageSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(source='language.id', read_only=True)
    name = serializers.CharField(source='language.name', read_only=True)
    value1 = serializers.CharField(source='language.value1', read_only=True)

    class Meta:
        model = UserLanguage
        fields = ['id', 'name', 'value1']

class UserReportSerializer(serializers.ModelSerializer):

    reported_user_name = serializers.CharField(source='reported_user.display_name', read_only=True)
    reported_user_ai_image = serializers.CharField(source='reported_user.default_image', read_only=True)
    reported_user_profile_image = serializers.CharField(source='reported_user.profile_image', read_only=True)
    reported_user_display_image = serializers.CharField(source='reported_user.display_image', read_only=True)
    created_at = serializers.DateTimeField(read_only=True)
    class Meta:
        model = UserReport
        fields = ['id', 'user', 'reported_user','reported_user_name', 'reported_user_ai_image', 'reported_user_profile_image', 'reported_user_display_image', 'description', 'created_at']

class UserReportbySerializer(serializers.ModelSerializer):

    reported_user_name = serializers.CharField(source='user.display_name', read_only=True)
    reported_user_ai_image = serializers.CharField(source='user.default_image', read_only=True)
    reported_user_profile_image = serializers.CharField(source='user.profile_image', read_only=True)
    created_at = serializers.DateTimeField(read_only=True)
    class Meta:
        model = UserReport
        fields = ['id', 'user', 'reported_user','reported_user_name', 'reported_user_ai_image', 'reported_user_profile_image', 'description', 'created_at']


class PlanSerializer(serializers.ModelSerializer):
    class Meta:
        model = Plan
        fields = '__all__'


class UserTransactionSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserTransaction
        fields = '__all__'