from django.shortcuts import render, redirect
from django.contrib.auth import login, logout, get_user_model
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.contrib.sites.shortcuts import get_current_site
from django.utils.encoding import force_bytes, force_str
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.template.loader import render_to_string
from django.core.mail import EmailMessage
from django.utils import timezone

from .models import Profile, Referral
from .forms import SignupForm, ResendActivationForm
from .tokens import account_activation_token

User = get_user_model()

def send_activation_email(request, user):
    current_site = get_current_site(request)
    mail_subject = 'Activate your Referral Rewards account.'
    message = render_to_string('core/emails/activation_email.html', {
        'user': user,
        'domain': current_site.domain,
        'protocol': 'https' if request.is_secure() else 'http',
        'uid': urlsafe_base64_encode(force_bytes(user.pk)),
        'token': account_activation_token.make_token(user),
    })
    to_email = user.email
    email = EmailMessage(
        mail_subject, message, to=[to_email]
    )
    return email.send()

def home(request):
    if request.user.is_authenticated:
        return redirect('dashboard')
    return render(request, 'core/index.html')

def signup(request):
    if request.user.is_authenticated:
        return redirect('dashboard')
    if request.method == 'POST':
        form = SignupForm(request.POST)
        if form.is_valid():
            user = form.save(commit=False)
            user.is_active = False
            user.save()
            
            # Referral logic
            ref_code = request.session.get('ref')
            if ref_code:
                try:
                    referrer_profile = Profile.objects.get(referral_code=ref_code)
                    referrer = referrer_profile.user
                    
                    # Update user's profile with referrer
                    user.profile.referred_by = referrer
                    user.profile.save()
                    
                    # Create Referral record
                    Referral.objects.create(
                        referrer=referrer,
                        referred_user=user,
                        referral_code=ref_code,
                        status='pending'
                    )
                except Profile.DoesNotExist:
                    pass # Invalid referral code, just ignore
            
            # Send activation email
            try:
                send_activation_email(request, user)
                messages.success(request, 'Please confirm your email address to complete the registration. Check your inbox.')
            except Exception as e:
                messages.error(request, f'Error sending email: {str(e)}. Please contact support.')
            
            return redirect('login')
    else:
        form = SignupForm()
    return render(request, 'core/signup.html', {'form': form})

def resend_activation(request):
    if request.user.is_authenticated:
        return redirect('dashboard')
    
    if request.method == 'POST':
        form = ResendActivationForm(request.POST)
        if form.is_valid():
            email_addr = form.cleaned_data.get('email')
            try:
                user = User.objects.get(email=email_addr)
                if not user.is_active:
                    send_activation_email(request, user)
                    messages.success(request, 'A new activation email has been sent. Please check your inbox.')
                    return redirect('login')
                else:
                    messages.info(request, 'This account is already active. Please log in.')
                    return redirect('login')
            except User.DoesNotExist:
                # Security: Don't reveal if email exists, just say it's sent if it's inactive
                messages.success(request, 'If an inactive account with that email exists, an activation email has been sent.')
                return redirect('login')
            except Exception as e:
                messages.error(request, f'Error sending email: {str(e)}. Please contact support.')
    else:
        form = ResendActivationForm()
    
    return render(request, 'core/resend_activation.html', {'form': form})

def activate(request, uidb64, token):
    try:
        uid = force_str(urlsafe_base64_decode(uidb64))
        user = User.objects.get(pk=uid)
    except(TypeError, ValueError, OverflowError, User.DoesNotExist):
        user = None
    if user is not None and account_activation_token.check_token(user, token):
        user.is_active = True
        user.save()
        
        # Complete referral if exists
        referral = Referral.objects.filter(referred_user=user, status='pending').first()
        if referral:
            referral.status = 'successful'
            referral.completed_at = timezone.now()
            referral.save()
            
            # Reward referrer (e.g. add 10 points)
            referrer_profile = referral.referrer.profile
            referrer_profile.points += 10
            referrer_profile.save()
            
            messages.info(request, f'You were successfully referred by {referral.referrer.username}!')

        login(request, user)
        messages.success(request, 'Thank you for your email confirmation. Now you can enjoy our services.')
        return redirect('dashboard')
    else:
        messages.error(request, 'Activation link is invalid!')
        return redirect('home')

@login_required
def dashboard(request):
    profile, created = Profile.objects.get_or_create(user=request.user)
    
    # Get successful referrals
    referrals = Referral.objects.filter(referrer=request.user, status__in=['successful', 'rewarded']).order_by('-completed_at')
    
    current_site = get_current_site(request)
    domain = current_site.domain
    protocol = 'https' if request.is_secure() else 'http'
    referral_link = f"{protocol}://{domain}/?ref={profile.referral_code}"
    
    context = {
        'profile': profile,
        'referrals': referrals,
        'referral_link': referral_link,
    }
    return render(request, 'core/dashboard.html', context)

def logout_view(request):
    logout(request)
    return redirect('home')