"""Turns one inbound email into Document/IntakeEvent rows.

Kept separate from the IMAP connection logic (in scripts/fetch_email_documents.py)
so this part — the actual business logic — can be unit tested with a plain
EmailMessage object, without needing a real mailbox. The actual filing rules
(single profile / ambiguous / rejected) live in app.processing.intake_common,
shared with every other channel.
"""
from flask import current_app

from app.extensions import db
from app.models import IntakeEvent, User
from app.processing.intake_common import file_attachments_for_user


def _find_user_by_email(sender_email: str):
    if not sender_email:
        return None
    return User.query.filter(db.func.lower(User.email) == sender_email.lower()).first()


def _extract_attachments(msg) -> list[tuple[str, bytes]]:
    try:
        parts = list(msg.iter_attachments())
    except AttributeError:
        parts = []  # message wasn't built with a MIME-aware policy

    max_size = current_app.config["MAX_CONTENT_LENGTH"]
    attachments = []
    for part in parts:
        filename = part.get_filename()
        content = part.get_content()
        if not filename or not isinstance(content, (bytes, bytearray)):
            continue
        if len(content) > max_size:
            continue
        attachments.append((filename, bytes(content)))
    return attachments


def process_email_message(msg) -> list[IntakeEvent]:
    """msg: an email.message.EmailMessage (policy=email.policy.default).

    Returns the IntakeEvent(s) created (added to the session, not committed —
    the caller controls the transaction, one email per commit).
    """
    from email.utils import parseaddr

    _, sender_email = parseaddr(msg.get("From", ""))
    subject = msg.get("Subject", "") or ""
    user = _find_user_by_email(sender_email)

    if user is None:
        event = IntakeEvent(
            channel="email",
            status=IntakeEvent.STATUS_UNMATCHED_SENDER,
            sender_identifier=sender_email,
            subject=subject,
            notes="Ninguna cuenta registrada usa este correo.",
        )
        db.session.add(event)
        return [event]

    attachments = _extract_attachments(msg)
    return file_attachments_for_user(
        user, attachments, channel="email", sender_identifier=sender_email, subject=subject
    )
