from django.db import IntegrityError
from django.core.exceptions import ObjectDoesNotExist
from warpauth.models import LdapUser
from warppay.models import UserCredit, UserCreditSerializer, Product, ProductSerializer
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import authentication_classes, permission_classes
from rest_framework.authtoken.models import Token
from django.contrib.auth.models import User
from rest_framework import status

# logging.getLogger('main').info(token.key)

@api_view(['GET', 'PUT'])
#@authentication_classes((TokenAuthentication,))
#@permission_classes((IsAuthenticated,))
def product_list(request):
    if request.method == 'GET':
        products = Product.objects.all()
        serializer = ProductSerializer(products,context={'request': request}, many=True)
        return Response(serializer.data)
    elif request.method == 'PUT':
        return Response()
    return Response()


@api_view(['GET'])
def gen_token(request):
    if request.method == 'GET': 
        token = Token.objects.create(user=User.objects.get(username='api'))    
        return Response(token)
    return Response()

@api_view(['GET', 'PUT'])
#@authentication_classes((TokenAuthentication,))
#@permission_classes((IsAuthenticated,))
def user_list(request, user_id = 0):
    if request.method == 'GET':
        sync_users()
        if not user_id:
            users = UserCredit.objects.all()
            serializer = UserCreditSerializer(users, many=True)
        else:
            user = UserCredit.objects.get(uid=user_id)
            serializer = UserCreditSerializer(user)
        return Response(serializer.data)        
    elif request.method == 'PUT':
        if not user_id:
            return Response(status=status.HTTP_406_NOT_ACCEPTABLE)
            
        sync_users()
        try:
            user = UserCredit.objects.get(uid=user_id)
            if "credit" in request.data:
                user.credit = request.data['credit']
            elif "card_id" in request.data:
                # ToDo: Diskussion: Direkt Karte Ändern?
                try:
                    ldap_user = LdapUser.objects.get(uid=str(request.data['uid']))
                    if not ldap_user.card_id:
                        ldap_user.card_id = request.data['card_id']
                        ldap_user.save()
                    else:
                        return Response(status=status.HTTP_403_FORBIDDEN)
                except:
                    pass
                user.card_id = request.data['card_id']
            user.save();

            return Response(UserCreditSerializer(user).data)
        except UserCredit.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        return Response()
        
    elif request.method == 'POST':
        card_id=""
        if not 'uid' in request.data:
            return Response(status=status.HTTP_406_NOT_ACCEPTABLE)
        if 'card_id' in request.data:
            card_id = request.data['card_id']
        u = UserCredit(uid=request.data['uid'], card_id=card_id, credit=0.0)
        try:
            u.save()
            state=status.HTTP_201_CREATED
        except IntegrityError as e:
            u = UserCredit.objects.get(uid=request.data['uid'])
            state=status.HTTP_409_CONFLICT
        
        serializer = UserCreditSerializer(u)
        return Response(serializer.data, status=state)
    return Response()
    

def sync_users():
    for user in LdapUser.objects.all():
        try:
            u = UserCredit.objects.get(uid=user.uid)
            if user.card_id:
                u.card_id = user.card_id
                u.save()
        except ObjectDoesNotExist:
            u = UserCredit(uid=user.uid, card_id=user.card_id, credit=0.0)
            u.save()