import json
from datetime import timedelta
from django.shortcuts import render, get_object_or_404, redirect
from django.views.decorators.http import require_http_methods
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth import authenticate, login, logout
from django.http import JsonResponse
from django.core.validators import validate_email
from django.core.exceptions import ValidationError
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.utils import timezone
from twilio.rest import Client
from decouple import config
from django.db.models import Q
from .models import Accreditation, RSVP
from .utils import send_registration_confirmation_email, send_birthday_invitation_email
import logging

# Send WhatsApp Message
account_sid = config('TWILIO_ACCOUNT_SID')
auth_token = config('TWILIO_AUTH_TOKEN')
messaging_service_sid = "MG018ee670d457100f1e059c498af63ce3"
client = Client(account_sid, auth_token)

logger = logging.getLogger(__name__)

# Index
def index(request):
    return render(request, 'index.html')

# Accreditation
def accreditation(request):
    return render(request, 'accreditation.html')

def search_guests(request):
    """Search for guests by first name or last name prefix"""
    if request.method == 'GET':
        query = request.GET.get('q', '').strip()

        if len(query) >= 2:
            rsvp_results = RSVP.objects.filter(name__icontains=query).order_by('name')

            ticket_list = []

            # Get today's accreditations
            today = timezone.now().date()
            tomorrow = today + timezone.timedelta(days=1)
            rsvp_accreditations = set(Accreditation.objects.filter(
                rsvp__in=rsvp_results,
                date__gte=today,
                date__lt=tomorrow,
                is_accredited=True
            ).values_list('rsvp_id', flat=True))

            # Process RSVP results
            for rsvp in rsvp_results:
                ticket_list.append({
                    'id': rsvp.id,
                    'name': rsvp.name,
                    'email': rsvp.email,
                    'phone': rsvp.phone,
                    'type': 'rsvp',
                    'total_quantity': 1,
                    'is_accredited': rsvp.id in rsvp_accreditations,
                })

            return JsonResponse({'tickets': ticket_list})
        else:
            return JsonResponse({'tickets': []})

    return JsonResponse({'status': 405, 'message': 'Method Not Allowed!'})

@csrf_exempt
def check_in(request):
    if request.method == 'POST':
        name = request.POST.get('name')
        quantity_str = request.POST.get('quantity')
        accredit_all = request.POST.get('accredit_all') == 'true'

        if not name:
            return JsonResponse({'status': 400, 'message': 'Please provide ticket name'})
        
        # Try to find RSVP by name or ticket number
        rsvp = RSVP.objects.filter(
            Q(name__iexact=name) | Q(ticket_number__iexact=name)
        ).first()

        if not rsvp:
            return JsonResponse({'status': 404, 'message': 'RSVP not found'})

        # Handle RSVP check-in
        if rsvp:
            # Check if already accredited today
            today = timezone.now().date()
            tomorrow = today + timedelta(days=1)
            existing_accreditation = Accreditation.objects.filter(
                rsvp=rsvp, 
                is_accredited=True,
                date__gte=today,
                date__lt=tomorrow
            ).first()
            
            if quantity_str:
                # Process check-in with quantity
                if existing_accreditation:
                    return JsonResponse({'status': 400, 'message': 'This RSVP has already been checked in today'})

                # Check in the RSVP
                Accreditation.objects.create(
                    rsvp=rsvp,
                    is_accredited=True
                )

                return JsonResponse({
                    'status': 200,
                    'message': 'RSVP checked in successfully',
                    'guest': {
                        'name': rsvp.name,
                        'email': rsvp.email,
                        'phone': rsvp.phone,
                        'accredited_quantity': 1,
                        'total_quantity': 1,
                        'type': 'rsvp'
                    }
                })
            else:
                # Return ticket info for modal
                is_accredited_today = existing_accreditation is not None
                ticket_info = {
                    'name': rsvp.name,
                    'email': rsvp.email,
                    'phone': rsvp.phone,
                    'accredited_quantity': 1 if is_accredited_today else 0,
                    'total_quantity': 1,
                    'remaining_quantity': 0 if is_accredited_today else 1,
                    'current_date': timezone.now().strftime('%Y-%m-%d'),
                    'type': 'rsvp'
                }
                return JsonResponse({'status': 200, 'ticket': ticket_info})

    return JsonResponse({'status': 405, 'message': 'Method not allowed'})

# RSVP
def rsvp(request):
    return render(request, 'rsvp.html')

