# backend/app/connectors/mail/real_imap.py — IMAP(HEY/일반) sync 커넥터 (phase-13)
# 로컬 우선 대안: OAuth 불필요. UID SEARCH SINCE 증분 → 동일 normalize_email 로 귀결.
import email as email_lib
import imaplib
from datetime import UTC, datetime

from sqlmodel import Session

from ...crypto import decrypt_token  # token_enc 에 {host,user,password} 저장
from ..base import BaseConnector, NormalizedRecord, RawRecord
from .normalize import normalize_email, upsert_email


class ImapConnector(BaseConnector):
    domain = "mail"
    entity_type = "email"

    def fetch(self, session: Session, *, full: bool = False):
        creds = decrypt_token(self.account.token_enc)
        if not creds:
            raise PermissionError("imap credentials missing")
        m = imaplib.IMAP4_SSL(creds["host"])
        m.login(creds["user"], creds["password"])
        m.select("INBOX")
        crit = "ALL" if full else "UNSEEN"
        _typ, data = m.search(None, crit)
        for uid in data[0].split():
            _t, msgdata = m.fetch(uid, "(RFC822)")
            raw_bytes = msgdata[0][1]
            msg = email_lib.message_from_bytes(raw_bytes)
            payload = {
                "from": msg.get("From", ""),
                "subject": msg.get("Subject", ""),
                "to": msg.get("To", "나"),
                "preview": (
                    (msg.get_payload(decode=False) or "")[:120] if not msg.is_multipart() else ""
                ),
                "date": msg.get("Date", "방금"),
            }
            yield RawRecord(
                external_id=msg.get("Message-ID", uid.decode()),
                payload=payload,
                etag=msg.get("Date", ""),
                external_updated_at=datetime.now(UTC),
            )
        m.logout()

    def normalize(self, raw: RawRecord) -> NormalizedRecord:
        return normalize_email(self.account, raw, provider="imap")

    def write(self, session: Session, norm: NormalizedRecord):
        return upsert_email(session, norm)

    def event_for(self, norm, entity_id):
        return "mail.received"
