#!/usr/bin/env python3
"""
Ghost Agency Radar FAST - Optimized for speed
- Processes leads in parallel batches
- Uses Hunter.io efficiently with async requests
- Caches DNS checks
"""

import os
import csv
import time
import socket
import random
import requests
import json
import re
import dns.resolver
from pathlib import Path
from datetime import datetime
from concurrent.futures import ThreadPoolExecutor, as_completed
from urllib.parse import quote_plus

SEED_CSV = Path("/home/ubuntu/GhostAgency/leads_seed_parma.csv")
OUTPUT_DIR = Path("/home/ubuntu/GhostAgency")
HUNTER_API_KEY = os.getenv("HUNTER_API_KEY", "")
GOOGLE_MAPS_API_KEY = os.getenv("GOOGLE_MAPS_API_KEY", "")
FACEBOOK_TOKEN = os.getenv("FACEBOOK_TOKEN", "")

# Rate limits - optimized
DNS_DELAY = 0.1
HUNTER_DELAY = 0.5
SCRAPE_DELAY = 1.0

USER_AGENTS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36",
]

def get_headers():
    return {"User-Agent": random.choice(USER_AGENTS)}

# DNS cache
dns_cache = {}

def check_dns(domain):
    if domain in dns_cache:
        return dns_cache[domain]
    try:
        socket.gethostbyname(domain)
        dns_cache[domain] = True
        return True
    except socket.gaierror:
        dns_cache[domain] = False
        return False

def check_mx(domain):
    if domain in dns_cache:
        return dns_cache[domain]
    try:
        answers = dns.resolver.resolve(domain, 'MX')
        dns_cache[domain] = len(answers) > 0
        return dns_cache[domain]
    except:
        dns_cache[domain] = False
        return False

def hunter_email_finder(domain, company_name):
    if not HUNTER_API_KEY:
        return None, None
    try:
        url = f"https://api.hunter.io/v2/domain-search?domain={domain}&api_key={HUNTER_API_KEY}&limit=10"
        r = requests.get(url, timeout=10)
        if r.status_code == 200:
            data = r.json()
            emails = data.get("data", {}).get("emails", [])
            if emails:
                best = max(emails, key=lambda x: x.get("confidence", 0))
                return best["value"], "hunter"
    except:
        pass
    return None, None

def generate_emails_from_name(name):
    clean = re.sub(r'[^a-z0-9]', '', name.lower())
    patterns = [
        f"info@{clean}.it",
        f"contatto@{clean}.it",
        f"prenotazioni@{clean}.it",
        f"admin@{clean}.it",
        f"hello@{clean}.it",
    ]
    return patterns

def find_email_for_lead(lead):
    nome = lead.get("nome", "")
    categoria = lead.get("categoria", "")
    indirizzo = lead.get("indirizzo", "")
    
    # 1. Try Hunter.io if domain can be guessed
    clean = re.sub(r'[^a-z0-9]', '', nome.lower())
    domain_guess = f"{clean}.it"
    
    if check_dns(domain_guess):
        email, source = hunter_email_finder(domain_guess, nome)
        if email:
            return email, "hunter"
    
    # 2. Pattern MX verification
    for pattern in generate_emails_from_name(nome):
        domain = pattern.split('@')[1]
        if check_mx(domain):
            return pattern, "pattern_mx"
    
    # 3. Fallback: no email found
    return None, "none"

def process_batch(leads):
    results = []
    with ThreadPoolExecutor(max_workers=5) as executor:
        futures = {executor.submit(find_email_for_lead, lead): lead for lead in leads}
        for future in as_completed(futures):
            lead = futures[future]
            try:
                email, source = future.result(timeout=30)
                results.append({
                    "nome": lead.get("nome", ""),
                    "categoria": lead.get("categoria", ""),
                    "indirizzo": lead.get("indirizzo", ""),
                    "telefono": lead.get("telefono", ""),
                    "email": email or "",
                    "fonte": source
                })
            except Exception as e:
                results.append({
                    "nome": lead.get("nome", ""),
                    "categoria": lead.get("categoria", ""),
                    "indirizzo": lead.get("indirizzo", ""),
                    "telefono": lead.get("telefono", ""),
                    "email": "",
                    "fonte": "error"
                })
    return results

def main():
    print(f"[{datetime.now()}] Starting FAST radar...")
    
    # Load seed leads
    leads = []
    with open(SEED_CSV, 'r') as f:
        reader = csv.DictReader(f)
        for row in reader:
            leads.append(row)
    
    print(f"Loaded {len(leads)} seed leads")
    
    # Process in batches
    batch_size = 10
    all_results = []
    
    for i in range(0, len(leads), batch_size):
        batch = leads[i:i+batch_size]
        print(f"Processing batch {i//batch_size + 1}/{(len(leads)+batch_size-1)//batch_size} ({len(batch)} leads)...")
        
        batch_results = process_batch(batch)
        all_results.extend(batch_results)
        
        # Save progress
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
        output_file = OUTPUT_DIR / f"leads_parma_{timestamp}_fast.csv"
        
        with open(output_file, 'w', newline='') as f:
            fieldnames = ["nome", "categoria", "indirizzo", "telefono", "email", "fonte"]
            writer = csv.DictWriter(f, fieldnames=fieldnames)
            writer.writeheader()
            writer.writerows(all_results)
        
        # Count emails found
        with_email = sum(1 for r in all_results if r["email"])
        print(f"  Batch done. Total leads: {len(all_results)}, With email: {with_email}")
    
    # Final save
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
    final_file = OUTPUT_DIR / f"leads_parma_{timestamp}_fast_final.csv"
    with open(final_file, 'w', newline='') as f:
        fieldnames = ["nome", "categoria", "indirizzo", "telefono", "email", "fonte"]
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerows(all_results)
    
    with_email = sum(1 for r in all_results if r["email"])
    print(f"\nDONE! Total: {len(all_results)}, With email: {with_email} ({with_email/len(all_results)*100:.1f}%)")
    print(f"Saved to: {final_file}")

if __name__ == "__main__":
    main()