"""
BizNode Email Service
===================
SMTP email service for owner and associate communications.

Supports:
- Owner notifications
- Lead notifications
- Associate network emails
- AI agent emails
"""

import importlib.util
import logging
import os
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from pathlib import Path
from typing import Dict, Any, Optional
from email.mime.image import MIMEImage
import json

log = logging.getLogger(__name__)
_PROJECT_ROOT = Path(__file__).resolve().parent.parent

# ── HTML Template Engine ─────────────────────────────────────────────────

STYLE_MAP = {
    "1": "style_1_professional.html",
    "2": "style_2_modern.html",
    "3": "style_3_elegant.html",
    "4": "style_4_bold.html",
    "5": "style_5_minimal.html",
}


def _load_template(style: str = "1") -> Optional[str]:
    """Load an HTML email template by style number."""
    filename = STYLE_MAP.get(str(style), STYLE_MAP["1"])
    tpl_path = _PROJECT_ROOT / "templates" / filename
    if tpl_path.exists():
        return tpl_path.read_text(encoding="utf-8")
    log.warning("Email template not found: %s", tpl_path)
    return None


def wrap_body_in_template(subject: str, body: str, style: str = "1") -> Optional[str]:
    """Wrap plain-text body content into an HTML template.

    Replaces {{SUBJECT}}, {{BODY}}, {{BUSINESS_NAME}} placeholders.
    Converts newlines in body to <br> for HTML rendering.
    Returns None if template cannot be loaded.
    """
    tpl = _load_template(style)
    if not tpl:
        return None
    business_name = os.getenv("BUSINESS_NAME", "BizNode")
    html_body = body.replace("\n", "<br>\n")
    html = tpl.replace("{{SUBJECT}}", subject)
    html = html.replace("{{BODY}}", html_body)
    html = html.replace("{{BUSINESS_NAME}}", business_name)
    return html


def _log_sent(to_addr, subject, body_preview, email_type="general", status="ok", error_msg="", from_addr=""):
    try:
        spec = importlib.util.spec_from_file_location("_db", str(_PROJECT_ROOT / "memory" / "database.py"))
        mod  = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(mod)
        mod.log_email_sent(
            to_addr=to_addr, subject=subject, body_preview=body_preview,
            email_type=email_type, status=status, error_msg=error_msg, from_addr=from_addr,
        )
    except Exception as exc:
        log.warning("email_log write failed: %s", exc)

# Configuration
SMTP_HOST = os.getenv("SMTP_HOST", "smtp.gmail.com")
SMTP_PORT = int(os.getenv("SMTP_PORT", "587"))
SMTP_USER = os.getenv("SMTP_USER", "")
SMTP_PASSWORD = os.getenv("SMTP_PASSWORD", "")
AGENT_EMAIL = os.getenv("AGENT_EMAIL", "")


class EmailService:
    """Email service for BizNode communications."""
    
    def __init__(
        self,
        smtp_host: str = None,
        smtp_port: int = None,
        smtp_user: str = None,
        smtp_password: str = None,
        from_email: str = None
    ):
        self.smtp_host = smtp_host or SMTP_HOST
        self.smtp_port = smtp_port or SMTP_PORT
        self.smtp_user = smtp_user or SMTP_USER
        self.smtp_password = smtp_password or SMTP_PASSWORD
        self.from_email = from_email or AGENT_EMAIL or smtp_user
    
    def _create_message(
        self,
        to_email: str,
        subject: str,
        body: str,
        html: str = None
    ) -> MIMEMultipart:
        """Create email message with optional inline logo."""
        if html and "cid:biznode_logo" in html:
            # Use mixed/related structure for inline images
            msg = MIMEMultipart('related')
            msg['From'] = self.from_email
            msg['To'] = to_email
            msg['Subject'] = subject

            alt_part = MIMEMultipart('alternative')
            alt_part.attach(MIMEText(body, 'plain'))
            alt_part.attach(MIMEText(html, 'html'))
            msg.attach(alt_part)

            # Attach logo inline
            logo_path = _PROJECT_ROOT / "logos" / "logo.png"
            if logo_path.exists():
                with open(logo_path, "rb") as f:
                    img = MIMEImage(f.read(), _subtype="png")
                    img.add_header("Content-ID", "<biznode_logo>")
                    img.add_header("Content-Disposition", "inline", filename="logo.png")
                    msg.attach(img)
        else:
            msg = MIMEMultipart('alternative')
            msg['From'] = self.from_email
            msg['To'] = to_email
            msg['Subject'] = subject
            msg.attach(MIMEText(body, 'plain'))
            if html:
                msg.attach(MIMEText(html, 'html'))

        return msg
    
    def send_email(
        self,
        to_email: str,
        subject: str,
        body: str,
        html: str = None,
        cc: str = None
    ) -> Dict[str, Any]:
        """
        Send an email.
        
        Args:
            to_email: Recipient email
            subject: Email subject
            body: Plain text body
            html: Optional HTML body
            cc: Optional CC recipients
        
        Returns:
            Success status and message
        """
        if not self.smtp_user or not self.smtp_password:
            return {
                "success": False,
                "error": "SMTP not configured"
            }

        try:
            # Auto-apply HTML template if EMAIL_FORMAT=html and no explicit html
            if not html and os.getenv("EMAIL_FORMAT", "text").lower() == "html":
                style = os.getenv("EMAIL_STYLE", "1")
                html = wrap_body_in_template(subject, body, style)

            msg = self._create_message(to_email, subject, body, html)
            
            if cc:
                msg['Cc'] = cc
            
            # Connect to SMTP server
            server = smtplib.SMTP(self.smtp_host, self.smtp_port, timeout=15)
            server.starttls()
            server.login(self.smtp_user, self.smtp_password)
            
            # Send
            recipients = [to_email]
            if cc:
                recipients.append(cc)
            
            server.sendmail(self.from_email, recipients, msg.as_string())
            server.quit()

            _log_sent(
                to_addr=to_email, subject=subject,
                body_preview=(body or "")[:500],
                email_type=getattr(self, "_email_type", "general"),
                status="ok", from_addr=self.from_email,
            )
            return {
                "success": True,
                "message": f"Email sent to {to_email}"
            }

        except Exception as e:
            _log_sent(
                to_addr=to_email, subject=subject,
                body_preview=(body or "")[:500],
                email_type=getattr(self, "_email_type", "general"),
                status="failed", error_msg=str(e), from_addr=self.from_email,
            )
            return {
                "success": False,
                "error": str(e)
            }
    
    def send_html_email(
        self,
        to_email: str,
        subject: str,
        html_content: str
    ) -> Dict[str, Any]:
        """Send HTML email."""
        return self.send_email(
            to_email=to_email,
            subject=subject,
            body="Please enable HTML to view this email.",
            html=html_content
        )


