#!/usr/bin/env python3
"""
Gmail Audit Pass 3 - Auto-label emails before Aug 26, 2025
Process in batches of 200, apply Tier 1 + Tier 2 labels
Track progress and report results
"""

import json
from pathlib import Path
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
import time
from datetime import datetime
import re
from collections import defaultdict

TOKEN_PATH = Path.home() / ".config/gmail/token.json"
WORKSPACE = Path.home() / ".openclaw/workspace"

# Auto-label rules
RULES = {
    "Receipt + Finance": {
        "patterns": [
            (r"(lazada|amazon|ebay|paypal|stripe|xoom)", "from_sender"),
            (r"(invoice|receipt|order|payment confirmation)", "subject"),
            (r"(bank statement|gesa|gcash)", "from_or_subject"),
        ],
        "labels": ["Receipt", "Finance"]
    },
    "Receipt + Condo": {
        "patterns": [
            (r"(airbnb|booking\.com|agoda)", "from_sender"),
        ],
        "labels": ["Receipt", "Condo"]
    },
    "Reference + Gov/Benefits": {
        "patterns": [
            (r"(RRB|VA|DFAS|eRAS|myPay|veteran|military benefit)", "from_or_subject"),
            (r"(Bureau of Immigration|alien certificate|ACR|visa|Philippine e-Government)", "from_or_subject"),
            (r"(Federal EHR|EHR notification)", "from_or_subject"),
        ],
        "labels": ["Reference", "Gov/Benefits"]
    },
    "Reference + Finance": {
        "patterns": [
            (r"(bank planning|investment|financial planning|financial correspondence)", "subject"),
        ],
        "labels": ["Reference", "Finance"]
    },
    "Ministry": {
        "patterns": [
            (r"(elder training|agdao|church|worship|prayer|reformed|catechism|theological)", "from_or_subject"),
        ],
        "labels": ["Ministry"]
    },
    "Family": {
        "patterns": [
            (r"(Judy|Xavier|Pamela|Kay Johnson|Mom|Jeannine|family)", "from_or_subject"),
        ],
        "labels": ["Family"]
    },
    "Soliciting": {
        "patterns": [
            (r"(unsubscribe|newsletter|promotional|marketing|digest)", "subject_and_body"),
        ],
        "labels": ["Soliciting"]
    },
    "Learning": {
        "patterns": [
            (r"(Ron Paul Curriculum|educational|coursework|lesson)", "from_or_subject"),
        ],
        "labels": ["Learning"]
    },
    "Tech": {
        "patterns": [
            (r"(Anthropic|Claude|OpenClaw|n8n|GitHub|technical|developer)", "from_or_subject"),
        ],
        "labels": ["Tech"]
    },
    "Travel": {
        "patterns": [
            (r"(Philippine Airlines|PAL|Victory Liner|ferry|booking|flight confirmation)", "from_or_subject"),
        ],
        "labels": ["Reference", "Gov/Benefits"]
    },
    "Junk": {
        "patterns": [
            (r"(spam|phishing|verify your account|confirm identity)", "subject"),
        ],
        "labels": ["Junk"]
    },
}

def get_service():
    creds = Credentials.from_authorized_user_file(str(TOKEN_PATH), ["https://www.googleapis.com/auth/gmail.modify"])
    return build("gmail", "v1", credentials=creds)

def get_label_ids(service):
    """Get all label IDs"""
    labels_response = service.users().labels().list(userId="me").execute()
    return {label["name"]: label["id"] for label in labels_response.get("labels", [])}

def get_message_content(service, msg_id):
    """Get message headers and snippet"""
    msg = service.users().messages().get(
        userId="me", id=msg_id, 
        format='metadata',
        metadataHeaders=['From', 'Subject', 'Date', 'Content-Type']
    ).execute()
    
    headers = {h['name']: h['value'] for h in msg.get('payload', {}).get('headers', [])}
    return {
        'id': msg_id,
        'from': headers.get('From', '').lower(),
        'subject': headers.get('Subject', '').lower(),
        'date': headers.get('Date', ''),
        'labels': msg.get('labelIds', []),
        'snippet': msg.get('snippet', '')
    }

def check_pattern(pattern, message, pattern_type):
    """Check if pattern matches message"""
    regex, check_type = pattern
    
    if check_type == "from_sender":
        return bool(re.search(regex, message['from'], re.IGNORECASE))
    elif check_type == "subject":
        return bool(re.search(regex, message['subject'], re.IGNORECASE))
    elif check_type == "from_or_subject":
        return bool(re.search(regex, message['from'] + " " + message['subject'], re.IGNORECASE))
    elif check_type == "subject_and_body":
        text = message['subject'] + " " + message.get('snippet', '')
        return bool(re.search(regex, text, re.IGNORECASE))
    return False

