#!/usr/bin/env python3
"""
Eden Reply Handler - Autonomous Follow-Up System
Monitors GitHub notifications, detects engagement, sends follow-ups
"""
import imaplib
import email
import json
import sqlite3
import requests
import re
from datetime import datetime, timedelta
from pathlib import Path
from email.header import decode_header

# Config
CONFIG_PATH = "/Eden/SECRETS/email_config.json"
DB_PATH = "/Eden/DATA/sales.db"
TOKEN_PATH = "/Eden/SECRETS/github_token_clean.txt"
STATE_PATH = "/Eden/DATA/reply_handler_state.json"
LOG_PATH = "/Eden/LOGS/reply_handler.log"

# Follow-up limits
MAX_FOLLOWUPS_PER_DAY = 5
MAX_FOLLOWUPS_PER_USER = 2

def log(msg):
    ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    line = f"[{ts}] {msg}"
    print(line)
    with open(LOG_PATH, 'a') as f:
        f.write(line + "\n")

def load_state():
    try:
        return json.loads(Path(STATE_PATH).read_text())
    except:
        return {"processed_emails": [], "followups_today": 0, "last_date": "", "user_followups": {}}

def save_state(state):
    Path(STATE_PATH).write_text(json.dumps(state, indent=2))

def get_token():
    return Path(TOKEN_PATH).read_text().strip()

def get_gmail_config():
    return json.loads(Path(CONFIG_PATH).read_text())

def classify_engagement(subject, body):
    """Classify the type of engagement"""
    subject_lower = subject.lower()
    body_lower = body.lower()
    
    # Positive signals
    if 'closed' in subject_lower and 'completed' in body_lower:
        return 'ISSUE_FIXED', 0.9
    if 'merged' in body_lower or 'via' in body_lower:
        return 'PR_MERGED', 0.9
    if any(word in body_lower for word in ['thanks', 'thank you', 'helpful', 'great', 'awesome']):
        return 'POSITIVE_REPLY', 0.8
    if any(word in body_lower for word in ['interested', 'yes', 'sure', 'send', 'details']):
        return 'HOT_LEAD', 1.0
    if any(word in body_lower for word in ['price', 'cost', 'how much', '$']):
        return 'PRICE_INQUIRY', 0.95
    
    # Negative signals
    if any(word in body_lower for word in ['spam', 'stop', 'unsubscribe', 'not interested', 'no thanks']):
        return 'NEGATIVE', 0.0
    if 'closed' in subject_lower and 'not planned' in body_lower:
        return 'REJECTED', 0.1
    
    # Neutral
    return 'ENGAGEMENT', 0.5

def generate_followup(engagement_type, user, repo):
    """Generate contextual follow-up message"""
    
    templates = {
        'ISSUE_FIXED': f"""Nice work fixing that, @{user}! 🎉

Since you're proactive about code quality, I ran a deeper scan on `{repo}`. Found a few more patterns worth reviewing.

Full security audit available for $149 - includes:
- Complete vulnerability scan
- Dependency risk analysis  
- Remediation roadmap
- 30-day rescan

Interested? Reply here or: https://paypal.me/jamlen

— Eden 💚""",

        'PR_MERGED': f"""Great PR, @{user}! Clean implementation.

Want me to scan the full codebase for similar patterns? $149 gets you a complete SAGE audit with prioritized fixes.

— Eden""",

        'HOT_LEAD': f"""Awesome, @{user}! Here's how it works:

1. Pay $149 at https://paypal.me/jamlen
2. Reply with your email
3. I'll send the full audit within 24 hours

Questions? Just ask.

— Eden 💚""",

        'PRICE_INQUIRY': f"""Great question, @{user}!

**SAGE Security Audit - $149**
- Full vulnerability scan
- Dependency analysis
- Secrets detection
- Remediation roadmap
- 30-day follow-up scan

Pay at: https://paypal.me/jamlen
Then reply with your email for delivery.

— Eden""",

        'POSITIVE_REPLY': f"""Glad it helped, @{user}! 

If you want the complete picture, I offer full audits for $149. Covers everything: vulnerabilities, dependencies, secrets, configs.

Just let me know.

— Eden 💚""",

        'ENGAGEMENT': f"""Thanks for the response, @{user}!

Let me know if you'd like a full security scan. Happy to help.

— Eden"""
    }
    
    return templates.get(engagement_type, templates['ENGAGEMENT'])

def post_followup(issue_url, message, token):
    """Post follow-up comment to GitHub"""
    try:
        parts = issue_url.replace("https://github.com/", "").split("/")
        owner, repo = parts[0], parts[1]
        issue_num = parts[3] if len(parts) > 3 else parts[-1]
        
        api_url = f"https://api.github.com/repos/{owner}/{repo}/issues/{issue_num}/comments"
        
        resp = requests.post(api_url,
            headers={"Authorization": f"token {token}", "Accept": "application/vnd.github.v3+json"},
            json={"body": message}, timeout=30)
        
        return resp.status_code == 201
    except Exception as e:
        log(f"❌ Post failed: {e}")
        return False

def extract_repo_from_subject(subject):
    """Extract owner/repo from email subject"""
    match = re.search(r'\[([^\]]+/[^\]]+)\]', subject)
    if match:
        return match.group(1)
    return None

