"""
Email Service

Central service for sending emails using PuckEmailTemplate system.
Provides a simple API for sending templated emails throughout the application.

Usage:
    from smoothschedule.communication.messaging.email_service import send_system_email

    # Send a simple email
    send_system_email(
        email_type=EmailType.APPOINTMENT_CONFIRMATION,
        to_email='customer@example.com',
        context={
            'customer_name': 'John Doe',
            'appointment_date': '2024-01-15',
            'appointment_time': '10:00 AM',
        }
    )
"""
import logging
from typing import Dict, Any, Optional, List

from django.conf import settings
from django.core.mail import EmailMultiAlternatives

from .email_types import EmailType
from .models import PuckEmailTemplate
from .email_renderer import render_email


logger = logging.getLogger(__name__)


def is_email_blocked() -> bool:
    """
    Check if emails should be blocked for the current tenant.

    Used for demo accounts where we don't want to send real emails.
    Checks the tenant's block_emails flag.

    Returns:
        True if emails should be blocked, False otherwise
    """
    try:
        from django.db import connection
        tenant = getattr(connection, 'tenant', None)
        if tenant and hasattr(tenant, 'block_emails'):
            return tenant.block_emails
    except Exception:
        pass
    return False


def send_system_email(
    email_type: EmailType,
    to_email: str,
    context: Optional[Dict[str, Any]] = None,
    from_email: Optional[str] = None,
    reply_to: Optional[str] = None,
    extra_headers: Optional[Dict[str, str]] = None,
    fail_silently: bool = False,
) -> bool:
    """
    Send an email using a system template.

    Retrieves the appropriate PuckEmailTemplate for the email_type,
    renders it with the provided context, and sends via Django's email backend.

    Args:
        email_type: EmailType enum value (e.g., EmailType.APPOINTMENT_CONFIRMATION)
        to_email: Recipient email address
        context: Dictionary of tag values for template rendering
        from_email: Optional sender email (defaults to DEFAULT_FROM_EMAIL)
        reply_to: Optional reply-to address
        extra_headers: Optional additional email headers
        fail_silently: If True, suppress exceptions on send failure

    Returns:
        True if email sent successfully, False otherwise

    Example:
        send_system_email(
            email_type=EmailType.WELCOME,
            to_email='new.user@example.com',
            context={'customer_name': 'John', 'business_name': 'Acme Corp'},
        )
    """
    if not to_email:
        logger.warning("Cannot send email: no recipient address")
        return False

    # Check if emails are blocked for this tenant (demo accounts)
    if is_email_blocked():
        logger.info(f"Email blocked for demo tenant: {email_type.value} to {to_email}")
        return True  # Return True to avoid error handling in callers

    context = context or {}

    try:
        # Get or create template for this email type
        template = PuckEmailTemplate.get_or_create_for_type(email_type)

        if not template.is_active:
            logger.info(f"Email template {email_type} is inactive, skipping send")
            return False

        # Render the email
        rendered = render_email(template, context)

        # Build the email
        sender = from_email or getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@smoothschedule.com')

        msg = EmailMultiAlternatives(
            subject=rendered['subject'],
            body=rendered['text'],
            from_email=sender,
            to=[to_email],
        )

        # Add HTML version
        if rendered['html']:
            msg.attach_alternative(rendered['html'], 'text/html')

        # Add reply-to if specified
        if reply_to:
            msg.reply_to = [reply_to]

        # Add extra headers
        if extra_headers:
            msg.extra_headers = extra_headers

        # Send it
        msg.send(fail_silently=fail_silently)
        logger.info(f"Sent {email_type.value} email to {to_email}")
        return True

    except Exception as e:
        logger.error(f"Failed to send {email_type.value} email to {to_email}: {e}")
        if not fail_silently:
            raise
        return False