def determine_labels(message):
    """Determine appropriate labels for a message"""
    labels_to_apply = []
    
    # Check each rule
    for rule_name, rule in RULES.items():
        # Check if any pattern matches
        for pattern in rule['patterns']:
            if check_pattern(pattern, message, None):
                labels_to_apply.extend(rule['labels'])
                break
    
    # Remove duplicates while preserving order
    return list(dict.fromkeys(labels_to_apply))

def apply_labels(service, msg_id, label_names, label_ids):
    """Apply labels to a message"""
    label_ids_to_apply = [label_ids[name] for name in label_names if name in label_ids]
    
    if not label_ids_to_apply:
        return False
    
    try:
        service.users().messages().modify(
            userId="me", id=msg_id,
            body={"addLabelIds": label_ids_to_apply}
        ).execute()
        return True
    except Exception as e:
        print(f"Error labeling {msg_id}: {e}")
        return False

def main():
    service = get_service()
    label_ids = get_label_ids(service)
    
    print("=" * 70)
    print("Gmail Audit Pass 3 - Starting")
    print("=" * 70)
    
    # Query for emails before Aug 26, 2025 that lack primary labels
    query = 'before:2025/08/26'
    
    # Track statistics
    stats = defaultdict(int)
    batch_size = 200
    processed_this_pass = 0
    already_labeled = 0
    
    page_token = None
    start_time = time.time()
    max_runtime = 90 * 60  # 90 minutes in seconds
    
    try:
        while True:
            # Check runtime
            elapsed = time.time() - start_time
            if elapsed > max_runtime:
                print(f"\n⏱️  90-minute limit reached after {processed_this_pass} emails")
                break
            
            # Fetch batch
            request = service.users().messages().list(
                userId="me", q=query, maxResults=batch_size, pageToken=page_token
            )
            results = request.execute()
            messages = results.get('messages', [])
            
            if not messages:
                print("\n✓ All emails processed!")
                break
            
            print(f"\nBatch {processed_this_pass // batch_size + 1}: Processing {len(messages)} emails...")
            
            # Process each message
            for msg in messages:
                msg_id = msg['id']
                
                # Get message details
                msg_data = get_message_content(service, msg_id)
                
                # Check if already labeled with primary categories
                existing_labels = [label_ids.get(k, k) for k in msg_data['labels']]
                has_primary = any(
                    label_ids.get(cat) in existing_labels 
                    for cat in ["Receipt", "Finance", "Reference", "Gov/Benefits", "Ministry", "Family", "Tech", "Learning", "Soliciting", "Junk"]
                )
                
                if has_primary:
                    already_labeled += 1
                    stats['skipped_already_labeled'] += 1
                    continue
                
                # Determine labels
                labels_to_apply = determine_labels(msg_data)
                
                if labels_to_apply:
                    # Apply labels
                    if apply_labels(service, msg_id, labels_to_apply, label_ids):
                        for label in labels_to_apply:
                            stats[f"label_{label}"] += 1
                        stats['labeled'] += 1
                        processed_this_pass += 1
                        print(f"  ✓ {msg_data['subject'][:60]} → {', '.join(labels_to_apply)}")
                    else:
                        stats['label_error'] += 1
                else:
                    stats['no_match'] += 1
                    print(f"  ? {msg_data['subject'][:60]} (no match)")
                
                time.sleep(0.05)  # Rate limiting
            
            # Get next page
            page_token = results.get('nextPageToken')
            if not page_token:
                break
    
    except Exception as e:
        print(f"\n❌ Error during audit: {e}")
        import traceback
        traceback.print_exc()
    
    # Report results
    print("\n" + "=" * 70)
    print("AUDIT RESULTS")
    print("=" * 70)
    print(f"Emails processed this pass: {processed_this_pass}")
    print(f"Emails already labeled (skipped): {already_labeled}")
    print(f"Labels applied by category:")
    for label in ["Receipt", "Finance", "Reference", "Gov/Benefits", "Ministry", "Family", "Soliciting", "Learning", "Tech", "Junk"]:
        count = stats.get(f'label_{label}', 0)
        if count > 0:
            print(f"  - {label}: {count}")
    
    if stats['no_match'] > 0:
        print(f"\nEmails without matching rules: {stats['no_match']}")
    
    print(f"\nRuntime: {int((time.time() - start_time) / 60)} minutes")
    print("=" * 70)
    
    return {
        'processed': processed_this_pass,
        'already_labeled': already_labeled,
        'stats': dict(stats)
    }

if __name__ == "__main__":
    result = main()

# TONY-APPROVED: 2026-03-01 | sha:a3ae1c51
