from django.shortcuts import render, redirect, get_object_or_404
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView, View, TemplateView
from django.contrib import messages
from django.urls import reverse_lazy, reverse
from django.http import JsonResponse
from django.db.models import Count
from django.views.decorators.http import require_POST
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt
from django.utils import timezone

from .models import TShirtType, TShirtSize, ApparelRequest
from .forms import ApparelRequestForm, VerificationForm
from attendance.models import RegisteredUser

class ApparelFormView(View):
    template_name = 'apparel/apparel_form.html'
    
    def get(self, request):
        form = ApparelRequestForm()
        context = {
            'form': form,
        }
        return render(request, self.template_name, context)
    
    def post(self, request):
        form = ApparelRequestForm(request.POST)
        if form.is_valid():
            apparel_request = form.save(commit=False)
            
            # Explicitly link to registered user based on registration code
            registration_code = form.cleaned_data['registration_code']
            try:
                user = RegisteredUser.objects.get(registration_code=registration_code)
                
                # Check if this user already has an apparel request
                existing_request = ApparelRequest.objects.filter(registered_user=user).first()
                if existing_request:
                    # Update the existing request instead of creating a new one
                    existing_request.tshirt_type = form.cleaned_data['tshirt_type']
                    existing_request.tshirt_size = form.cleaned_data['tshirt_size']
                    existing_request.additional_notes = form.cleaned_data['additional_notes']
                    existing_request.save()
                    messages.success(request, 'Your apparel request has been updated successfully!')
                else:
                    # Create a new request
                    apparel_request.registered_user = user
                    apparel_request.event_name = user.event_name
                    apparel_request.save()
                    messages.success(request, 'Your apparel request has been submitted successfully!')
                
                return redirect('apparel:thank_you')
            except RegisteredUser.DoesNotExist:
                form.add_error('registration_code', 'Invalid registration code. Please check and try again.')

        
        context = {
            'form': form,
        }
        return render(request, self.template_name, context)

class VerifyRegistrationCodeView(View):
    @method_decorator(csrf_exempt)
    def dispatch(self, *args, **kwargs):
        return super().dispatch(*args, **kwargs)
    
    def post(self, request):
        form = VerificationForm(request.POST)
        if form.is_valid():
            registration_code = form.cleaned_data['registration_code']
            try:
                user = RegisteredUser.objects.get(registration_code=registration_code)
                
                # Check if user already has an apparel request
                existing_request = ApparelRequest.objects.filter(registered_user=user).first()
                has_existing_request = existing_request is not None
                
                return JsonResponse({
                    'success': True,
                    'user': {
                        'full_name': user.full_name,
                        'email': user.email,
                        'event_name': user.event_name if hasattr(user, 'event_name') else '',
                        'has_existing_request': has_existing_request,
                        'existing_request': {
                            'tshirt_type': existing_request.tshirt_type.id if existing_request else None,
                            'tshirt_size': existing_request.tshirt_size.id if existing_request else None,
                            'additional_notes': existing_request.additional_notes if existing_request else ''
                        } if has_existing_request else None
                    }
                })
            except RegisteredUser.DoesNotExist:
                return JsonResponse({
                    'success': False,
                    'message': 'Invalid registration code. Please check and try again.'
                })
        return JsonResponse({
            'success': False,
            'message': 'Please provide a valid registration code.'
        })

class ThankYouView(TemplateView):
    template_name = 'apparel/thank_you.html'

from django.contrib.admin.views.decorators import staff_member_required
from django.utils.decorators import method_decorator

@method_decorator(login_required, name='dispatch')
@method_decorator(staff_member_required, name='dispatch')
class DashboardView(View):
    template_name = 'apparel/dashboard.html'
    
    def get(self, request):
        # Get counts by type and size
        type_stats = ApparelRequest.objects.values('tshirt_type__name').annotate(count=Count('id')).order_by('tshirt_type__name')
        size_stats = ApparelRequest.objects.values('tshirt_size__name').annotate(count=Count('id')).order_by('tshirt_size__name')
        
        # Get total requests and fulfillment stats
        total_requests = ApparelRequest.objects.count()
        fulfilled_requests = ApparelRequest.objects.filter(is_fulfilled=True).count()
        pending_requests = total_requests - fulfilled_requests
        fulfillment_rate = (fulfilled_requests / total_requests * 100) if total_requests > 0 else 0
        
        # Get recent requests
        recent_requests = ApparelRequest.objects.select_related('tshirt_type', 'tshirt_size', 'registered_user').order_by('-created_at')[:10]
        
        context = {
            'total_requests': total_requests,
            'fulfilled_requests': fulfilled_requests,
            'pending_requests': pending_requests,
            'fulfillment_rate': fulfillment_rate,
            'type_stats': type_stats,
            'size_stats': size_stats,
            'recent_requests': recent_requests,
        }
        return render(request, self.template_name, context)

