#!/usr/bin/env python3
"""
Gmail Presale Monitor
Scans Gmail for presale-related emails and alerts via Telegram.
Designed to run via cron every 5 minutes.

State file: ~/.openclaw/workspace/scripts/presale-monitor-state.json
"""

import imaplib
import email
import os
import sys
import json
import urllib.request
import urllib.parse
from datetime import datetime, timedelta
from email.header import decode_header

# Config
GMAIL_USER = 'mikeziarko@gmail.com'
GMAIL_PWD_FILE = os.path.expanduser('~/.openclaw/secrets/gmail-app-password.txt')
BOT_TOKEN = '7764678817:AAH1_A4woI2gKd13gSfRF_uAStowKxsKARg'
CHAT_ID = '8792051045'
STATE_FILE = os.path.expanduser('~/.openclaw/workspace/scripts/presale-monitor-state.json')

# Keywords to match in subject or sender
PRESALE_KEYWORDS = [
    'presale', 'pre-sale', 'pre sale',
    'front of the line', 'early access',
    'exclusive access', 'member sale',
    'verified fan', 'fan presale',
    'priority access', 'first access',
]

# Only check these folders (avoids scanning huge All Mail)
FOLDERS_TO_CHECK = [
    'INBOX',
    '"[Gmail]/Promotions"',
]

def decode_header_value(value):
    if not value:
        return ''
    decoded = decode_header(value)
    parts = []
    for part, charset in decoded:
        if isinstance(part, bytes):
            parts.append(part.decode(charset or 'utf-8', errors='replace'))
        else:
            parts.append(str(part))
    return ''.join(parts)

def load_state():
    if os.path.exists(STATE_FILE):
        with open(STATE_FILE) as f:
            return json.load(f)
    return {'alerted_ids': []}

def save_state(state):
    with open(STATE_FILE, 'w') as f:
        json.dump(state, f)

def send_telegram(message):
    url = f'https://api.telegram.org/bot{BOT_TOKEN}/sendMessage'
    data = urllib.parse.urlencode({
        'chat_id': CHAT_ID,
        'text': message,
    }).encode()
    req = urllib.request.Request(url, data=data)
    try:
        urllib.request.urlopen(req, timeout=10)
        return True
    except Exception as e:
        print(f"Telegram error: {e}", file=sys.stderr)
        return False

def is_presale_email(subject, sender):
    text = f"{subject} {sender}".lower()
    return any(kw in text for kw in PRESALE_KEYWORDS)

def get_message_id(msg):
    """Get a stable unique ID for deduplication."""
    mid = msg.get('Message-ID', '')
    if mid:
        return mid.strip()
    # Fallback: combine date + subject
    return f"{msg.get('Date','')}-{msg.get('Subject','')}"

def check_gmail():
    pwd = open(GMAIL_PWD_FILE).read().strip()
    mail = imaplib.IMAP4_SSL('imap.gmail.com')
    mail.login(GMAIL_USER, pwd)

    state = load_state()
    alerted_ids = set(state.get('alerted_ids', []))
    new_alerts = list(alerted_ids)
    alerts_sent = 0

    # Look back 24h on first run, 30min on subsequent runs
    is_first_run = len(alerted_ids) == 0
    lookback_hours = 24 if is_first_run else 1
    since = (datetime.now() - timedelta(hours=lookback_hours)).strftime('%d-%b-%Y')

    for folder in FOLDERS_TO_CHECK:
        try:
            status, _ = mail.select(folder, readonly=True)
            if status != 'OK':
                continue
        except Exception as e:
            print(f"Could not open {folder}: {e}", file=sys.stderr)
            continue

        # Search unseen emails since lookback date
        status, data = mail.search(None, f'(SINCE {since})')
        if status != 'OK' or not data[0]:
            continue

        ids = data[0].split()
        print(f"{folder}: {len(ids)} emails to check")

        for mid in ids:
            try:
                _, msg_data = mail.fetch(mid, '(BODY.PEEK[HEADER.FIELDS (FROM SUBJECT DATE MESSAGE-ID)])')
                raw = msg_data[0][1].decode('utf-8', errors='replace')
                msg = email.message_from_string(raw)

                subject = decode_header_value(msg.get('Subject', ''))
                sender = decode_header_value(msg.get('From', ''))
                date = msg.get('Date', '')
                msg_id = get_message_id(msg)

                if msg_id in alerted_ids:
                    continue

                if is_presale_email(subject, sender):
                    message = (
                        f"🎟️ PRESALE ALERT!\n\n"
                        f"From: {sender}\n"
                        f"Subject: {subject}\n"
                        f"Received: {date}\n\n"
                        f"Open Gmail to see the full email and links."
                    )
                    if send_telegram(message):
                        alerts_sent += 1
                        new_alerts.append(msg_id)
                        print(f"  ✓ Alert sent: {subject}")
                    else:
                        print(f"  ✗ Failed to send alert for: {subject}")

            except Exception as e:
                print(f"  Error reading message: {e}", file=sys.stderr)

    mail.logout()

    # Save state (keep last 2000 IDs)
    state['alerted_ids'] = new_alerts[-2000:]
    state['last_run'] = datetime.now().isoformat()
    save_state(state)

    print(f"\nDone. Alerts sent: {alerts_sent}")
    return alerts_sent

if __name__ == '__main__':
    check_gmail()
