#!/usr/bin/env python3
"""
Mark all newsletters, promotions, and spam as read in Gmail.
Targets: CATEGORY_PROMOTIONS, CATEGORY_UPDATES, CATEGORY_SOCIAL, SPAM
Accounts: both connected Gmail accounts.
"""
import json, os, sys, time, urllib.parse, urllib.request

WORKSPACE = os.environ.get('WORKSPACE', '/root/.openclaw/workspace')
GOOGLE_AUTH_DIR = os.path.join(WORKSPACE, 'google-auth')

ACCOUNTS = [
    {'label': 'kitt@curiousendeavor.com', 'token': 'token.json'},
    {'label': 'assafdagancos@gmail.com', 'token': 'token-personal.json'},
]

TARGETS = [
    ('CATEGORY_PROMOTIONS', 'Promotions'),
    ('CATEGORY_UPDATES', 'Updates'),
    ('CATEGORY_SOCIAL', 'Social'),
    ('SPAM', 'Spam'),
]

def load_token(token_path):
    with open(token_path) as f:
        return json.load(f)

def refresh_token(token_data):
    data = urllib.parse.urlencode({
        'client_id': token_data['client_id'],
        'client_secret': token_data['client_secret'],
        'refresh_token': token_data['refresh_token'],
        'grant_type': 'refresh_token',
    }).encode()
    req = urllib.request.Request('https://oauth2.googleapis.com/token', data=data)
    resp = urllib.request.urlopen(req)
    tokens = json.loads(resp.read())
    return tokens['access_token']

def gmail_request(access_token, method, path, body=None):
    url = f'https://gmail.googleapis.com/gmail/v1{path}'
    headers = {'Authorization': f'Bearer {access_token}', 'Content-Type': 'application/json'}
    data = json.dumps(body).encode() if body else None
    req = urllib.request.Request(url, data=data, headers=headers, method=method)
    try:
        resp = urllib.request.urlopen(req)
        raw = resp.read()
        return json.loads(raw) if raw else {}
    except urllib.error.HTTPError as e:
        err = e.read().decode()
        raise Exception(f"Gmail API {method} {path}: {e.code} {err}")

def get_unread_ids(access_token, label, max_results=500):
    ids = []
    page_token = None
    while True:
        params = {
            'labelIds': label,
            'q': 'is:unread',
            'maxResults': 500,
        }
        if page_token:
            params['pageToken'] = page_token
        path = f'/users/me/messages?{urllib.parse.urlencode(params)}'
        data = gmail_request(access_token, 'GET', path)
        msgs = data.get('messages', [])
        ids.extend([m['id'] for m in msgs])
        page_token = data.get('nextPageToken')
        if not page_token or len(ids) >= max_results:
            break
    return ids[:max_results]

def batch_mark_read(access_token, ids):
    if not ids:
        return
    # Gmail batch modify — up to 1000 at a time
    for i in range(0, len(ids), 1000):
        chunk = ids[i:i+1000]
        gmail_request(access_token, 'POST', '/users/me/messages/batchModify', {
            'ids': chunk,
            'removeLabelIds': ['UNREAD'],
        })
        time.sleep(0.3)

def process_account(account):
    token_path = os.path.join(GOOGLE_AUTH_DIR, account['token'])
    if not os.path.exists(token_path):
        print(f"  ⚠️  Token not found: {token_path}")
        return

    try:
        token_data = load_token(token_path)
        access_token = refresh_token(token_data)
    except Exception as e:
        print(f"  ❌ Auth failed: {e}")
        return

    total = 0
    for label, name in TARGETS:
        try:
            ids = get_unread_ids(access_token, label)
            if ids:
                batch_mark_read(access_token, ids)
                print(f"  ✅ {name}: marked {len(ids)} as read")
                total += len(ids)
            else:
                print(f"  — {name}: nothing unread")
        except Exception as e:
            print(f"  ❌ {name}: {e}")

    print(f"  📊 Total marked read: {total}")

def main():
    for account in ACCOUNTS:
        print(f"\n📧 {account['label']}")
        process_account(account)

if __name__ == '__main__':
    main()
