from datetime import datetime

from celery import shared_task
from celery.utils.log import get_task_logger

from django.core.mail import send_mail, EmailMultiAlternatives

logger = get_task_logger(__name__)

from account.models import CustomUser
from django.conf import settings
from django.template.loader import render_to_string


@shared_task
def send_notification_email_task(recipient_email, subject, template_path, context=None, attachments=None):
    send_email_with_context(
        recipients=recipient_email,
        subject=subject,
        template_path=template_path,
        context=context or {},
        attachments=attachments,
    )



def send_email_with_context(recipients, subject, template_path=None, context=None, message: str | None = None, attachments=None):
    """
    Send email using component-based template system.
    Uses base.html with header/footer components and includes the specified content template.
    """
    if isinstance(recipients, str):
        recipients = [recipients]

    if not recipients:
        logger.warning("No recipients provided for email. Skipping sending email.")
        return "No recipients provided for email."
    
    ctx = dict(context or {})
    
    # Add current_year to context if not present
    if "current_year" not in ctx:
        ctx["current_year"] = datetime.now().year
    
    # Add AppConfig data for footer if not already present
    if "company_name" not in ctx:
        try:
            from configuration.models import AppConfig
            config = AppConfig.objects.first()
            if config:
                ctx["company_name"] = config.company_name
                ctx["company_address"] = config.company_address
                ctx["company_ico"] = config.company_ico
                ctx["company_dic"] = config.company_dic
                ctx["contact_email"] = config.contact_email
                ctx["contact_phone"] = config.contact_phone
        except Exception:
            pass  # Gracefully skip if AppConfig not available
    
    # Sanitize user if someone passes the model by mistake
    if "user" in ctx and not isinstance(ctx["user"], dict):
        try:
            ctx["user"] = _build_user_template_ctx(ctx["user"])
        except Exception:
            ctx["user"] = {}

    # Render HTML using base template with content include
    html_message = None
    if template_path:
        ctx["content_template"] = template_path
        html_message = render_to_string("email/components/base.html", ctx)

    try:
        email = EmailMultiAlternatives(
            subject=subject,
            body=message or "Tento e-mail vyžaduje HTML podporu.",
            from_email=None,
            to=recipients if len(recipients) == 1 else [],
            bcc=recipients if len(recipients) > 1 else [],
        )
        
        if html_message:
            email.attach_alternative(html_message, "text/html")
        
        if attachments:
            for filename, content, mimetype in attachments:
                email.attach(filename, content, mimetype)
        
        email.send(fail_silently=False)
        
        logger.info(f"Sent email to {recipients} with subject '{subject}'")

        if settings.EMAIL_BACKEND == 'django.core.mail.backends.console.EmailBackend':
            logger.debug(f"\nEMAIL HTML:\n{html_message}\nKONEC OBSAHU")
        return "Successfully sent email."
    except Exception as e:
        logger.error(f"E-mail se neodeslal: {e}")
        raise  # Re-raise so Celery marks the task as FAILED and can retry


def _build_user_template_ctx(user: CustomUser) -> dict:
    """
    Return a plain dict for templates instead of passing the DB model.
    Provides aliases to avoid template errors (firstname vs first_name).
    Adds a backward-compatible key 'get_full_name' for templates using user.get_full_name.
    """
    first_name = getattr(user, "first_name", "") or ""
    last_name = getattr(user, "last_name", "") or ""
    full_name = f"{first_name} {last_name}".strip()
    return {
        "id": user.pk,
        "email": getattr(user, "email", "") or "",
        "username": getattr(user, "username", "") or "",
        "first_name": first_name,
        "firstname": first_name,
        "last_name": last_name,
        "lastname": last_name,
        "full_name": full_name,
        "get_full_name": full_name,
    }