import logging
import threading
from django.utils import timezone
from django.views.decorators.http import require_POST
from django.views.decorators.csrf import csrf_protect
from django.http import JsonResponse
from django.template.loader import render_to_string
from django.core.mail import send_mail
from django.conf import settings
from django.views.decorators.csrf import csrf_exempt

from .forms import NewsletterSubscribeForm, NewsletterUnsubscribeForm
from .models import NewsletterSubscriber

logger = logging.getLogger(__name__)


def _send_subscription_confirmation_safe(email, site):
    try:
        _send_subscription_confirmation(email, site)
    except Exception:
        logger.exception('Failed to send newsletter confirmation', extra={'email': email})


@require_POST
@csrf_exempt
def subscribe(request):
    form = NewsletterSubscribeForm(request.POST)

    if not form.is_valid():
        non_field_errors = form.errors.get('__all__')
        email_errors = form.errors.get('email')

        if non_field_errors:
            return JsonResponse({
                'status': 'already_active',
                'message': non_field_errors[0],
            }, status=400)

        if email_errors:
            return JsonResponse({
                'status': 'invalid',
                'message': email_errors[0],
            }, status=400)

        return JsonResponse({'status': 'error', 'message': 'Invalid request.'}, status=400)

    subscriber, created = form.save()

    action = 'subscribed' if created else 'resubscribed'
    logger.info(
        'Newsletter %s',
        action,
        extra={'email': subscriber.email, 'site': subscriber.site},
    )

    threading.Thread(
        target=_send_subscription_confirmation_safe,
        args=(subscriber.email, subscriber.site),
        daemon=True,
    ).start()

    return JsonResponse({
        'status': 'success',
        'message': 'You\'re subscribed! Check your inbox for a confirmation.',
    })


@require_POST
@csrf_exempt
def unsubscribe(request):
    """
    Unsubscribe an email from the newsletter for a given site.
    Silent success even if email is not found — prevents email enumeration.
    """
    form = NewsletterUnsubscribeForm(request.POST)

    if not form.is_valid():
        return JsonResponse({'status': 'error', 'errors': form.errors}, status=400)

    email = form.cleaned_data['email']
    site = form.cleaned_data['site']

    updated = NewsletterSubscriber.objects.filter(
        email=email,
        site=site,
        unsubscribed=False,
    ).update(
        unsubscribed=True,
        unsubscribed_at=timezone.now(),
    )

    if updated:
        logger.info(
            'Newsletter unsubscribed',
            extra={'email': email, 'site': site},
        )

    # Always return success — do not reveal whether email existed
    return JsonResponse({
        'status': 'success',
        'message': 'You\'ve been unsubscribed.',
    })


# ---------------------------------------------------------------------------
# Internal email helper
# ---------------------------------------------------------------------------

def _send_subscription_confirmation(email: str, site: str) -> None:
    site_display = 'Lifey' if site == 'lifey' else 'PlanySoft'
    subject = f'You\'re subscribed to {site_display} updates'
    body = render_to_string(
        'Emails/newsletter/email-newsletter.html',
        {'site': site, 'site_display': site_display},
    )
    send_mail(
        subject=subject,
        message='',
        from_email=settings.DEFAULT_FROM_EMAIL,
        recipient_list=[email],
        html_message=body,
        fail_silently=False,
    )