from __future__ import annotations

import logging
from dataclasses import dataclass
from typing import Iterable

from django.conf import settings
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
from django.utils import timezone

from .models import LeadSettings, LeadSubmission

logger = logging.getLogger(__name__)


@dataclass
class DuplicateCheckResult:
    is_duplicate: bool
    existing: LeadSubmission | None = None


def get_client_ip(request) -> str | None:
    forwarded = request.META.get("HTTP_X_FORWARDED_FOR", "")
    if forwarded:
        return forwarded.split(",")[0].strip()
    real_ip = request.META.get("HTTP_X_REAL_IP")
    if real_ip:
        return real_ip.strip()
    remote = request.META.get("REMOTE_ADDR")
    return remote.strip() if remote else None


def infer_device_type(user_agent: str) -> str:
    ua = (user_agent or "").lower()
    if "mobile" in ua:
        return "mobile"
    if "tablet" in ua or "ipad" in ua:
        return "tablet"
    if ua:
        return "desktop"
    return "unknown"


def get_lead_settings() -> LeadSettings:
    obj = LeadSettings.objects.order_by("created_at").first()
    if obj:
        return obj
    return LeadSettings.objects.create()


def find_duplicate(*, lead_type: str, email: str, mobile_number: str, source_page_url: str) -> DuplicateCheckResult:
    if not email and not mobile_number:
        return DuplicateCheckResult(is_duplicate=False)

    window_start = timezone.now() - timezone.timedelta(hours=24)
    queryset = LeadSubmission.objects.filter(
        lead_type=lead_type,
        created_at__gte=window_start,
    )
    if email:
        queryset = queryset.filter(email__iexact=email)
    elif mobile_number:
        queryset = queryset.filter(mobile_number=mobile_number)

    if source_page_url:
        queryset = queryset.filter(source_page_url=source_page_url)

    existing = queryset.order_by("-created_at").first()
    return DuplicateCheckResult(is_duplicate=existing is not None, existing=existing)


def _parse_admin_emails(settings_obj: LeadSettings) -> list[str]:
    values = [value.strip() for value in (settings_obj.admin_notification_emails or "").split(",") if value.strip()]
    if values:
        return values
    fallback = getattr(settings, "DEFAULT_FROM_EMAIL", "")
    return [fallback] if fallback else []


def _safe_send(subject: str, text_body: str, html_body: str, recipients: Iterable[str]) -> None:
    recipient_list = [str(value).strip() for value in recipients if str(value).strip()]
    if not recipient_list:
        return

    msg = EmailMultiAlternatives(
        subject=subject,
        body=text_body,
        from_email=getattr(settings, "DEFAULT_FROM_EMAIL", "noreply@truewaveindia.com"),
        to=recipient_list,
    )
    if html_body:
        msg.attach_alternative(html_body, "text/html")
    msg.send(fail_silently=False)


def send_lead_emails(lead: LeadSubmission, settings_obj: LeadSettings) -> None:
    if settings_obj.enable_admin_notifications:
        recipients = _parse_admin_emails(settings_obj)
        try:
            admin_html = render_to_string("leads/admin_notification.html", {"lead": lead})
            admin_text = (
                f"New lead captured\n"
                f"Type: {lead.lead_type}\n"
                f"Name: {lead.full_name}\n"
                f"Email: {lead.email}\n"
                f"Mobile: {lead.mobile_number}\n"
                f"Source: {lead.source_page_name} ({lead.source_page_url})"
            )
            _safe_send(
                subject=f"[True Wave Leads] New {lead.get_lead_type_display()} lead",
                text_body=admin_text,
                html_body=admin_html,
                recipients=recipients,
            )
        except Exception:
            logger.exception("Failed to send admin lead email for %s", lead.id)

    if settings_obj.enable_user_auto_reply and lead.email:
        try:
            user_html = render_to_string("leads/user_confirmation.html", {"lead": lead})
            user_text = (
                "Thank you for reaching out to True Wave Marketing. "
                "We received your interest and our team will connect with you soon."
            )
            _safe_send(
                subject="Thank you for your interest in True Wave Marketing",
                text_body=user_text,
                html_body=user_html,
                recipients=[lead.email],
            )
        except Exception:
            logger.exception("Failed to send user confirmation email for %s", lead.id)
