from django.shortcuts import render, redirect, get_object_or_404
from django.http import JsonResponse, FileResponse, Http404
from django.views.decorators.http import require_POST, require_GET
from django.core.mail import send_mail
from django.template.loader import render_to_string
from django.conf import settings
from .models import Subscriber, LeadMagnet
from .forms import SubscribeForm


def get_client_ip(request):
    """Get client IP address from request."""
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        return x_forwarded_for.split(',')[0].strip()
    return request.META.get('REMOTE_ADDR')


@require_POST
def subscribe(request):
    """Handle newsletter subscription."""
    form = SubscribeForm(request.POST)
    source = request.POST.get('source', 'other')

    # Check for AJAX request
    is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'

    if form.is_valid():
        email = form.cleaned_data['email']

        # Check for existing unsubscribed user
        existing = Subscriber.objects.filter(email=email, status='unsubscribed').first()

        if existing:
            # Reactivate subscription
            existing.status = 'pending'
            existing.confirmation_token = Subscriber._meta.get_field('confirmation_token').default()
            existing.unsubscribed_at = None
            existing.ip_address = get_client_ip(request)
            existing.save()
            subscriber = existing
        else:
            # Create new subscriber
            subscriber = form.save(commit=False)
            subscriber.source = source
            subscriber.ip_address = get_client_ip(request)
            subscriber.save()

        # Send confirmation email
        send_confirmation_email(request, subscriber)

        if is_ajax:
            return JsonResponse({
                'success': True,
                'message': 'Merci ! Vérifie ta boîte mail pour confirmer ton inscription.'
            })
        return redirect('newsletter:confirm_pending')

    else:
        if is_ajax:
            errors = {field: errors[0] for field, errors in form.errors.items()}
            return JsonResponse({
                'success': False,
                'errors': errors
            }, status=400)
        return render(request, 'newsletter/subscribe_error.html', {'form': form})


def send_confirmation_email(request, subscriber):
    """Send double opt-in confirmation email."""
    confirm_url = request.build_absolute_uri(
        f'/newsletter/confirm/{subscriber.confirmation_token}/'
    )

    subject = "Confirme ton inscription à la newsletter JoPer"
    html_message = render_to_string('newsletter/emails/confirm.html', {
        'subscriber': subscriber,
        'confirm_url': confirm_url,
    })
    text_message = f"""
Salut{' ' + subscriber.first_name if subscriber.first_name else ''} !

Merci de t'inscrire à la newsletter JoPer.

Clique sur ce lien pour confirmer ton inscription :
{confirm_url}

Si tu n'as pas demandé cette inscription, ignore simplement cet email.

À bientôt !
L'équipe JoPer
"""

    try:
        send_mail(
            subject=subject,
            message=text_message,
            from_email=settings.DEFAULT_FROM_EMAIL,
            recipient_list=[subscriber.email],
            html_message=html_message,
            fail_silently=False,
        )
    except Exception:
        # Log error but don't fail the subscription
        pass


@require_GET
def confirm(request, token):
    """Confirm subscription via token."""
    subscriber = get_object_or_404(Subscriber, confirmation_token=token)

    if subscriber.status == 'confirmed':
        return render(request, 'newsletter/already_confirmed.html')

    subscriber.confirm()
    return render(request, 'newsletter/confirmed.html', {'subscriber': subscriber})


@require_GET
def unsubscribe(request, token):
    """Unsubscribe via token."""
    subscriber = get_object_or_404(Subscriber, unsubscribe_token=token)

    if subscriber.status == 'unsubscribed':
        return render(request, 'newsletter/already_unsubscribed.html')

    subscriber.unsubscribe()
    return render(request, 'newsletter/unsubscribed.html', {'subscriber': subscriber})


def confirm_pending(request):
    """Show pending confirmation page."""
    return render(request, 'newsletter/confirm_pending.html')


@require_GET
def download_lead_magnet(request, token):
    """Download page for lead magnet (requires confirmed subscriber token)."""
    # Verify subscriber is confirmed
    subscriber = get_object_or_404(Subscriber, unsubscribe_token=token, status='confirmed')

    # Get active lead magnets
    lead_magnets = LeadMagnet.objects.filter(is_active=True)

    return render(request, 'newsletter/download.html', {
        'subscriber': subscriber,
        'lead_magnets': lead_magnets,
    })


@require_GET
def download_file(request, token, magnet_token):
    """Serve the actual lead magnet file."""
    # Verify subscriber is confirmed
    subscriber = get_object_or_404(Subscriber, unsubscribe_token=token, status='confirmed')

    # Get the lead magnet
    lead_magnet = get_object_or_404(LeadMagnet, download_token=magnet_token, is_active=True)

    # Increment download count
    lead_magnet.increment_download()

    # Serve the file
    try:
        response = FileResponse(
            lead_magnet.file.open('rb'),
            as_attachment=True,
            filename=lead_magnet.file.name.split('/')[-1]
        )
        return response
    except FileNotFoundError:
        raise Http404("Fichier non trouvé")
