"""Send emails via SMTP using markdown templates with markdown_merge."""

# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/05_utils_email.ipynb.

# %% ../nbs/05_utils_email.ipynb #287ff563
from __future__ import annotations
from typing import Optional, List, Dict, Any
import os
import logging
from pathlib import Path
from nbdev.showdoc import show_doc

logger = logging.getLogger(__name__)

# %% auto #0
__all__ = ['logger', 'get_smtp_config', 'get_template_path', 'load_template', 'send_email', 'send_batch_emails',
           'send_welcome_email', 'send_invitation_email', 'send_password_reset_email']

# %% ../nbs/05_utils_email.ipynb #36890cc9
def get_smtp_config() -> Dict[str, Any]:
    """Load SMTP configuration from environment variables."""
    smtp_host = os.getenv('SMTP_HOST')
    smtp_port = int(os.getenv('SMTP_PORT', '587'))
    smtp_user = os.getenv('SMTP_USER')
    smtp_pass = os.getenv('SMTP_PASSWORD')
    from_email = os.getenv('SMTP_MAIL_FROM')
    
    # SSL and TLS settings - check string and boolean values
    smtp_ssl = os.getenv('SMTP_SSL', 'False')
    use_ssl = smtp_ssl.lower() in ('true', '1', 'yes') if isinstance(smtp_ssl, str) else bool(smtp_ssl)
    
    smtp_starttls = os.getenv('SMTP_STARTTLS', 'True')
    use_tls = smtp_starttls.lower() in ('true', '1', 'yes') if isinstance(smtp_starttls, str) else bool(smtp_starttls)
    
    # If SSL is enabled, disable TLS
    if use_ssl:
        use_tls = False
    
    # Validate required fields
    if not all([smtp_host, smtp_user, smtp_pass, from_email]):
        raise ValueError(
            "SMTP_HOST, SMTP_USER, SMTP_PASSWORD, and SMTP_MAIL_FROM "
            "environment variables are required"
        )
    
    return {
        'host': smtp_host,
        'port': smtp_port,
        'user': smtp_user,
        'password': smtp_pass,
        'from_email': from_email,
        'from_name': '',  # Optional, can be added as SMTP_FROM_NAME if needed
        'use_ssl': use_ssl,
        'use_tls': use_tls
    }

# %% ../nbs/05_utils_email.ipynb #2711e696
def get_template_path(
    template_name: str,  # Template basename (e.g., 'welcome', 'invitation')
    custom_template_path: Optional[str | Path] = None  # Custom path overrides package templates
) -> Path:
    """Get absolute path to email template file."""
    if custom_template_path:
        custom_path = Path(custom_template_path)
        if not custom_path.exists():
            raise FileNotFoundError(f"Custom template not found: {custom_path}")
        return custom_path
    else:
        package_dir = Path(__file__).parent if '__file__' in globals() else Path.cwd()
        template_path = package_dir / 'templates' / f'{template_name}.md'
        
        if not template_path.exists():
            raise FileNotFoundError(
                f"Template not found: {template_path}\n"
                f"Available templates: welcome, invitation, password_reset\n"
                f"Or provide custom_template_path parameter"
            )
        
        return template_path


def load_template(
    template_name: str,  # Template basename (e.g., 'welcome')
    custom_template_path: Optional[str | Path] = None  # Custom path overrides package templates
) -> str:
    """Load markdown email template as string."""
    template_path = get_template_path(template_name, custom_template_path)
    return template_path.read_text(encoding='utf-8')

# %% ../nbs/05_utils_email.ipynb #70940428
def send_email(
    to_email: str,  # Recipient email address
    to_name: str,  # Recipient display name
    subject: str,  # Email subject line
    template_name: str,  # Template name: 'welcome', 'invitation', 'password_reset'
    template_vars: Dict[str, str],  # Variables to substitute in template
    test: bool = False,  # If True, prints email instead of sending
    smtp_config: Optional[Dict[str, Any]] = None,  # Custom SMTP config (defaults to env vars)
    custom_template_path: Optional[str | Path] = None  # Custom template path
) -> Dict[str, Any]:
    """Send single email using markdown template with variable substitution."""
    try:
        from markdown_merge import MarkdownMerge, get_addr
    except ImportError:
        raise ImportError(
            "markdown_merge not installed. Install with: pip install markdown_merge"
        )
    
    # Load SMTP config
    if smtp_config is None:
        config = get_smtp_config()
    else:
        config = smtp_config
    
    # Prepare SMTP config for markdown_merge
    mm_smtp_cfg = {
        'host': config['host'],
        'port': config['port'],
        'user': config['user'],
        'password': config['password'],
        'use_ssl': config.get('use_ssl', False),
        'use_tls': config.get('use_tls', True)
    }
    
    # Load template (supports custom path)
    template = load_template(template_name, custom_template_path)
    
    # Prepare addresses
    from_addr = get_addr(config['from_email'], config.get('from_name', ''))
    to_addr = get_addr(to_email, to_name)
    
    # Create MarkdownMerge instance
    mm = MarkdownMerge(
        [to_addr],
        from_addr,
        subject,
        template,
        smtp_cfg=mm_smtp_cfg,
        inserts=[template_vars],
        test=test
    )
    
    # Send email
    try:
        mm.send_msgs()
        
        if test:
            logger.info(f"Test email printed for {to_email}")
            return {
                "status": "test",
                "to_email": to_email,
                "message": "Email printed (test mode)"
            }
        else:
            logger.info(f"Email sent successfully to {to_email}")
            return {
                "status": "success",
                "to_email": to_email,
                "subject": subject
            }
    except Exception as e:
        logger.error(f"Failed to send email to {to_email}: {str(e)}")
        return {
            "status": "error",
            "to_email": to_email,
            "error": str(e)
        }

