from django.contrib.auth.decorators import login_required, user_passes_test
from django.http import HttpResponseBadRequest, JsonResponse
from django.utils.timezone import make_aware
from django.views.decorators.http import require_GET, require_POST
from datetime import datetime

from rest_framework.status import HTTP_401_UNAUTHORIZED, HTTP_208_ALREADY_REPORTED, HTTP_403_FORBIDDEN, HTTP_200_OK

from tombola.models import *
import django.apps
import pytz

from tombola.serializers import PasseportSerializer, TicketSerializer, HourRangeSerializer, PartenaireSerializer, \
    UserSerializer


@login_required
@require_POST
@user_passes_test(lambda u: u.is_badge or u.is_partner or u.is_coord)
def scan(request):
    raffle = RaffleDraw.objects.get(is_active=True)
    uid = request.POST.get('uid')

    # on récupère l'heure
    scan_datetime = make_aware(datetime.now())

    try:
        passeport = Passeport.objects.get(unique_id=uid, raffle=raffle)
    except Passeport.DoesNotExist:
        try:
            hour_range = HourRange.objects.get(start__lte=scan_datetime,
                                               end__gte=scan_datetime)
        except HourRange.DoesNotExist:
            hour_range = None

        return JsonResponse({'message': 'Passeport invalide. Merci de contacter un des organisateurs.',
                             'context': {
                                'uid': uid,
                                'raffle': raffle.id,
                                'in_range': 1 if hour_range else 0,
                             }},
                            status=HTTP_401_UNAUTHORIZED)  # Mauvais QR code


    context = {
        'passeport': PasseportSerializer(passeport).data,
        'hour_tickets': TicketSerializer(Ticket.objects.filter(passeport=passeport, hour_range__isnull=False, partner__isnull=True), many=True).data,
        'partner_tickets': TicketSerializer(Ticket.objects.filter(passeport=passeport, partner__isnull=False, hour_range__isnull=True), many=True).data,
        'hour_ranges': HourRangeSerializer(HourRange.objects.filter(raffle=raffle), many=True).data,
        'partners': PartenaireSerializer(Partenaire.objects.filter(raffle=raffle), many=True).data,
        'user': UserSerializer(User.objects.get(pk=request.user.pk)).data,
        'nb_passeports_scannes': 0,
        'nb_total_passeports': Passeport.objects.filter(raffle=raffle).count(),
    }

    if request.user.is_partner:
            try:
                partner = Partenaire.objects.get( user = request.user , raffle = raffle)
                Ticket.objects.get(passeport=passeport, partner=partner)
            except Ticket.DoesNotExist:
                ticket = Ticket(passeport=passeport, partner=partner).save()
                context['partner_tickets'].append(TicketSerializer(ticket).data)
            else:
                return JsonResponse({'message': 'Passeport déjà scanné chez le partenaire !',
                                     'context': context},
                            status=HTTP_208_ALREADY_REPORTED)
    elif request.user.is_badge:
        try:
            hour_range = HourRange.objects.get(start__lte=scan_datetime,
                                               end__gte=scan_datetime)
            context['nb_passeports_scannes'] = Ticket.objects.filter(passeport__raffle=raffle, hour_range=hour_range).count()
        except HourRange.DoesNotExist:
            return JsonResponse({'message': "Scan du passeport non autorisé hors des plages horaires définies (1er quart d'heure de chaque heure)",
                                 'context': context},
                                status=HTTP_403_FORBIDDEN)  # En dehors de la plage horaire autorisée

        try:
            Ticket.objects.get(passeport=passeport,
                               hour_range=hour_range)
        except Ticket.DoesNotExist:
            Ticket(passeport=passeport,
                   hour_range=hour_range,
                   ).save()
            context['nb_passeports_scannes'] += 1
        else:
            return JsonResponse({'message': 'Passeport déjà scanné durant cette plage horaire !',
                                 'context': context},
                                status=HTTP_208_ALREADY_REPORTED)
    elif request.user.is_coord:
        outputs = []
        print(request.POST)
        for id in  request.POST.getlist('ranges_to_badge[]'):
            print('here')
            hour_range = HourRange.objects.get(id=int(id))
            try:
                Ticket.objects.get(passeport=passeport, hour_range=hour_range)
            except Ticket.DoesNotExist:
                Ticket(passeport=passeport, hour_range=hour_range).save()
                outputs.append({'hour_range': HourRangeSerializer(hour_range).data,
                                'message': 'Créneau horaire validé',
                                'status': 'success'})
            else:
                outputs.append({'hour_range': HourRangeSerializer(hour_range).data,
                                'message': 'Créneau horaire déjà validé',
                                'status': 'already'})

        context['staff_output'] = outputs
        return JsonResponse({'message': "Scan validé !",
                             'context': context}, status=HTTP_200_OK)

    return JsonResponse({'message': "Scan validé !",
                         'context': context}, status=HTTP_200_OK)