from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth import authenticate, login, logout
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .models import User, Download, Gallery, Official
from django.db.models import Q
from django.contrib.admin.views.decorators import staff_member_required
from django.core.mail import send_mail
from django.conf import settings

def home(request):
    return render(request, "public/home.html")

def register_view(request):
    if request.method == 'POST':

        # Get form data
        first_name = request.POST.get('first_name')
        last_name = request.POST.get('last_name')
        email = request.POST.get('email')
        phone = request.POST.get('phone')
        county = request.POST.get('county')
        constituency = request.POST.get('constituency')
        institution = request.POST.get('institution')
        course = request.POST.get('course')
        registration_number = request.POST.get('registration_number')
        password1 = request.POST.get('password1')
        password2 = request.POST.get('password2')

        student_id = request.FILES.get('student_id')

        # ===== VALIDATION =====

        if password1 != password2:
            messages.error(request, "Passwords do not match.")
            return render(request, 'public/register.html')

        if len(password1) < 6:
            messages.error(request, "Password must be at least 6 characters.")
            return render(request, 'public/register.html')

        if email and User.objects.filter(email=email).exists():
            messages.error(request, "Email already exists.")
            return render(request, 'public/register.html')

        if phone and User.objects.filter(phone_number=phone).exists():
            messages.error(request, "Phone number already exists.")
            return render(request, 'public/register.html')

        # ===== CREATE USER =====

        username = email if email else phone

        user = User.objects.create_user(
            username=username,
            first_name=first_name,
            last_name=last_name,
            email=email,
            password=password1,
        )

        user.phone_number = phone
        user.county = county
        user.constituency = constituency
        user.institution = institution
        user.course = course
        user.registration_number = registration_number
        user.student_id = student_id
        user.is_approved = False

        user.save()

        # ==========================
        # 📩 EMAIL TO USER
        # ==========================

        if user.email:
            send_mail(
                subject="BUSA Registration Received",
                message=f"""
Hello {user.first_name},

Thank you for registering as a member of the
Baliti University Students Association (BUSA).

Your registration is currently being reviewed by the administration.
You will receive another email once your account has been approved.

Thank you for your patience.

BUSA Administration
""",
                from_email=settings.DEFAULT_FROM_EMAIL,
                recipient_list=[user.email],
                fail_silently=True,
            )

        # ==========================
        # EMAIL TO ADMINS (2 emails)
        # ==========================

        admin_emails = [
            "muhamedhussein08@gmail.com",
            "habibaramata@gmail.com",
        ]

        send_mail(
            subject="New BUSA Registration",
            message=f"""
A new user has registered and is pending approval.

Name: {user.get_full_name()}
Email: {user.email}
Phone: {user.phone_number}
Institution: {user.institution}
Course: {user.course}

Please log in to the admin panel to review and approve.
""",
            from_email=settings.DEFAULT_FROM_EMAIL,
            recipient_list=admin_emails,
            fail_silently=True,
        )

        messages.success(
            request,
            "Registration successful! You can now login"
        )

        return redirect('login')

    return render(request, 'public/register.html')

def login_view(request):
    if request.method == 'POST':
        identifier = request.POST.get('login_identifier')
        password = request.POST.get('login_password')

        if not identifier or not password:
            messages.error(request, "Please fill in all fields.")
            return render(request, 'public/login.html')

        try:
            user_obj = User.objects.get(
                Q(email=identifier) | Q(phone_number=identifier)
            )

            user = authenticate(
                request,
                username=user_obj.username,
                password=password
            )

            if user is not None:
                login(request, user)

                # Handle ?next= first
                next_url = request.GET.get('next')
                if next_url:
                    return redirect(next_url)

                
                #if user.is_staff or user.is_superuser:
                    #return redirect('admin_dashboard')

                return redirect('dashboard')

            else:
                messages.error(request, "Invalid password.")

        except User.DoesNotExist:
            messages.error(
                request,
                "No account found with that email or phone number."
            )

        return render(request, 'public/login.html')

    return render(request, 'public/login.html')