def send_system_email_bulk(
    email_type: EmailType,
    recipients: List[Dict[str, Any]],
    common_context: Optional[Dict[str, Any]] = None,
    from_email: Optional[str] = None,
    fail_silently: bool = True,
) -> Dict[str, bool]:
    """
    Send the same email type to multiple recipients with individual context.

    Args:
        email_type: EmailType enum value
        recipients: List of dicts with 'email' and optional 'context' keys
        common_context: Context values shared by all recipients
        from_email: Optional sender email
        fail_silently: If True, continue on individual send failures

    Returns:
        Dict mapping email addresses to success status

    Example:
        send_system_email_bulk(
            email_type=EmailType.APPOINTMENT_REMINDER,
            recipients=[
                {'email': 'customer1@example.com', 'context': {'customer_name': 'Alice'}},
                {'email': 'customer2@example.com', 'context': {'customer_name': 'Bob'}},
            ],
            common_context={'business_name': 'Acme Corp'},
        )
    """
    results = {}
    common_context = common_context or {}

    for recipient in recipients:
        email = recipient.get('email')
        if not email:
            continue

        # Merge common context with recipient-specific context
        recipient_context = recipient.get('context', {})
        merged_context = {**common_context, **recipient_context}

        success = send_system_email(
            email_type=email_type,
            to_email=email,
            context=merged_context,
            from_email=from_email,
            fail_silently=fail_silently,
        )
        results[email] = success

    return results


def get_template_preview(
    email_type: EmailType,
    context: Optional[Dict[str, Any]] = None,
) -> Dict[str, str]:
    """
    Get a preview of what an email would look like without sending.

    Args:
        email_type: EmailType enum value
        context: Dictionary of tag values for rendering

    Returns:
        Dict with 'subject', 'html', and 'text' keys
    """
    template = PuckEmailTemplate.get_or_create_for_type(email_type)
    return render_email(template, context or {})


def send_plain_email(
    subject: str,
    message: str,
    from_email: Optional[str],
    recipient_list: List[str],
    fail_silently: bool = False,
) -> int:
    """
    Send a plain text email, respecting the tenant's block_emails setting.

    This is a wrapper around Django's send_mail that checks if emails are blocked
    for the current tenant (e.g., demo accounts).

    Args:
        subject: Email subject line
        message: Email body text
        from_email: Sender email address
        recipient_list: List of recipient email addresses
        fail_silently: If True, suppress exceptions on send failure

    Returns:
        Number of emails sent (0 if blocked, 1 if sent)
    """
    from django.core.mail import send_mail

    # Check if emails are blocked for this tenant
    if is_email_blocked():
        logger.info(f"Email blocked for demo tenant: {subject} to {recipient_list}")
        return 1  # Return 1 to indicate "success" to callers

    return send_mail(
        subject=subject,
        message=message,
        from_email=from_email,
        recipient_list=recipient_list,
        fail_silently=fail_silently,
    )


def send_html_email(
    subject: str,
    message: str,
    from_email: Optional[str],
    recipient_list: List[str],
    html_message: Optional[str] = None,
    fail_silently: bool = False,
) -> int:
    """
    Send an email with HTML support, respecting the tenant's block_emails setting.

    This is a wrapper around Django's send_mail that checks if emails are blocked
    for the current tenant (e.g., demo accounts).

    Args:
        subject: Email subject line
        message: Plain text email body
        from_email: Sender email address
        recipient_list: List of recipient email addresses
        html_message: Optional HTML version of the email
        fail_silently: If True, suppress exceptions on send failure

    Returns:
        Number of emails sent (0 if blocked, 1 if sent)
    """
    from django.core.mail import send_mail

    # Check if emails are blocked for this tenant
    if is_email_blocked():
        logger.info(f"Email blocked for demo tenant: {subject} to {recipient_list}")
        return 1  # Return 1 to indicate "success" to callers

    return send_mail(
        subject=subject,
        message=message,
        from_email=from_email,
        recipient_list=recipient_list,
        html_message=html_message,
        fail_silently=fail_silently,
    )
