from rest_framework import serializers
from tournaments.models.court import Court
from tournaments.models import Club, LiveMatch, TeamScore, Tournament, CustomUser, Event, Round, GroupStage, Match, TeamRegistration, PlayerRegistration, Purchase, FailedApiCall, DateInterval, Log, DeviceToken, UnregisteredTeam, UnregisteredPlayer
from django.db.utils import IntegrityError
from django.conf import settings

# email
from django.template.loader import render_to_string
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.encoding import force_bytes
from django.core.mail import EmailMessage
from django.contrib.sites.shortcuts import get_current_site

from api.tokens import account_activation_token

from shared.cryptography import encryption_util
from tournaments.models.draw_log import DrawLog
from tournaments.models.enums import UserOrigin

class EncryptedUserField(serializers.Field):
    def to_representation(self, value):
        # Encrypt data when sending it out
        return encryption_util.encrypt_aes_gcm(str(value.id))

    def to_internal_value(self, data):
        # Decrypt data when receiving it
        decrypted_user_id = encryption_util.decrypt_aes_gcm(data)
        user = CustomUser.objects.get(id=decrypted_user_id)
        if decrypted_user_id is None:
            raise serializers.ValidationError("Invalid encrypted data")
        return user

class UserSerializer(serializers.ModelSerializer):

    password = serializers.CharField(write_only=True)

    def create(self, validated_data):

        # print(validated_data)
        umpire_code = None
        if 'umpire_code' in validated_data:
            umpire_code = validated_data['umpire_code']
        phone = None
        if 'phone' in validated_data:
            phone = validated_data['phone']
        licence_id = None
        if 'licence_id' in validated_data:
            licence_id = validated_data['licence_id']
        country = None
        if 'country' in validated_data:
            country = validated_data['country']

        username_lower = validated_data['username'].lower()
        if CustomUser.objects.filter(username__iexact=username_lower) | CustomUser.objects.filter(email__iexact=username_lower):
            raise IntegrityError("Cet identifiant est déjà utilisé. Veuillez en choisir un autre :)")

        user = CustomUser.objects.create_user(
            username=validated_data['username'],
            last_update=validated_data.get('last_update'),
            email=validated_data['email'],
            password=validated_data['password'],
            first_name=validated_data['first_name'],
            last_name=validated_data['last_name'],
            is_active=False,
            umpire_code=umpire_code,
            phone=phone,
            licence_id=licence_id,
            country=country,
            summons_message_body=validated_data.get('summons_message_body'),
            summons_message_signature=validated_data.get('summons_message_signature'),
            summons_available_payment_methods=validated_data.get('summons_available_payment_methods'),
            summons_display_format=validated_data.get('summons_display_format'),
            summons_display_entry_fee=validated_data.get('summons_display_entry_fee'),
            summons_use_full_custom_message=validated_data.get('summons_use_full_custom_message'),
            match_formats_default_duration=validated_data.get('match_formats_default_duration'),
            bracket_match_format_preference=validated_data.get('bracket_match_format_preference'),
            group_stage_match_format_preference=validated_data.get('group_stage_match_format_preference'),
            loser_bracket_match_format_preference=validated_data.get('loser_bracket_match_format_preference'),
            loser_bracket_mode=validated_data.get('loser_bracket_mode'),
            origin=UserOrigin.APP,
        )

        if not settings.DEBUG:
            self.send_email(self.context['request'], user)
        # RegistrationProfile.objects.filter(user=user).send_activation_email()

        return user

    def send_email(self, request, user):

        current_site = get_current_site(request)
        mail_subject = 'Activez votre compte Padel Club !'
        message = render_to_string('tournaments/acc_active_email.html', {
            'user': user,
            'domain': current_site.domain,
            'uid': urlsafe_base64_encode(force_bytes(user.pk)),
            'token': account_activation_token.make_token(user),
        })
        email = EmailMessage(mail_subject, message, to=[user.email])
        email.content_subtype = "html"
        email.send()

    class Meta:
        club_id = serializers.PrimaryKeyRelatedField(queryset=Club.objects.all())
        model = CustomUser
        fields = '__all__' # ['id', 'username', 'password', 'umpire_code', 'clubs', 'phone', 'first_name', 'last_name', 'licence_id']