def logout_view(request):
    """Handle user logout"""
    logout(request)
    return redirect('home')

@login_required()
def dashboard(request):
    return render(request, 'public/dashboard.html', {'user': request.user})

@login_required
def profile_view(request):
    user = request.user

    # Only approved users can view profile
    if not user.is_approved:
        messages.warning(request, "Your account is pending approval.")
        return redirect('dashboard')

    return render(request, 'public/profile.html', {'user_obj': user})

@login_required
def vote_view(request):

    # Only approved users can access voting
    if not request.user.is_approved:
        messages.warning(request, "Your account is not yet approved.")
        return redirect('dashboard')

    return render(request, 'public/vote.html')


def downloads_view(request):
    downloads = Download.objects.all()
    return render(request, 'public/downloads.html', {
        'downloads': downloads
    })

def gallery_view(request):
    images = Gallery.objects.all()
    return render(request, 'public/gallery.html', {
        'images': images
    })

def officials_view(request):

    # Define the exact hierarchy order you want
    position_order = [
        "patron",
        "chairperson",
        "vice_chairperson",
        "spokesperson",
        "secretary_general",
        "finance_secretary",
        "organizing_secretary",
        "public_relations_officer",
        "gender_representative",
        "coordinator",
    ]

    # Create ranking dictionary
    order_map = {position: index for index, position in enumerate(position_order)}

    officials = Official.objects.all()

    # Sort using the defined hierarchy
    officials = sorted(
        officials,
        key=lambda x: order_map.get(x.position, 999)
    )

    return render(request, 'public/officials.html', {
        'officials': officials
    })











@staff_member_required
def admin_dashboard(request):
    return render(request, 'admin/admin_dashboard.html')


@staff_member_required
def user_list(request):
    users = User.objects.all().order_by('-date_registered')

    total_users = users.count()
    approved_users = users.filter(is_approved=True).count()
    pending_users = users.filter(is_approved=False).count()

    context = {
        'users': users,
        'total_users': total_users,
        'approved_users': approved_users,
        'pending_users': pending_users,
    }

    return render(request, 'admin/user_list.html', context)



@staff_member_required
def user_detail(request, user_id):
    user_obj = get_object_or_404(User, id=user_id)

    if request.method == 'POST':

        # Store previous approval state
        was_approved = user_obj.is_approved

        user_obj.first_name = request.POST.get('first_name')
        user_obj.last_name = request.POST.get('last_name')
        user_obj.email = request.POST.get('email')
        user_obj.phone_number = request.POST.get('phone_number')
        user_obj.county = request.POST.get('county')
        user_obj.constituency = request.POST.get('constituency')
        user_obj.institution = request.POST.get('institution')
        user_obj.course = request.POST.get('course')
        user_obj.registration_number = request.POST.get('registration_number')

        # Approval toggle
        user_obj.is_approved = True if request.POST.get('is_approved') == 'on' else False

        user_obj.save()

        # 🔥 Send email ONLY if newly approved
        if not was_approved and user_obj.is_approved and user_obj.email:

            subject = "Welcome to BUSA - Account Approved"
            message = f"""
Hello {user_obj.first_name},

Congratulations!

Your account has been approved as a member of the
Baliti University Students Association (BUSA).

You can now log in and participate in elections and other activities.

Thank you for joining BUSA.

Best regards,
BUSA Administration
"""

            send_mail(
                subject,
                message,
                settings.DEFAULT_FROM_EMAIL,
                [user_obj.email],
                fail_silently=True,
            )

        messages.success(request, "User details updated successfully.")
        return redirect('user_list')

    return render(request, 'admin/user_detail.html', {'user_obj': user_obj})


@staff_member_required
def delete_user(request, user_id):
    user_obj = get_object_or_404(User, id=user_id)

    if request.method == "POST":
        # Prevent deleting yourself (important safety)
        if user_obj == request.user:
            messages.error(request, "You cannot delete your own account.")
            return redirect('user_detail', user_id=user_obj.id)

        user_obj.delete()
        messages.success(request, "User deleted successfully.")
        return redirect('user_list')

    return render(request, "admin/delete_user.html", {"user_obj": user_obj})



