#!/usr/bin/env python3
"""
Tier 1 Batch Updater - Rate Limited
- Updates CRM 'tier' field with "Tier 1", "Tier 2", etc.
- Processes 1 lead per second to avoid rate limits
- Runs in background, updates state
"""
import json, re, time, urllib.request, ssl
from datetime import datetime
from pathlib import Path

SCRIPT_DIR = Path(__file__).parent
STATE_FILE = SCRIPT_DIR / "state" / "tier1-batch-state.json"
CRM_URL = "https://salesforce.hoaledgeriq.com/rest"
CRM_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5M2FmNGFmNS0zZWQ0LTQ1ZDMtOWE5Zi01MDMzZjc3YTY3MjMiLCJ0eXBlIjoiQVBJX0tFWSIsIndvcmtzcGFjZUlkIjoiOTNhZjRhZjUtM2VkNC00NWQzLTlhOWYtNTAzM2Y3N2E2NzIzIiwiaWF0IjoxNzczMzI4NDQzLCJleHAiOjE4MDQ3ODE2NDIsImp0aSI6IjIwZjEyYzkwLTRkMDctNGJmNi1iMzk3LTZjNmU3MzlmMThjOCJ9.zeM5NvwCSGEcz99m2LYtgb0sVD6WUXcCF7SwonFg930"

ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE

def log(msg):
    ts = datetime.now().strftime('%H:%M:%S')
    print(f"[{ts}] {msg}")

def load_state():
    if STATE_FILE.exists():
        return json.loads(STATE_FILE.read_text())
    return {"processed_ids": [], "batch_start": None}

def save_state(s):
    STATE_FILE.write_text(json.dumps(s, indent=2))

def get_tier_label(score):
    """Convert score to tier label (CRM format)"""
    if score >= 8:
        return "TIER_1"
    elif score >= 6:
        return "TIER_2"
    elif score >= 4:
        return "TIER_3"
    else:
        return "TIER_4"

def score_lead(note):
    """Score a lead 1-10 based on criteria"""
    temp = note.get('temp', 'COLD')
    if not temp or temp not in ['HOT', 'WARM', 'COLD']:
        temp = 'COLD'
        title = note.get('title', '').upper()
        if title.startswith('HOT:'):
            temp = 'HOT'
        elif title.startswith('WARM:'):
            temp = 'WARM'
    
    body = note.get('bodyV2', {}).get('markdown', '') if isinstance(note.get('bodyV2'), dict) else ''
    title = note.get('title', '')
    text = f"{title} {body}".lower()
    
    # Extract units
    units = None
    for pattern in [r'units:\s*(\d{1,4})', r'(\d{1,4})\s*(?:homes|units|lots)', r'community\s*of\s*(\d{1,4})']:
        match = re.search(pattern, text, re.IGNORECASE)
        if match:
            try:
                units = int(match.group(1))
                if 10 <= units <= 5000:
                    break
            except:
                pass
    
    # Check budget
    has_budget = 'budget pdf' in text or 'budget.pdf' in text or ('budget' in text and 'found' in text)
    has_site = 'https://' in text or 'http://' in text
    
    score = 0
    
    # Temperature (max 3)
    if temp == 'HOT':
        score += 3
    elif temp == 'WARM':
        score += 2
    
    # Units (max 4)
    if units:
        if 150 <= units <= 400:
            score += 4
        elif 100 <= units < 150 or 400 < units <= 500:
            score += 3
        elif 50 <= units < 100 or 500 < units <= 1000:
            score += 2
        else:
            score += 1
    
    # Budget (max 2)
    if has_budget:
        score += 2
    elif has_site:
        score += 1
    
    # Website (max 1)
    if has_site:
        score += 1
    
    return score

def update_crm_tier(note_id, tier_label):
    """Update CRM note with tier field"""
    try:
        patch_data = json.dumps({
            "tier": tier_label
        }).encode()
        
        req = urllib.request.Request(
            f"{CRM_URL}/notes/{note_id}",
            data=patch_data,
            headers={
                "Authorization": f"Bearer {CRM_TOKEN}",
                "Content-Type": "application/json"
            },
            method='PATCH'
        )
        
        opener = urllib.request.build_opener(urllib.request.HTTPSHandler(context=ssl_context))
        with opener.open(req, timeout=20) as r:
            return True
    except Exception as e:
        log(f"  ✗ Update failed: {e}")
        return False

def fetch_recent_notes(limit=200):
    """Fetch recent notes"""
    try:
        req = urllib.request.Request(
            f"{CRM_URL}/notes?limit={limit}&order[createdAt]=desc",
            headers={"Authorization": f"Bearer {CRM_TOKEN}", "Accept": "application/json"}
        )
        opener = urllib.request.build_opener(urllib.request.HTTPSHandler(context=ssl_context))
        with opener.open(req, timeout=30) as r:
            data = json.loads(r.read().decode())
            return data.get('data', {}).get('notes', [])
    except Exception as e:
        log(f"Fetch error: {e}")
        return []

def main():
    log("=" * 60)
    log("Tier 1 Batch Updater - Starting")
    log("=" * 60)
    
    state = load_state()
    processed_ids = set(state.get('processed_ids', []))
    
    if not state.get('batch_start'):
        state['batch_start'] = datetime.now().isoformat()
        save_state(state)
    
    # Fetch recent notes
    notes = fetch_recent_notes(500)
    log(f"Fetched {len(notes)} recent notes")
    
    updated = 0
    skipped = 0
    
    for i, note in enumerate(notes):
        note_id = note.get('id')
        title = note.get('title', '')[:50]
        
        # Skip if already processed
        if note_id in processed_ids:
            skipped += 1
            continue
        
        # Score the lead
        score = score_lead(note)
        tier_label = get_tier_label(score)
        
        # Update CRM
        if update_crm_tier(note_id, tier_label):
            log(f"  ✓ [{score}/10] {tier_label}: {title}")
            updated += 1
            
            # Save state after each update
            processed_ids.add(note_id)
            state['processed_ids'] = list(processed_ids)[-25000:]
            state['last_updated'] = datetime.now().isoformat()
            save_state(state)
        
        # Rate limit: 1 second between updates
        time.sleep(1)
    
    log("\n" + "=" * 60)
    log(f"Batch Complete!")
    log(f"  Updated: {updated}")
    log(f"  Skipped: {skipped}")
    log(f"  Total processed: {len(processed_ids)}")
    log("=" * 60)

if __name__ == "__main__":
    main()