# %% ../nbs/05_utils_email.ipynb #8bb47a55
def send_batch_emails(
    recipients: List[Dict[str, str]],  # List of dicts with 'email' and 'name' keys
    subject: str,  # Email subject line
    template_name: str,  # Template name: 'welcome', 'invitation', 'password_reset'
    template_vars_list: List[Dict[str, str]],  # List of variable dicts, one per recipient
    test: bool = False,  # If True, prints emails instead of sending
    pause: float = 0.2,  # Seconds between emails (rate limiting)
    smtp_config: Optional[Dict[str, Any]] = None,  # Custom SMTP config
    custom_template_path: Optional[str | Path] = None  # Custom template path
) -> List[Dict[str, Any]]:
    """Send personalized emails to multiple recipients."""
    try:
        from markdown_merge import MarkdownMerge, get_addr
    except ImportError:
        raise ImportError(
            "markdown_merge not installed. Install with: pip install markdown_merge"
        )
    
    # Load SMTP config
    if smtp_config is None:
        config = get_smtp_config()
    else:
        config = smtp_config
    
    # Prepare SMTP config for markdown_merge
    mm_smtp_cfg = {
        'host': config['host'],
        'port': config['port'],
        'user': config['user'],
        'password': config['password'],
        'use_ssl': config.get('use_ssl', False),
        'use_tls': config.get('use_tls', True)
    }
    
    # Load template (supports custom path)
    template = load_template(template_name, custom_template_path)
    
    # Prepare addresses
    from_addr = get_addr(config['from_email'], config.get('from_name', ''))
    to_addrs = [get_addr(r['email'], r['name']) for r in recipients]
    
    # Create MarkdownMerge instance
    mm = MarkdownMerge(
        to_addrs,
        from_addr,
        subject,
        template,
        smtp_cfg=mm_smtp_cfg,
        inserts=template_vars_list,
        test=test
    )
    
    # Send emails
    results = []
    try:
        mm.send_msgs(pause=pause)
        
        for recipient in recipients:
            if test:
                results.append({
                    "status": "test",
                    "to_email": recipient['email'],
                    "message": "Email printed (test mode)"
                })
            else:
                results.append({
                    "status": "success",
                    "to_email": recipient['email'],
                    "subject": subject
                })
        
        logger.info(f"Sent {len(recipients)} emails successfully")
    except Exception as e:
        logger.error(f"Batch send failed: {str(e)}")
        for recipient in recipients:
            results.append({
                "status": "error",
                "to_email": recipient['email'],
                "error": str(e)
            })
    
    return results

# %% ../nbs/05_utils_email.ipynb #3f8765b9
def send_welcome_email(
    to_email: str,  # Recipient email address
    to_name: str,  # Recipient display name
    user_name: str,  # User's name for personalization
    tenant_name: str,  # Tenant/organization name
    dashboard_url: str,  # URL to user's dashboard
    test: bool = False,  # If True, prints email instead of sending
    custom_template_path: Optional[str | Path] = None  # Custom welcome.md template path
) -> Dict[str, Any]:
    """Send welcome email to new user. Template vars: {user_name}, {tenant_name}, {dashboard_url}, {to_email}"""
    return send_email(
        to_email=to_email,
        to_name=to_name,
        subject=f"Welcome to {tenant_name}!",
        template_name='welcome',
        template_vars={
            'user_name': user_name,
            'tenant_name': tenant_name,
            'dashboard_url': dashboard_url,
            'to_email': to_email
        },
        test=test,
        custom_template_path=custom_template_path
    )

# %% ../nbs/05_utils_email.ipynb #21ac6df3
def send_invitation_email(
    to_email: str,  # Recipient email address
    to_name: str,  # Recipient display name
    inviter_name: str,  # Name of person sending invitation
    tenant_name: str,  # Tenant/organization name
    invitation_url: str,  # URL to accept invitation
    test: bool = False,  # If True, prints email instead of sending
    custom_template_path: Optional[str | Path] = None  # Custom invitation.md template path
) -> Dict[str, Any]:
    """Send invitation email. Template vars: {inviter_name}, {tenant_name}, {invitation_url}, {to_email}"""
    return send_email(
        to_email=to_email,
        to_name=to_name,
        subject=f"{inviter_name} invited you to join {tenant_name}",
        template_name='invitation',
        template_vars={
            'inviter_name': inviter_name,
            'tenant_name': tenant_name,
            'invitation_url': invitation_url,
            'to_email': to_email
        },
        test=test,
        custom_template_path=custom_template_path
    )

# %% ../nbs/05_utils_email.ipynb #f7285c99
def send_password_reset_email(
    to_email: str,  # Recipient email address
    to_name: str,  # Recipient display name
    user_name: str,  # User's name for personalization
    reset_url: str,  # Secure password reset URL
    test: bool = False,  # If True, prints email instead of sending
    custom_template_path: Optional[str | Path] = None  # Custom password_reset.md template path
) -> Dict[str, Any]:
    """Send password reset email. Template vars: {user_name}, {reset_url}, {to_email}"""
    return send_email(
        to_email=to_email,
        to_name=to_name,
        subject="Reset Your Password",
        template_name='password_reset',
        template_vars={
            'user_name': user_name,
            'reset_url': reset_url,
            'to_email': to_email
        },
        test=test,
        custom_template_path=custom_template_path
    )