# === Email Templates ===

def format_lead_notification_email(lead: Dict) -> tuple:
    """Format lead notification email."""
    subject = "🔔 New Business Lead - Action Required"
    
    body = f"""
New Business Lead Received
========================

Name: {lead.get('name', 'Unknown')}
Business: {lead.get('business', 'Not specified')}
Contact: {lead.get('contact_info', 'Not provided')}

Summary:
{lead.get('summary', 'No summary available')}

Source: {lead.get('source', 'Unknown')}

Please log in to review and take action.
"""
    
    html = f"""
<!DOCTYPE html>
<html>
<head>
    <style>
        body {{ font-family: Arial, sans-serif; line-height: 1.6; }}
        .header {{ background: #4F46E5; color: white; padding: 20px; }}
        .content {{ padding: 20px; background: #f9f9f9; }}
        .label {{ font-weight: bold; color: #374151; }}
    </style>
</head>
<body>
    <div class="header">
        <h2>🔔 New Business Lead</h2>
    </div>
    <div class="content">
        <p><span class="label">Name:</span> {lead.get('name', 'Unknown')}</p>
        <p><span class="label">Business:</span> {lead.get('business', 'Not specified')}</p>
        <p><span class="label">Contact:</span> {lead.get('contact_info', 'Not provided')}</p>
        <p><span class="label">Summary:</span><br>{lead.get('summary', 'No summary')}</p>
        <p><span class="label">Source:</span> {lead.get('source', 'Unknown')}</p>
    </div>
</body>
</html>
"""
    
    return subject, body, html


def format_approval_request_email(action: Dict) -> tuple:
    """Format approval request email."""
    subject = "⚠️ Action Requires Your Approval"
    
    body = f"""
Approval Request
================

Type: {action.get('action_type', 'Unknown')}
Risk Level: {action.get('risk_level', 'low').upper()}

Data:
{json.dumps(action.get('data', {}), indent=2)}

Please respond with APPROVE or REJECT via Telegram.
"""
    
    html = f"""
<!DOCTYPE html>
<html>
<head>
    <style>
        body {{ font-family: Arial, sans-serif; }}
        .warning {{ background: #FEF3C7; padding: 20px; border-left: 4px solid #F59E0B; }}
    </style>
</head>
<body>
    <div class="warning">
        <h2>⚠️ Approval Required</h2>
        <p><strong>Type:</strong> {action.get('action_type')}</p>
        <p><strong>Risk Level:</strong> {action.get('risk_level', 'low').upper()}</p>
        <p><strong>Data:</strong> {json.dumps(action.get('data', {}))}</p>
    </div>
    <p>Please respond via Telegram.</p>
</body>
</html>
"""
    
    return subject, body, html


def format_network_intro_email(associate: Dict, lead: Dict) -> tuple:
    """Format network introduction email."""
    subject = "🤝 Network Opportunity - Introduction Request"
    
    body = f"""
Network Opportunity
==================

A new lead has been identified that matches your profile.

Lead: {lead.get('name', 'Unknown')}
Business: {lead.get('business', '')}

Your Role: {associate.get('role', 'Partner')}

Would you like us to facilitate an introduction?
Reply via Telegram to proceed.
"""
    
    return subject, body, None


# === Convenience Functions ===

def notify_owner_email(owner_email: str, lead: Dict) -> Dict:
    """Send lead notification to owner."""
    service = EmailService()
    service._email_type = "lead_notification"
    subject, body, html = format_lead_notification_email(lead)
    return service.send_email(owner_email, subject, body, html)


def send_approval_request(owner_email: str, action: Dict) -> Dict:
    """Send approval request to owner."""
    service = EmailService()
    service._email_type = "approval_request"
    subject, body, html = format_approval_request_email(action)
    return service.send_email(owner_email, subject, body, html)


def send_agent_email(
    to_email: str,
    subject: str,
    body: str,
    html: str = None
) -> Dict:
    """Send email from AI agent email address."""
    service = EmailService()
    service._email_type = "agent_email"
    return service.send_email(to_email, subject, body, html)


# === Initialize ===

def init_email_service() -> EmailService:
    """Initialize email service with config."""
    return EmailService()


if __name__ == "__main__":
    service = init_email_service()
    print(f"SMTP Configured: {service.smtp_host}:{service.smtp_port}")
