from django.contrib.auth import get_user_model
from django.db import transaction
from ldap3.core.exceptions import LDAPEntryAlreadyExistsResult
from rest_framework import serializers

from uncloud import AMOUNT_DECIMALS, AMOUNT_MAX_DIGITS
from uncloud_pay.models import BillingAddress

from .ungleich_ldap import LdapManager


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = get_user_model()
        read_only_fields = [ 'username', 'balance', 'maximum_credit' ]
        fields =  read_only_fields + [ 'email' ]  # , 'primary_billing_address' ]

    def validate(self, data):
        """
        Ensure that the primary billing address belongs to the user
        """
        # The following is raising exceptions probably, it is WIP somewhere
        # if 'primary_billing_address' in data:
        #     if not data['primary_billing_address'].owner == self.instance:
        #         raise serializers.ValidationError('Invalid data')

        return data

    def update(self, instance, validated_data):
        ldap_manager = LdapManager()
        return_val, _ = ldap_manager.change_user_details(
            instance.username, {'mail': validated_data.get('email')}
        )
        if not return_val:
            raise serializers.ValidationError('Couldn\'t update email')
        instance.email = validated_data.get('email')
        instance.save()
        return instance


class UserRegistrationSerializer(serializers.ModelSerializer):
    class Meta:
        model = get_user_model()
        fields = ['username', 'first_name', 'last_name', 'email', 'password']
        extra_kwargs = {
            'password': {'style': {'input_type': 'password'}},
            'first_name': {'allow_blank': False, 'required': True},
            'last_name': {'allow_blank': False, 'required': True},
            'email': {'allow_blank': False, 'required': True},
        }

    def create(self, validated_data):
        ldap_manager = LdapManager()
        try:
            data = {
                'user': validated_data['username'],
                'password': validated_data['password'],
                'email': validated_data['email'],
                'firstname': validated_data['first_name'],
                'lastname': validated_data['last_name'],
            }
            ldap_manager.create_user(**data)
        except LDAPEntryAlreadyExistsResult:
            raise serializers.ValidationError(
                {'username': ['A user with that username already exists.']}
            )
        else:
            return get_user_model().objects.create_user(**validated_data)


class ImportUserSerializer(serializers.Serializer):
    username = serializers.CharField()