class CustomUserSerializer(serializers.ModelSerializer): ### the one matching the CustomUser class and used for sync
    class Meta:
        model = CustomUser
        fields = CustomUser.fields_for_update()

class ShortUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = CustomUser
        fields = ['id', 'first_name', 'last_name']

class ClubSerializer(serializers.ModelSerializer):
    class Meta:
        model = Club
        fields = '__all__'

    def create(self, validated_data):
        user = self.context['request'].user
        validated_data['creator'] = user
        return super().create(validated_data)

class TournamentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Tournament
        fields = '__all__'

class EventSerializer(serializers.ModelSerializer):
    class Meta:
        #club_id = serializers.PrimaryKeyRelatedField(queryset=Club.objects.all())
        model = Event
        fields = '__all__'

class RoundSerializer(serializers.ModelSerializer):
    class Meta:
        model = Round
        fields = '__all__'

class GroupStageSerializer(serializers.ModelSerializer):
    class Meta:
        model = GroupStage
        fields = '__all__'

class MatchSerializer(serializers.ModelSerializer):
    class Meta:
        model = Match
        fields = '__all__'

class TeamScoreSerializer(serializers.ModelSerializer):
    class Meta:
        model = TeamScore
        fields = '__all__'

class TeamRegistrationSerializer(serializers.ModelSerializer):
    class Meta:
        model = TeamRegistration
        fields = '__all__'

class PlayerRegistrationSerializer(serializers.ModelSerializer):
    class Meta:
        model = PlayerRegistration
        fields = '__all__'

class PurchaseSerializer(serializers.ModelSerializer):
    user = EncryptedUserField()

    class Meta:
        model = Purchase
        fields = '__all__'

    def create(self, validated_data):
        user = self.context['request'].user
        validated_data['user'] = user
        return super().create(validated_data)


class LiveMatchSerializer(serializers.ModelSerializer):
    class Meta:
        model = LiveMatch
        fields = '__all__' # ['title', 'date'] # Serialize all fields of the model

class CourtSerializer(serializers.ModelSerializer):
    class Meta:
        model = Court
        fields = '__all__'

class DateIntervalSerializer(serializers.ModelSerializer):
    class Meta:
        model = DateInterval
        fields = '__all__'

class FailedApiCallSerializer(serializers.ModelSerializer):
    class Meta:
        model = FailedApiCall
        fields = '__all__'

class LogSerializer(serializers.ModelSerializer):
    class Meta:
        model = Log
        fields = '__all__'

class DeviceTokenSerializer(serializers.ModelSerializer):
    class Meta:
        model = DeviceToken
        fields = '__all__'
        read_only_fields = ['user']

class DrawLogSerializer(serializers.ModelSerializer):
    class Meta:
        model = DrawLog
        fields = '__all__'

class UnregisteredTeamSerializer(serializers.ModelSerializer):
    class Meta:
        # match_id = serializers.PrimaryKeyRelatedField(queryset=Match.objects.all())
        # group_stage_id = serializers.PrimaryKeyRelatedField(queryset=GroupStage.objects.all())
        model = UnregisteredTeam
        fields = '__all__'
        # ['id', 'group_stage_id', 'registration_date', 'call_date', 'bracket_position',
        #     'group_stage_position', 'logo']

class UnregisteredPlayerSerializer(serializers.ModelSerializer):
    class Meta:
        # team_registration_id = serializers.PrimaryKeyRelatedField(queryset=TeamRegistration.objects.all())
        # team_state_id = serializers.PrimaryKeyRelatedField(queryset=TeamState.objects.all())
        model = UnregisteredPlayer
        fields = '__all__'
        # ['id', 'team_registration_id', 'first_name', 'last_name', 'licence_id', 'rank', 'has_paid']