@staff_member_required
def admin_downloads(request):
    downloads = Download.objects.all()
    return render(request, 'admin/admin_downloads.html', {
        'downloads': downloads
    })


@staff_member_required
def add_download(request):
    if request.method == "POST":
        name = request.POST.get("name")
        file = request.FILES.get("file")

        if not name or not file:
            messages.error(request, "All fields are required.")
            return redirect('add_download')

        Download.objects.create(name=name, file=file)
        messages.success(request, "Download uploaded successfully.")
        return redirect('admin_downloads')

    return render(request, 'admin/add_download.html')


@staff_member_required
def delete_download(request, download_id):
    download = get_object_or_404(Download, id=download_id)

    if request.method == "POST":
        download.file.delete()  # delete file from storage
        download.delete()       # delete db record
        messages.success(request, "Download deleted successfully.")
        return redirect('admin_downloads')

    return redirect('admin_downloads')


@staff_member_required
def admin_gallery(request):
    images = Gallery.objects.all()
    return render(request, 'admin/admin_gallery.html', {
        'images': images
    })


@staff_member_required
def add_gallery(request):
    if request.method == "POST":
        caption = request.POST.get("caption")
        image = request.FILES.get("image")

        if not caption or not image:
            messages.error(request, "All fields are required.")
            return redirect('add_gallery')

        Gallery.objects.create(caption=caption, image=image)
        messages.success(request, "Image added to gallery.")
        return redirect('admin_gallery')

    return render(request, 'admin/add_gallery.html')


@staff_member_required
def edit_gallery(request, gallery_id):
    gallery = get_object_or_404(Gallery, id=gallery_id)

    if request.method == "POST":
        gallery.caption = request.POST.get("caption")

        if request.FILES.get("image"):
            gallery.image.delete()  # delete old image
            gallery.image = request.FILES.get("image")

        gallery.save()
        messages.success(request, "Gallery image updated.")
        return redirect('admin_gallery')

    return render(request, 'admin/edit_gallery.html', {
        'gallery': gallery
    })


@staff_member_required
def delete_gallery(request, gallery_id):
    gallery = get_object_or_404(Gallery, id=gallery_id)

    if request.method == "POST":
        gallery.image.delete()
        gallery.delete()
        messages.success(request, "Gallery image deleted.")
        return redirect('admin_gallery')

    return redirect('admin_gallery')


@staff_member_required
def admin_officials(request):
    officials = Official.objects.all()
    return render(request, 'admin/admin_officials.html', {
        'officials': officials
    })


@staff_member_required
def add_official(request):
    if request.method == "POST":
        name = request.POST.get("name")
        position = request.POST.get("position")
        description = request.POST.get("description")
        image = request.FILES.get("image")

        if not name or not position:
            messages.error(request, "Name and position are required.")
            return redirect('add_official')

        Official.objects.create(
            name=name,
            position=position,
            description=description,
            image=image
        )

        messages.success(request, "Official added successfully.")
        return redirect('admin_officials')

    return render(request, 'admin/add_official.html', {
        'positions': Official.POSITION_CHOICES
    })


@staff_member_required
def edit_official(request, official_id):
    official = get_object_or_404(Official, id=official_id)

    if request.method == "POST":
        official.name = request.POST.get("name")
        official.position = request.POST.get("position")
        official.description = request.POST.get("description")

        if request.FILES.get("image"):
            if official.image:
                official.image.delete()
            official.image = request.FILES.get("image")

        official.save()
        messages.success(request, "Official updated successfully.")
        return redirect('admin_officials')

    return render(request, 'admin/edit_official.html', {
        'official': official,
        'positions': Official.POSITION_CHOICES
    })


@staff_member_required
def delete_official(request, official_id):
    official = get_object_or_404(Official, id=official_id)

    if request.method == "POST":
        if official.image:
            official.image.delete()
        official.delete()
        messages.success(request, "Official deleted successfully.")
        return redirect('admin_officials')



@staff_member_required
def admin_voting(request):
    return render(request, 'admin/admin_voting.html')