"""Business email (Namecheap Private Email, ahmad@revalstudio.com) for the
jarvis-tools service — plain SMTP+IMAP, stdlib only, creds from env. Ported from
the Mac email_control.py so it works from every device via the one connector.

Env:
  EMAIL_ADDRESS   the mailbox / From: address
  EMAIL_PASSWORD  its password
  EMAIL_SMTP_HOST / EMAIL_SMTP_PORT   default mail.privateemail.com : 465 (SSL)
  EMAIL_IMAP_HOST / EMAIL_IMAP_PORT   default mail.privateemail.com : 993 (SSL)

Note: sending on Namecheap has a ~15-30s delivery delay — 'sent' is real even if
it hasn't shown up yet. No local-file attachments (a remote server can't read the
caller's disk).
"""
from __future__ import annotations

import email
import imaplib
import os
import smtplib
from email.header import decode_header, make_header
from email.message import EmailMessage


def _addr() -> str:
    return os.environ.get("EMAIL_ADDRESS", "").strip()


def configured() -> bool:
    return bool(_addr() and os.environ.get("EMAIL_PASSWORD"))


def _decode(raw) -> str:
    if raw is None:
        return ""
    try:
        return str(make_header(decode_header(raw)))
    except Exception:  # noqa: BLE001
        return str(raw)


def _body_of(msg) -> str:
    if msg.is_multipart():
        for part in msg.walk():
            if (part.get_content_type() == "text/plain"
                    and "attachment" not in str(part.get("Content-Disposition"))):
                try:
                    return part.get_payload(decode=True).decode(
                        part.get_content_charset() or "utf-8", "replace")
                except Exception:  # noqa: BLE001
                    continue
        return "(no plain-text body)"
    try:
        return msg.get_payload(decode=True).decode(
            msg.get_content_charset() or "utf-8", "replace")
    except Exception:  # noqa: BLE001
        return str(msg.get_payload())


def _imap():
    host = os.environ.get("EMAIL_IMAP_HOST", "mail.privateemail.com")
    port = int(os.environ.get("EMAIL_IMAP_PORT", "993"))
    m = imaplib.IMAP4_SSL(host, port)
    m.login(_addr(), os.environ["EMAIL_PASSWORD"])
    return m


def send(to: str, subject: str, body: str, cc: str = "") -> str:
    to = str(to).strip()
    if not to:
        return "email_send failed: no recipient."
    host = os.environ.get("EMAIL_SMTP_HOST", "mail.privateemail.com")
    port = int(os.environ.get("EMAIL_SMTP_PORT", "465"))
    msg = EmailMessage()
    msg["From"] = _addr()
    msg["To"] = to
    if cc:
        msg["Cc"] = cc
    msg["Subject"] = subject
    msg.set_content(body)
    rcpts = [a.strip() for a in (to + "," + cc).split(",") if a.strip()]
    with smtplib.SMTP_SSL(host, port, timeout=30) as s:
        s.login(_addr(), os.environ["EMAIL_PASSWORD"])
        s.send_message(msg, to_addrs=rcpts)
    return (f"Sent '{subject}' to {to}" + (f" (cc {cc})" if cc else "")
            + ". (Namecheap can take ~15-30s to actually deliver.)")


def search(query: str, limit: int = 10) -> str:
    limit = max(1, min(int(limit or 10), 25))
    m = _imap()
    try:
        m.select("INBOX")
        if str(query).strip():
            typ, data = m.uid("search", None, "OR",
                              "FROM", f'"{query}"', "SUBJECT", f'"{query}"')
        else:
            typ, data = m.uid("search", None, "ALL")
        uids = data[0].split() if data and data[0] else []
        uids = uids[-limit:][::-1]
        if not uids:
            return "No matching messages."
        lines = []
        for uid in uids:
            typ, hd = m.uid("fetch", uid,
                            "(BODY.PEEK[HEADER.FIELDS (FROM SUBJECT DATE)])")
            hdr = email.message_from_bytes(hd[0][1]) if hd and hd[0] else None
            frm = _decode(hdr.get("From")) if hdr else "?"
            sub = _decode(hdr.get("Subject")) if hdr else "?"
            date = (hdr.get("Date") or "") if hdr else ""
            lines.append(f"[uid {uid.decode()}] {date}\n  from: {frm}\n  subj: {sub}")
        return "\n".join(lines)
    finally:
        try:
            m.logout()
        except Exception:  # noqa: BLE001
            pass


def read(uid: str) -> str:
    uid = str(uid).strip()
    if not uid:
        return "email_read failed: no uid."
    m = _imap()
    try:
        m.select("INBOX")
        typ, data = m.uid("fetch", uid.encode(), "(RFC822)")
        if not data or not data[0]:
            return f"No message with uid {uid}."
        msg = email.message_from_bytes(data[0][1])
        frm = _decode(msg.get("From"))
        sub = _decode(msg.get("Subject"))
        body = _body_of(msg)
        if len(body) > 5000:
            body = body[:5000] + "\n…(truncated)"
        return f"From: {frm}\nSubject: {sub}\n\n{body}"
    finally:
        try:
            m.logout()
        except Exception:  # noqa: BLE001
            pass