@method_decorator(login_required, name='dispatch')
@method_decorator(staff_member_required, name='dispatch')
class ApparelRequestListView(ListView):
    model = ApparelRequest
    template_name = 'apparel/apparel_list.html'
    context_object_name = 'requests'
    paginate_by = 20
    
    def get_queryset(self):
        queryset = super().get_queryset()
        
        # Apply filters if provided in GET parameters
        tshirt_type = self.request.GET.get('tshirt_type')
        tshirt_size = self.request.GET.get('tshirt_size')
        is_fulfilled = self.request.GET.get('is_fulfilled')
        event_name = self.request.GET.get('event_name')
        
        if tshirt_type:
            queryset = queryset.filter(tshirt_type__name=tshirt_type)
        if tshirt_size:
            queryset = queryset.filter(tshirt_size__name=tshirt_size)
        if is_fulfilled:
            queryset = queryset.filter(is_fulfilled=(is_fulfilled == 'True'))
        if event_name:
            queryset = queryset.filter(event_name=event_name)
            
        return queryset
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        
        # Add filter options to context
        context['tshirt_types'] = TShirtType.objects.all()
        context['tshirt_sizes'] = TShirtSize.objects.all()
        context['event_names'] = ApparelRequest.objects.values_list('event_name', flat=True).distinct()
        
        return context


@login_required
@staff_member_required
def scanner(request):
    """View for scanning apparel collection"""
    context = {}
    return render(request, 'apparel/scanner.html', context)


@csrf_exempt
@login_required
@staff_member_required
def scan_barcode(request):
    """Process barcode scan for apparel collection"""
    import logging
    logger = logging.getLogger(__name__)
    
    if request.method == 'POST':
        registration_code = request.POST.get('registration_code', '')
        logger.info(f'Received scan request for code: {registration_code}')
        
        if not registration_code:
            logger.warning('No registration code provided')
            return JsonResponse({'success': False, 'message': 'Registration code is required'})
        
        try:
            # First check if the user exists
            user = RegisteredUser.objects.get(registration_code=registration_code)
            logger.info(f'Found user: {user.full_name}, payment status: {user.payment_status}')
            
            # Check if the user has a payment status of PAID (case-insensitive)
            if user.payment_status.strip().upper() != 'PAID':
                logger.warning(f'User {user.full_name} payment status is {user.payment_status}, not PAID')
                return JsonResponse({
                    'success': False, 
                    'message': f'User payment status is {user.payment_status}. Only PAID users can collect apparel.'
                })
            
            # Check if the user has requested apparel
            try:
                apparel_request = ApparelRequest.objects.get(registered_user=user)
                logger.info(f'Found apparel request: Type: {apparel_request.tshirt_type.name}, Size: {apparel_request.tshirt_size.name}, Fulfilled: {apparel_request.is_fulfilled}')
                
                # Check if the apparel has already been collected
                if apparel_request.is_fulfilled:
                    # Apparel already collected
                    logger.info(f'User {user.full_name} has already collected their apparel')
                    return JsonResponse({
                        'success': True, 
                        'already_collected': True,
                        'message': 'User has already collected their apparel',
                        'user': {
                            'full_name': user.full_name,
                            'email': user.email,
                            'registration_code': user.registration_code,
                            'event_name': apparel_request.event_name,
                            'tshirt_type': apparel_request.tshirt_type.name,
                            'tshirt_size': apparel_request.tshirt_size.name,
                            'payment_status': user.payment_status,
                        }
                    })
                else:
                    # Mark the apparel as collected
                    logger.info(f'Marking apparel as collected for user {user.full_name}')
                    apparel_request.is_fulfilled = True
                    apparel_request.updated_at = timezone.now()
                    apparel_request.save()
                    
                    return JsonResponse({
                        'success': True, 
                        'already_collected': False,
                        'message': 'Apparel collection recorded successfully',
                        'user': {
                            'full_name': user.full_name,
                            'email': user.email,
                            'registration_code': user.registration_code,
                            'event_name': apparel_request.event_name,
                            'tshirt_type': apparel_request.tshirt_type.name,
                            'tshirt_size': apparel_request.tshirt_size.name,
                            'payment_status': user.payment_status,
                        }
                    })
            except ApparelRequest.DoesNotExist:
                logger.warning(f'User {user.full_name} has not requested any apparel')
                return JsonResponse({
                    'success': False, 
                    'message': 'User has not requested any apparel'
                })
                
        except RegisteredUser.DoesNotExist:
            logger.warning(f'User with registration code {registration_code} not found')
            return JsonResponse({'success': False, 'message': 'User not found'})
    
    logger.warning('Invalid request method')
    return JsonResponse({'success': False, 'message': 'Invalid request method'})
