#!/usr/bin/env python3
"""
ProtonMail triage for sendinthecavalry@proton.me via Bridge IMAP
Implements full EMAIL-RULES.md ProtonMail ruleset via email_rules.py
"""

import imaplib, email as emaillib, json, os, sys, subprocess
from email.header import decode_header
from datetime import datetime, timezone

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, SCRIPT_DIR)

STATE_PATH           = os.path.join(SCRIPT_DIR, 'proton-state.json')
PENDING_PATH         = os.path.join(SCRIPT_DIR, 'pending-proton.txt')
UNKNOWN_SENDERS_PATH = os.path.join(SCRIPT_DIR, 'unknown-senders.json')
IMAP_HOST            = '127.0.0.1'
IMAP_PORT            = 1143
IMAP_USER            = 'sendinthecavalry@proton.me'
IMAP_PASS            = 'ec1uaIj_m1ioSR_-GB6nFA'
ACCOUNT              = 'proton'
ACCOUNT_LABEL        = 'ProtonMail'
EMAILS_GROUP         = 'group:gpmzW1ck/krcQcMsQDJVQBBBOQCsfR9e4Rq1Mgu/uN8='

from email_rules import (
    classify, extract_email_address, get_display_name, subject_action_override,
    IMPORTANT, PRIORITY, CORRESPONDENCE, COMMERCE_NOTIFY,
    SILENT_TIERS, NOTIFY_TIERS, UNKNOWN,
)


def load_unknown_senders():
    try:
        with open(UNKNOWN_SENDERS_PATH) as f:
            return json.load(f)
    except Exception:
        return {}


def save_unknown_senders(data):
    with open(UNKNOWN_SENDERS_PATH, 'w') as f:
        json.dump(data, f, indent=2)


def send_unknown_alert(name, email_addr, subject):
    msg = (
        f"Unknown sender on {ACCOUNT_LABEL}: {name} <{email_addr}>\n"
        f"Subject: {subject}\n"
        f"Add to EMAIL-RULES.md?"
    )
    subprocess.run([
        '/opt/homebrew/bin/openclaw', 'message', 'send',
        '--channel', 'signal',
        '--target', EMAILS_GROUP,
        '--message', msg,
    ], check=False)


def decode_header_value(val):
    if not val:
        return ''
    parts = decode_header(val)
    result = ''
    for part, charset in parts:
        if isinstance(part, bytes):
            result += part.decode(charset or 'utf-8', errors='ignore')
        else:
            result += part
    return result


def get_text_body(msg):
    if msg.is_multipart():
        for part in msg.walk():
            if part.get_content_type() == 'text/plain':
                payload = part.get_payload(decode=True)
                if payload:
                    return payload.decode('utf-8', errors='ignore')
    else:
        payload = msg.get_payload(decode=True)
        if payload:
            return payload.decode('utf-8', errors='ignore')
    return ''


def prepend_pending(line):
    existing = ''
    if os.path.exists(PENDING_PATH):
        with open(PENDING_PATH) as f:
            existing = f.read()
    with open(PENDING_PATH, 'w') as f:
        f.write(line + '\n' + existing)


def append_pending(line):
    with open(PENDING_PATH, 'a') as f:
        f.write(line + '\n')


def main():
    unknown_senders = load_unknown_senders()
    unknown_updated = False

    conn = imaplib.IMAP4(IMAP_HOST, IMAP_PORT)
    conn.login(IMAP_USER, IMAP_PASS)
    conn.select('INBOX')

    _, data = conn.uid('search', None, 'UNSEEN')
    uid_list = data[0].split() if data[0] else []

    if not uid_list:
        conn.logout()
        return

    for uid_bytes in uid_list:
        _, msg_data = conn.uid('fetch', uid_bytes, '(RFC822)')
        if not msg_data or not msg_data[0]:
            continue

        raw = msg_data[0][1]
        msg = emaillib.message_from_bytes(raw)

        sender  = decode_header_value(msg.get('From', ''))
        subject = decode_header_value(msg.get('Subject', '(no subject)'))
        body    = get_text_body(msg)

        tier = classify(sender, subject, body, ACCOUNT)

        action_override = subject_action_override(subject)
        if action_override and tier in SILENT_TIERS:
            tier = COMMERCE_NOTIFY

        email_addr   = extract_email_address(sender)
        display_name = get_display_name(sender)

        if tier == UNKNOWN:
            if email_addr not in unknown_senders:
                unknown_senders[email_addr] = {
                    'first_seen': datetime.now(timezone.utc).strftime('%Y-%m-%d'),
                    'name':       display_name,
                    'account':    ACCOUNT_LABEL,
                }
                unknown_updated = True
                send_unknown_alert(display_name, email_addr, subject)
            continue

        if tier in SILENT_TIERS:
            continue

        prefix = 'IMPORTANT' if tier == IMPORTANT else ACCOUNT_LABEL
        entry  = f"{prefix}|{display_name} <{email_addr}>|{subject}"

        if tier == IMPORTANT:
            prepend_pending(entry)
        else:
            append_pending(entry)

    conn.logout()

    if unknown_updated:
        save_unknown_senders(unknown_senders)


if __name__ == '__main__':
    main()
