import re

from backend.config import GOOGLE_API_SUPPORT, OUTLOOK_SUPPORT, _google_service, _outlook_session
from backend.gmail_helpers_runtime import _gmail_extract_plain_text_body
from backend.mail_helpers_runtime import _outlook_get_mail_item


_EMAIL_HTML_SCRIPT_RE = re.compile(r"<script\b[^>]*>[\s\S]*?</script>", re.IGNORECASE)
_EMAIL_HTML_SCRIPT_SELF_CLOSING_RE = re.compile(r"<script\b[^>]*?/>", re.IGNORECASE)
_EMAIL_HTML_EVENT_ATTR_RE = re.compile(r"\s+on[a-z0-9_-]+\s*=\s*(?:\"[^\"]*\"|'[^']*'|[^\s>]+)", re.IGNORECASE)
_EMAIL_HTML_JS_URL_RE = re.compile(r"(href|src)\s*=\s*(\"|')\s*javascript:[^\"']*(\2)", re.IGNORECASE)
_EMAIL_HTML_META_REFRESH_RE = re.compile(r"<meta\b[^>]*http-equiv\s*=\s*(\"|')?refresh\1?[^>]*>", re.IGNORECASE)
_EMAIL_HTML_META_RE = re.compile(r"<meta\b[^>]*>", re.IGNORECASE)
_EMAIL_HTML_LINK_RE = re.compile(r"<link\b[^>]*>", re.IGNORECASE)
_EMAIL_HTML_OBJECT_RE = re.compile(r"<(?:object|embed|iframe)\b[^>]*>[\s\S]*?</(?:object|embed|iframe)>", re.IGNORECASE)
_EMAIL_HTML_CID_URL_RE = re.compile(r"(href|src|poster|background)\s*=\s*(\"|')\s*cid:[^\"']*(\2)", re.IGNORECASE)
_EMAIL_HTML_CSS_CID_RE = re.compile(r"url\((\"|')?\s*cid:[^)]+\)", re.IGNORECASE)


def _wrap_plain_text_email_html(body: str) -> str:
    import html as _html_mod

    return (
        "<!DOCTYPE html><html><body style='font-family:sans-serif;"
        "white-space:pre-wrap;font-size:14px'>"
        + _html_mod.escape(body)
        + "</body></html>"
    )


def _sanitize_email_html(html: str) -> str:
    value = str(html or "").strip()
    if not value:
        return ""
    value = _EMAIL_HTML_SCRIPT_RE.sub("", value)
    value = _EMAIL_HTML_SCRIPT_SELF_CLOSING_RE.sub("", value)
    value = _EMAIL_HTML_META_REFRESH_RE.sub("", value)
    value = _EMAIL_HTML_META_RE.sub("", value)
    value = _EMAIL_HTML_LINK_RE.sub("", value)
    value = _EMAIL_HTML_OBJECT_RE.sub("", value)
    value = _EMAIL_HTML_EVENT_ATTR_RE.sub("", value)
    value = _EMAIL_HTML_JS_URL_RE.sub(r"\1=\2#\3", value)
    value = _EMAIL_HTML_CID_URL_RE.sub(r"\1=\2#\3", value)
    value = _EMAIL_HTML_CSS_CID_RE.sub("url('')", value)
    return value


def _outlook_get_email_html(message_id: str) -> str:
    """Return the HTMLBody of an Outlook email, or plain-text fallback."""
    if not OUTLOOK_SUPPORT:
        return ""
    mid = str(message_id or "").strip()
    if not mid:
        return ""
    try:
        with _outlook_session() as (_, ns):
            msg = _outlook_get_mail_item(ns, mid)
            if not msg:
                return ""
            html = (getattr(msg, "HTMLBody", None) or "").strip()
            if html:
                return _sanitize_email_html(html)
            body = (getattr(msg, "Body", None) or "").strip()
            if body:
                return _wrap_plain_text_email_html(body)
            return ""
    except Exception:
        return ""


def _gmail_get_email_html(message_id: str) -> str:
    """Return the HTML part of a Gmail message, or plain-text fallback."""
    if not GOOGLE_API_SUPPORT:
        return ""
    service = _google_service("gmail", "v1")
    if not service:
        return ""
    mid = str(message_id or "").strip()
    if not mid:
        return ""
    try:
        msg = service.users().messages().get(
            userId="me", id=mid, format="full",
        ).execute()

        def _find_html(payload: dict) -> str:
            mime = str(payload.get("mimeType") or "")
            parts = payload.get("parts") or []
            if mime == "text/html":
                data = (payload.get("body") or {}).get("data") or ""
                if data:
                    import base64

                    return base64.urlsafe_b64decode(data + "==").decode("utf-8", errors="replace")
            for part in parts:
                result = _find_html(part)
                if result:
                    return result
            return ""

        html = _find_html(msg.get("payload") or {})
        if html:
            return _sanitize_email_html(html)
        plain = _gmail_extract_plain_text_body(msg.get("payload") or {})
        if plain:
            return _wrap_plain_text_email_html(plain)
        return ""
    except Exception:
        return ""