import logging
import smtplib
import ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from .base import BaseIntegration


logger = logging.getLogger(__name__)

class GmailIntegration(BaseIntegration):
    identifier = "gmail"
    logo_url = "https://upload.wikimedia.org/wikipedia/commons/7/7e/Gmail_icon_%282020%29.svg"
    
    config_definition = {
        "sender_email": {
            "label": "Sender Email Address",
            "type": "STRING",
            "required": True,
            "help_text": "The Gmail address sending the alert."
        },
        "app_password": { # TODO: Hash sensitive data before saving to db.
            "label": "App Password",
            "type": "PASSWORD",
            "required": True,
            "help_text": "Enable 2FA on Google and generate an App Password."
        },
        "recipient_email": {
            "label": "Recipient Email(s)",
            "type": "STRING",
            "required": True,
            "help_text": "Comma-separated list of people to notify."
        }
    }

    def run(self, footprint, context):
        config = self.get_config()
        
        sender_email = config.get("sender_email")
        password = config.get("app_password")
        recipients_str = config.get("recipient_email")

        if not (sender_email and password and recipients_str):
            logger.warning("INSIDER: Gmail integration missing required config.")
            return

        recipients = [r.strip() for r in recipients_str.split(",") if r.strip()]

        message = MIMEMultipart("alternative")
        
        subject_title = f"Error {footprint.status_code}"
        if hasattr(footprint, 'incidence') and footprint.incidence:
             subject_title = footprint.incidence.title

        message["Subject"] = f"[Insider Alert] {subject_title}"
        message["From"] = sender_email
        message["To"] = ", ".join(recipients)

        issues = context.get("generated_issues", [])
        if not issues and context.get("issue_url"):
             issues = [{
                 "system": context.get("issue_system"),
                 "url": context.get("issue_url"),
                 "key": context.get("issue_key")
             }]

        links_html = ""
        if issues:
            links_html = '<div style="margin-bottom: 20px;">'
            for issue in issues:
                sys = issue.get("system", "External")
                url = issue.get("url")
                key = issue.get("key", "View Ticket")
                links_html += (
                    f'<a href="{url}" style="background-color: #0052cc; color: white; padding: 8px 12px; text-decoration: none; border-radius: 4px; font-weight: bold; margin-right: 10px; display: inline-block;">'
                    f'View on {sys} ({key})'
                    f'</a>'
                )
            links_html += '</div>'

        html_content = (
            f"<html>"
            f"<body style='font-family: Arial, sans-serif; color: #333; line-height: 1.6;'>"
            f"<h2 style='color: #d32f2f; border-bottom: 2px solid #d32f2f; padding-bottom: 10px;'>"
            f"Insider Exception Alert"
            f"</h2>"
            f"{links_html}"
            f"<table style='width: 100%; border-collapse: collapse; margin-bottom: 20px;'>"
            f"<tr style='background-color: #f8f9fa;'>"
            f"<td style='padding: 8px; font-weight: bold; width: 120px;'>Request:</td>"
            f"<td style='padding: 8px; font-family: monospace;'>{footprint.request_method} {footprint.request_path}</td>"
            f"</tr>"
            f"<tr>"
            f"<td style='padding: 8px; font-weight: bold;'>Status:</td>"
            f"<td style='padding: 8px;'>{footprint.status_code}</td>"
            f"</tr>"
            f"<tr style='background-color: #f8f9fa;'>"
            f"<td style='padding: 8px; font-weight: bold;'>User:</td>"
            f"<td style='padding: 8px;'>{footprint.request_user or 'Anonymous'}</td>"
            f"</tr>"
            f"</table>"
            f"<h3 style='color: #555;'>Stack Trace</h3>"
            f"<pre style='background: #333; color: #fff; padding: 15px; border-radius: 4px; overflow-x: auto; font-size: 12px;'>"
            f"{self._format_stack_trace(footprint)}"
            f"</pre>"
            f"<p style='font-size: 12px; color: #999; margin-top: 20px; text-align: center;'>"
            f"Generated by Django Insider Pipeline"
            f"</p>"
            f"</body>"
            f"</html>"
        )

        message.attach(MIMEText(html_content, "html"))

        # Send via SMTP_SSL
        try:
            context = ssl.create_default_context()
            with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server:
                server.login(sender_email, password)
                server.sendmail(sender_email, recipients, message.as_string())
            
            logger.info(f"INSIDER: Sent email alert to {len(recipients)} recipients.")
            return {"email_sent": True}

        except Exception as e:
            logger.error(f"INSIDER: Gmail send failed: {e}")
            return {}

    def _format_stack_trace(self, footprint):
        """
        Helper to extract a clean string from the stack trace list.
        """
        
        if not footprint.stack_trace:
            return "No stack trace available."
        
        if isinstance(footprint.stack_trace, str):
            return footprint.stack_trace

        lines = []
        for frame in footprint.stack_trace:
            if isinstance(frame, dict):
                func = frame.get('function')
                line = frame.get('line')
                code = frame.get('code', '').strip()
                file_path = frame.get('file')
            else:
                func = frame.function
                line = frame.line
                code = frame.code.strip()
                file_path = frame.file
            lines.append(f"{file_path}:{line} in {func}\n    {code}")
        
        return "\n".join(lines)