def extract_issue_url(body):
    """Extract GitHub issue URL from email body"""
    match = re.search(r'https://github\.com/[^\s]+/issues/\d+', body)
    if match:
        return match.group(0).split('#')[0]  # Remove anchor
    return None

def process_notifications():
    """Main processing loop"""
    state = load_state()
    cfg = get_gmail_config()
    token = get_token()
    
    # Reset daily counter
    today = datetime.now().strftime("%Y-%m-%d")
    if state.get("last_date") != today:
        state["followups_today"] = 0
        state["last_date"] = today
    
    # Connect to Gmail
    mail = imaplib.IMAP4_SSL(cfg['imap_server'])
    mail.login(cfg['user'], cfg['password'])
    mail.select('inbox')
    
    # Get recent GitHub notifications (last 24 hours)
    since = (datetime.now() - timedelta(days=1)).strftime("%d-%b-%Y")
    status, msgs = mail.search(None, f'(FROM "notifications@github.com" SINCE {since})')
    msg_ids = msgs[0].split() if msgs[0] else []
    
    log(f"📬 Found {len(msg_ids)} recent GitHub notifications")
    
    followups_sent = 0
    
    for mid in msg_ids:
        if state["followups_today"] >= MAX_FOLLOWUPS_PER_DAY:
            log(f"⏸️ Daily limit reached ({MAX_FOLLOWUPS_PER_DAY})")
            break
            
        mid_str = mid.decode()
        if mid_str in state.get("processed_emails", []):
            continue
        
        # Fetch email
        status, data = mail.fetch(mid, '(RFC822)')
        msg = email.message_from_bytes(data[0][1])
        
        subject = msg['Subject'] or ""
        if isinstance(subject, bytes):
            subject = subject.decode('utf-8', errors='ignore')
        decoded = decode_header(subject)[0]
        subject = decoded[0].decode(decoded[1] or 'utf-8') if isinstance(decoded[0], bytes) else str(decoded[0])
        
        # Get body
        body = ""
        if msg.is_multipart():
            for part in msg.walk():
                if part.get_content_type() == "text/plain":
                    body = part.get_payload(decode=True).decode('utf-8', errors='ignore')
                    break
        else:
            body = msg.get_payload(decode=True).decode('utf-8', errors='ignore') if msg.get_payload(decode=True) else ""
        
        # Skip our own messages
        if 'Edensages left a comment' in body:
            state["processed_emails"].append(mid_str)
            continue
        
        # Classify engagement
        engagement_type, score = classify_engagement(subject, body)
        
        if engagement_type == 'NEGATIVE' or score < 0.5:
            log(f"⏭️ Skip {subject[:40]}... ({engagement_type})")
            state["processed_emails"].append(mid_str)
            continue
        
        # Extract details
        repo = extract_repo_from_subject(subject)
        issue_url = extract_issue_url(body)
        user = repo.split('/')[0] if repo else "there"
        
        if not issue_url:
            state["processed_emails"].append(mid_str)
            continue
        
        # Check user followup limit
        user_count = state.get("user_followups", {}).get(user, 0)
        if user_count >= MAX_FOLLOWUPS_PER_USER:
            log(f"⏭️ User {user} already has {user_count} followups")
            state["processed_emails"].append(mid_str)
            continue
        
        # Generate and send followup
        followup_msg = generate_followup(engagement_type, user, repo or "your repo")
        
        log(f"💬 {engagement_type} from {user} on {repo}")
        
        if post_followup(issue_url, followup_msg, token):
            log(f"✅ Follow-up sent to {user}")
            state["followups_today"] += 1
            state.setdefault("user_followups", {})[user] = user_count + 1
            followups_sent += 1
            
            # Log to database
            try:
                conn = sqlite3.connect(DB_PATH)
                c = conn.cursor()
                c.execute("""INSERT OR IGNORE INTO followups 
                            (user, repo, engagement_type, score, sent_at)
                            VALUES (?, ?, ?, ?, ?)""",
                         (user, repo, engagement_type, score, datetime.now().isoformat()))
                conn.commit()
                conn.close()
            except:
                pass
        
        state["processed_emails"].append(mid_str)
        state["processed_emails"] = state["processed_emails"][-500:]  # Keep last 500
    
    mail.logout()
    save_state(state)
    
    log(f"📊 Cycle complete: {followups_sent} follow-ups sent, {state['followups_today']}/{MAX_FOLLOWUPS_PER_DAY} today")
    return followups_sent

def create_followups_table():
    """Create tracking table"""
    conn = sqlite3.connect(DB_PATH)
    c = conn.cursor()
    c.execute("""CREATE TABLE IF NOT EXISTS followups (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        user TEXT,
        repo TEXT,
        engagement_type TEXT,
        score REAL,
        sent_at TIMESTAMP,
        converted BOOLEAN DEFAULT 0
    )""")
    conn.commit()
    conn.close()

if __name__ == "__main__":
    import sys
    
    log("🔄 Eden Reply Handler starting...")
    create_followups_table()
    
    if "--daemon" in sys.argv:
        import time
        while True:
            try:
                process_notifications()
            except Exception as e:
                log(f"❌ Error: {e}")
            time.sleep(300)  # Check every 5 minutes
    else:
        process_notifications()
