import random
from rest_framework import viewsets, status
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser, AllowAny

from apps.attendance.models import RegisteredMember
from .models import RaffleEvent, RaffleEntry
from .serializers import RaffleEventSerializer, RaffleEntrySerializer


def _get_client_ip(request):
    xff = request.META.get('HTTP_X_FORWARDED_FOR')
    return xff.split(',')[0].strip() if xff else request.META.get('REMOTE_ADDR', 'unknown')


class RaffleEventViewSet(viewsets.ModelViewSet):
    queryset = RaffleEvent.objects.all()
    serializer_class = RaffleEventSerializer
    permission_classes = [IsAdminUser]


class PublicActiveRaffleEventView(APIView):
    """Returns the currently active (non-archived) raffle event."""
    permission_classes = [AllowAny]

    def get(self, request):
        event = RaffleEvent.objects.filter(is_active=True, is_archived=False).first()
        if not event:
            return Response({'detail': 'No active raffle event.'}, status=status.HTTP_404_NOT_FOUND)
        return Response({
            'id': event.id,
            'name': event.name,
            'slug': event.slug,
            'description': event.description,
            'entry_count': event.entry_count,
        })


class PublicRaffleRegisterView(APIView):
    """
    Public endpoint — records a member's entry in the raffle.
    Looks up the member's name from RegisteredMember if available.
    Deduplicates: one entry per registration_code per event.
    """
    permission_classes = [AllowAny]

    def post(self, request):
        registration_code = (request.data.get('registration_code') or '').strip().upper()
        event_id = request.data.get('event_id')

        if not registration_code or not event_id:
            return Response(
                {'success': False, 'message': 'Registration code and event are required.'},
                status=status.HTTP_400_BAD_REQUEST,
            )

        try:
            event = RaffleEvent.objects.get(id=event_id, is_active=True, is_archived=False)
        except RaffleEvent.DoesNotExist:
            return Response(
                {'success': False, 'message': 'Raffle is not currently active.'},
                status=status.HTTP_404_NOT_FOUND,
            )

        full_name = ''
        try:
            member = RegisteredMember.objects.get(registration_code__iexact=registration_code)
            full_name = member.full_name
        except RegisteredMember.DoesNotExist:
            return Response(
                {'success': False, 'message': 'Registration code not found. Please check your code and try again.', 'code': 'NOT_FOUND'},
                status=status.HTTP_404_NOT_FOUND,
            )

        entry, created = RaffleEntry.objects.get_or_create(
            event=event,
            registration_code=registration_code,
            defaults={
                'full_name': full_name,
                'ip_address': _get_client_ip(request),
            },
        )

        if not created:
            return Response({
                'success': True,
                'already_entered': True,
                'full_name': entry.full_name or registration_code,
                'message': f'You are already in the draw, {entry.full_name or registration_code}!',
            })

        return Response({
            'success': True,
            'already_entered': False,
            'full_name': full_name or registration_code,
            'message': f'You\'re in the draw, {full_name or registration_code}! Good luck!',
        }, status=status.HTTP_201_CREATED)


class RaffleEntriesView(APIView):
    """Admin — list all entries for the active raffle event."""
    permission_classes = [IsAdminUser]

    def get(self, request):
        event_id = request.query_params.get('event_id')
        if event_id:
            entries = RaffleEntry.objects.filter(event_id=event_id).order_by('-scanned_at')
        else:
            event = RaffleEvent.objects.filter(is_active=True, is_archived=False).first()
            entries = RaffleEntry.objects.filter(event=event).order_by('-scanned_at') if event else RaffleEntry.objects.none()
        return Response(RaffleEntrySerializer(entries, many=True).data)


class RafflePickWinnerView(APIView):
    """Admin — pick a random winner from the active raffle event's entries."""
    permission_classes = [IsAdminUser]

    def post(self, request):
        event_id = request.data.get('event_id')
        try:
            if event_id:
                event = RaffleEvent.objects.get(id=event_id)
            else:
                event = RaffleEvent.objects.filter(is_active=True, is_archived=False).first()
                if not event:
                    return Response({'success': False, 'message': 'No active raffle event.'}, status=status.HTTP_404_NOT_FOUND)
        except RaffleEvent.DoesNotExist:
            return Response({'success': False, 'message': 'Raffle event not found.'}, status=status.HTTP_404_NOT_FOUND)

        entries = list(event.entries.all())
        if not entries:
            return Response({'success': False, 'message': 'No entries in this raffle yet.'}, status=status.HTTP_400_BAD_REQUEST)

        winner = random.choice(entries)
        return Response({
            'success': True,
            'winner': {
                'full_name': winner.full_name or winner.registration_code,
                'registration_code': winner.registration_code,
                'scanned_at': winner.scanned_at,
            },
            'total_entries': len(entries),
        })