# RSVP Submit
@require_http_methods(["POST"])
def rsvp_submit(request):
    if request.method == 'POST':
        first_name = request.POST.get('first_name', '').strip()
        last_name = request.POST.get('last_name', '').strip()
        email = request.POST.get('email', '').strip()
        phone = request.POST.get('phone', '').strip()

        # Validate required fields
        if not all([first_name, email, phone]):
            return JsonResponse({
                'success': False,
                'message': 'First name, email, and phone are required'
            }, status=400)
                            
        if RSVP.objects.filter(email=email).exists():
            return JsonResponse({
                'success': False,
                'message': 'Email is already registered'
            }, status=400)

        # Validate email format
        try:
            validate_email(email)
        except ValidationError:
            return JsonResponse({
                'success': False,
                'message': 'Please enter a valid email address'
            }, status=400)

        # Create RSVP record
        rsvp = RSVP(
            name = f"{first_name} {last_name}",
            first_name=first_name,
            last_name=last_name,
            email=email,
            phone=phone,
        )
        rsvp.save()
        try:
            if rsvp.email:
                send_registration_confirmation_email(rsvp)
            
            if rsvp.phone:
                content_sid = "HX994e10d7bfa54ccd1b83de4e497b5e15"
                to_number = f"whatsapp:{rsvp.phone}"
        
                content_variables = json.dumps({
                    "name": rsvp.name,
                })
                try:
                    client.messages.create(
                        content_sid=content_sid,
                        to=to_number,
                        from_=messaging_service_sid,
                        content_variables=content_variables
                    )
                except Exception as e:
                    logger.error(f"Error sending WhatsApp message: {str(e)}")
                                
            return JsonResponse({
                'success': True,
                'message': 'Thank you for your RSVP!'
            })

        except Exception as e:
            logger.error(f"Error submitting RSVP: {str(e)}")
            return JsonResponse({
                'success': False,
                'message': str(e)
            }, status=400)

    return JsonResponse({'status': False, 'message': 'Method not allowed'}, status=405)

# Send QR Code
@login_required
def send_qr_code(request):
    if request.method == 'POST':
        rsvp_id = request.POST.get('rsvp_id')

        if not rsvp_id:
            return JsonResponse({'status': 400, 'message': "RSVP ID is required"}, status=400)

        try:
            rsvp = RSVP.objects.get(pk=rsvp_id)
            qr_code_url = f"https://oso80.wristbandsng.com/oso/media/access/{rsvp.ticket_number}.png"
            
            # Birthday Invitation
            try:
                if rsvp.email:
                    send_birthday_invitation_email(rsvp)
            
                if rsvp.phone:
                    content_sid = ""
                    to_number = f"whatsapp:{rsvp.phone}"
        
                content_variables = json.dumps({
                    "name": rsvp.name,
                    "qr_code_url": qr_code_url,
                })
                try:
                    msg = client.messages.create(
                        content_sid=content_sid,
                        to=to_number,
                        from_=messaging_service_sid,
                        content_variables=content_variables
                    )
                except Exception as e:
                    logger.error(f"Error sending WhatsApp message: {str(e)}")
                    
                rsvp.is_sent = True
                rsvp.message_sid = msg.sid
                rsvp.save()
                
                return JsonResponse({'status': 200, 'message': 'QR code sent successfully!'})

            except Exception as e:
                logger.error(f"Error submitting RSVP: {str(e)}")
                return JsonResponse({'status': 400, 'message': str(e)})
            
        except RSVP.DoesNotExist:
            return JsonResponse(
                {'status': 404, 'message': 'RSVP not found'},
                status=404
            )
        except Exception as e:
            return JsonResponse(
                {'status': 500, 'message': f'Error sending QR code: {str(e)}'},
                status=500
            )
    return JsonResponse(
        {'status': 405, 'message': 'Method not allowed'},
        status=405
    )

# Send Bulk QR Codes
@login_required
@csrf_exempt
def send_bulk_qr_codes(request):
    if request.method == 'POST':
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({'status': 400, 'message': "Invalid JSON data"}, status=400)
        rsvp_ids = data.get('rsvp_ids', [])

        if not rsvp_ids:
            return JsonResponse({'status': 400, 'message': "No RSVP IDs provided"}, status=400)

        sent_count = 0
        failed_rsvps = []

        for rsvp_id in rsvp_ids:
            try:
                rsvp = RSVP.objects.get(pk=rsvp_id)
                qr_code_url = f"https://oso80.wristbandsng.com/oso/media/access/{rsvp.ticket_number}.png"

                # Birthday Invitation
              
                try:
                    if rsvp.email:
                        send_birthday_invitation_email(rsvp)
                
                    if rsvp.phone:
                        content_sid = ""
                        to_number = f"whatsapp:{rsvp.phone}"
            
                    content_variables = json.dumps({
                        "name": rsvp.name,
                        "qr_code_url": qr_code_url,
                    })
                    try:
                        msg = client.messages.create(
                            content_sid=content_sid,
                            to=to_number,
                            from_=messaging_service_sid,
                            content_variables=content_variables
                        )
                    except Exception as e:
                        logger.error(f"Error sending WhatsApp message: {str(e)}")
                    
                    rsvp.is_sent = True
                    rsvp.message_sid = msg.sid
                    rsvp.save()
                    sent_count += 1
                    
                    return JsonResponse({'status': 200, 'message': 'QR code sent successfully!'})

                except Exception as e:
                    logger.error(f"Error submitting RSVP: {str(e)}")
                    failed_rsvps.append(f"RSVP ID {rsvp_id} (error: {str(e)})")
                    return JsonResponse({'status': 400, 'message': str(e)})

            except RSVP.DoesNotExist:
                failed_rsvps.append(f"RSVP ID {rsvp_id} (not found)")
            except Exception as e:
                failed_rsvps.append(f"RSVP ID {rsvp_id} (error: {str(e)})")

        message = f"QR codes sent to {sent_count} RSVP attendee(s)."
        if failed_rsvps:
            message += f" Failed for: {', '.join(failed_rsvps)}."

        return JsonResponse({
            'status': 200,
            'message': message,
            'sent_count': sent_count
        })

    return JsonResponse(
        {'status': 405, 'message': 'Method not allowed'},
        status=405
    )

