#!/usr/bin/env python3
"""
Gmail triage for krspamgang@gmail.com
Implements full EMAIL-RULES.md ruleset via email_rules.py
"""

import json, os, sys, base64, subprocess
from datetime import datetime, timezone

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

TOKEN_PATH           = os.path.join(SCRIPT_DIR, 'token-krspamgang.json')
NOTIFIED_PATH        = os.path.join(SCRIPT_DIR, 'triage-krspamgang-notified.json')
PENDING_PATH         = os.path.join(SCRIPT_DIR, 'pending-gmail.txt')
UNKNOWN_SENDERS_PATH = os.path.join(SCRIPT_DIR, 'unknown-senders.json')
MAX_NOTIFIED         = 500
ACCOUNT              = 'gmail'
ACCOUNT_LABEL        = 'Gmail (krspamgang)'
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_notified():
    try:
        with open(NOTIFIED_PATH) as f:
            return set(json.load(f).get('ids', []))
    except Exception:
        return set()


def save_notified(ids):
    lst = list(ids)[-MAX_NOTIFIED:]
    with open(NOTIFIED_PATH, 'w') as f:
        json.dump({'ids': lst}, f)


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 get_body(payload):
    if payload.get('mimeType') == 'text/plain':
        data = payload.get('body', {}).get('data', '')
        if data:
            return base64.urlsafe_b64decode(data).decode('utf-8', errors='ignore')
    for part in payload.get('parts', []):
        result = get_body(part)
        if result:
            return result
    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():
    from google.oauth2.credentials import Credentials
    from google.auth.transport.requests import Request
    from googleapiclient.discovery import build

    with open(TOKEN_PATH) as f:
        data = json.load(f)
    creds = Credentials(
        token=data['token'], refresh_token=data['refresh_token'],
        token_uri=data['token_uri'], client_id=data['client_id'],
        client_secret=data['client_secret']
    )
    if creds.expired and creds.refresh_token:
        creds.refresh(Request())
        data['token'] = creds.token
        with open(TOKEN_PATH, 'w') as f:
            json.dump(data, f)

    service = build('gmail', 'v1', credentials=creds)
    notified = load_notified()
    unknown_senders = load_unknown_senders()
    new_notified = set(notified)
    unknown_updated = False

    result = service.users().messages().list(
        userId='me', labelIds=['INBOX', 'UNREAD'], maxResults=25
    ).execute()
    messages = result.get('messages', [])

    for msg in messages:
        msg_id = msg['id']
        if msg_id in notified:
            continue

        full = service.users().messages().get(
            userId='me', id=msg_id, format='full'
        ).execute()

        headers = {h['name'].lower(): h['value']
                   for h in full.get('payload', {}).get('headers', [])}
        sender  = headers.get('from', '')
        subject = headers.get('subject', '(no subject)')
        body    = get_body(full.get('payload', {}))

        new_notified.add(msg_id)

        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)

    save_notified(new_notified)
    if unknown_updated:
        save_unknown_senders(unknown_senders)


if __name__ == '__main__':
    main()
