from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.urls import reverse
from django.utils import timezone
from django.db import transaction
from django.db.models import Q
from django.core.exceptions import ValidationError

from .models import Membership
from .forms import MembershipForm

@login_required(login_url='accounts:login')
def membership(request):
    """Display membership categories and handle application flow."""
    context = {
        'membership_categories': [
            {
                'name': 'Full Member',
                'fee': 600,
                'description': 'For graduates with a Bachelor\'s degree or higher qualification.'
            },
            {
                'name': 'Associate Member',
                'fee': 300,
                'description': 'For individuals who support our mission but don\'t meet full membership criteria.'
            },
            {
                'name': 'Student Member',
                'fee': 200,
                'description': 'For current students pursuing their first degree.'
            },
            {
                'name': 'Honorary Member',
                'fee': 200,
                'description': 'By invitation only, for distinguished individuals who support our cause.'
            }
        ]
    }
    
    if request.user.is_authenticated:
        membership = Membership.objects.filter(user=request.user).first()
        if membership:
            # If user came from login page and has membership, redirect to profile
            if request.GET.get('from') == 'login':
                if membership.is_active:
                    messages.info(request, 'Welcome back! You already have an active membership.')
                elif membership.membership_status == 'pending':
                    messages.info(request, 'Welcome back! Your application is under review.')
                elif membership.membership_status == 'expired':
                    messages.info(request, 'Welcome back! Your membership has expired. Please renew it.')
                return redirect('membership:profile')
        context['membership'] = membership
    
    return render(request, 'membership/membership.html', context)

@login_required(login_url='accounts:login')
def membership_application(request):
    """Handle membership application form."""
    try:
        membership = Membership.objects.get(user=request.user)
        if membership.membership_status != 'rejected':
            messages.info(request, 'You already have a membership application.')
            return redirect('membership:profile')
    except Membership.DoesNotExist:
        membership = None

    if request.method == 'POST':
        form = MembershipForm(request.POST, request.FILES, instance=membership)
        if form.is_valid():
            membership = form.save(commit=False)
            membership.user = request.user
            membership.email = request.user.email
            
            # Reset status and rejection reason if reapplying
            if membership.membership_status == 'rejected':
                membership.membership_status = 'pending'
                membership.rejection_reason = None
                membership.payment_proof = None  # Clear the payment proof
                membership.payment_verified = False  # Reset payment verification
                membership.payment_verified_at = None
                membership.payment_verified_by = None
            
            membership.save()
            messages.success(request, 'Your membership application has been submitted successfully.')
            return redirect('membership:payment_instructions')
    else:
        initial_data = {}
        if membership:
            # Pre-fill form with existing data for rejected applications
            form = MembershipForm(instance=membership)
        else:
            # Pre-fill form with user data for new applications
            initial_data = {
                'first_name': request.user.first_name,
                'last_name': request.user.last_name,
                'email': request.user.email,
            }
            form = MembershipForm(initial=initial_data)

    return render(request, 'membership/application.html', {'form': form})

@login_required(login_url='accounts:login')
def membership_profile(request):
    """Display user's membership profile."""
    try:
        membership = Membership.objects.get(user=request.user)
        return render(request, 'membership/profile.html', {'membership': membership})
    except Membership.DoesNotExist:
        messages.info(request, 'Please complete your membership application.')
        return redirect('membership:application')

@login_required(login_url='accounts:login')
def payment_instructions(request):
    """Display payment instructions and handle payment proof upload."""
    try:
        membership = Membership.objects.get(user=request.user)
        
        if request.method == 'POST' and request.FILES.get('payment_proof'):
            membership.payment_proof = request.FILES['payment_proof']
            membership.payment_verified = False
            membership.payment_verified_at = None
            membership.payment_verified_by = None
            
            # Set status to pending for verification
            membership.membership_status = 'pending'
            
            # If membership is expired, set new validity period
            if not membership.is_active:
                membership.membership_valid_until = timezone.now().date() + timezone.timedelta(days=365)
            
            membership.save()
            messages.success(request, 'Payment proof uploaded successfully. Your membership will be reactivated once payment is verified.')
            return redirect('membership:profile')

        # Define payment methods
        payment_methods = [
            {
                'name': 'Mobile Money',
                'instructions': [
                    '1. Dial *XXX# on your phone',
                    '2. Select "Send Money"',
                    '3. Enter number: 097XXXXXXX',
                    '4. Enter amount: K{}'.format(membership.membership_fee),
                    '5. Enter your PIN',
                    '6. Save the confirmation message'
                ]
            },
            {
                'name': 'Bank Transfer',
                'instructions': [
                    'Account Name: Graduate Women Zambia',
                    'Bank: Standard Chartered Bank',
                    'Account Number: XXXXXXXXXX',
                    'Branch: Cairo Road',
                    'Swift Code: SCBLZMLX',
                    'Reference: GWZ-{}'.format(membership.id)
                ]
            }
        ]

        context = {
            'membership': membership,
            'membership_fee': membership.membership_fee,
            'payment_methods': payment_methods
        }
        return render(request, 'membership/payment_instructions.html', context)
    except Membership.DoesNotExist:
        messages.error(request, 'Please complete your membership application first.')
        return redirect('membership:application')

@login_required(login_url='accounts:login')
@login_required(login_url='accounts:login')
def upload_payment(request):
    """Handle payment proof upload for membership renewal."""
    if request.method == 'POST' and request.FILES.get('payment_proof'):
        membership = get_object_or_404(Membership, user=request.user)
        
        # Reset payment verification
        membership.payment_verified = False
        membership.payment_verified_at = None
        membership.payment_verified_by = None
        
        # Update payment proof
        membership.payment_proof = request.FILES['payment_proof']
        membership.save()
        
        messages.success(request, 'Payment proof uploaded successfully. We will review it shortly.')
        return redirect('membership:profile')
    
    messages.error(request, 'No payment proof was uploaded.')
    return redirect('membership:profile')


def download_document(request, document_type, membership_id):
    """Handle document downloads."""
    membership = get_object_or_404(Membership, id=membership_id)
    
    # Ensure only the owner or admin can download documents
    if not request.user.is_staff and membership.user != request.user:
        messages.error(request, 'You do not have permission to access this document.')
        return redirect('membership:profile')
    
    document_map = {
        'cv': membership.cv,
        'nrc': membership.nrc_file,
        'certificate': membership.degree_certificate,
        'transcript': membership.transcript,
        'payment': membership.payment_proof
    }
    
    document = document_map.get(document_type)
    if not document:
        messages.error(request, 'Document not found.')
        return redirect('membership:profile')
        
    return redirect(document.url)