@login_required
def reset_rsvp_status(request):
    if request.method == 'POST':
        RSVP.objects.filter(is_sent=True).update(is_sent=False)
        return JsonResponse({'status': 200, 'message': 'Status has been reset.'})
    return JsonResponse(
        {'status': 405, 'message': 'Method not allowed'},
        status=405
    )

# Delete RSVP
@login_required
@csrf_exempt
@require_http_methods(["DELETE"])
def delete_rsvp(request, rsvp_id):
    try:
        rsvp = get_object_or_404(RSVP, id=rsvp_id)
        rsvp.delete()
        return JsonResponse({'success': True, 'message': 'RSVP deleted successfully'})
    except Exception as e:
        logger.error(f'Error deleting RSVP {rsvp_id}: {str(e)}')
        return JsonResponse({'success': False, 'message': str(e)}, status=500)

@login_required
@csrf_exempt
@require_http_methods(["POST"])
def edit_rsvp(request, rsvp_id):
    try:
        rsvp = get_object_or_404(RSVP, id=rsvp_id)
        
        # Parse the request data
        data = json.loads(request.body)
        first_name = data.get('first_name')
        last_name = data.get('last_name', '')
        
        # Update RSVP fields
        rsvp.name = f"{first_name} {last_name}"
        rsvp.first_name = first_name
        rsvp.last_name = last_name
        rsvp.email = data.get('email', rsvp.email)
        rsvp.phone = data.get('phone', rsvp.phone)
        
        # Validate email format
        try:
            validate_email(rsvp.email)
        except ValidationError:
            return JsonResponse({
                'success': False,
                'message': 'Please enter a valid email address'
            }, status=400)
        
        # Save the updated RSVP
        rsvp.save()
        
        return JsonResponse({'success': True, 'message': 'RSVP updated successfully'})
    except RSVP.DoesNotExist:
        return JsonResponse({'success': False, 'message': 'RSVP not found'}, status=404)
    except json.JSONDecodeError:
        return JsonResponse({'success': False, 'message': 'Invalid JSON data'}, status=400)
    except Exception as e:
        logger.error(f'Error updating RSVP {rsvp_id}: {str(e)}')
        return JsonResponse({'success': False, 'message': str(e)}, status=500)

# Dashboard
@login_required
def dashboard(request):
    # Additional security check - ensure user is authenticated
    if not request.user.is_authenticated:
        from django.contrib.auth.views import redirect_to_login
        return redirect_to_login(request.get_full_path(), login_url='/login/')
    
    guests = RSVP.objects.all()
    context = {
        'guests': guests,
        'total_guest':  guests.count(),
        'total_accredited': Accreditation.objects.count(),
    }
    return render(request, 'dashboard.html', context)

# Accredited
@login_required
def accredited(request):
    accredited = Accreditation.objects.prefetch_related('rsvp').all().order_by('-date')
    context = {
        'guests': accredited,
        'total_accredited': accredited.count(),
        'total_guest':  RSVP.objects.count(),
    }
    return render(request, 'accredited.html', context)

# Login
def login_view(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        
        if username and password:
            user = authenticate(request, username=username, password=password)
            if user is not None:
                if user.is_staff:
                    login(request, user)
                    # Regenerate session to prevent session fixation
                    request.session.cycle_key()
                    return redirect('dashboard')
                else:
                    messages.error(request, "You do not have permission to access this dashboard.")
            else:
                messages.error(request, "Invalid credentials. Please check your username and password.")
        else:
            messages.error(request, "Username and password are required.")

    return render(request, 'login.html')

# Logout
@login_required
def logout_view(request):
    request.session.flush()
    logout(request)
    return redirect('login')

