import telebot
import time
import json
import os
import random
import logging
import urllib.request
import urllib.error
import re
from curl_cffi import requests

# --- CONFIGURAZIONE ---
TOKEN = '8720275771:AAEUNSHhnto7KfSAOjQo9Y39DBEX5Gu_5-w'
CHAT_ID = '1640434336'
URL_RICERCA = 'https://www.subito.it/annunci-italia/vendita/offerte-lavoro/?q=smart+working'
FILE_STORICO = '/home/ubuntu/storico_annunci.json'

# --- LOGGING ---
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('/home/ubuntu/scraper.log', encoding='utf-8'),
        logging.StreamHandler()
    ]
)

bot = telebot.TeleBot(TOKEN)

def carica_storico():
    if not os.path.exists(FILE_STORICO):
        return []
    with open(FILE_STORICO, 'r', encoding='utf-8') as f:
        return json.load(f)

def salva_storico(storico):
    with open(FILE_STORICO, 'w', encoding='utf-8') as f:
        json.dump(storico, f)

def check_smart_working_ollama(description):
    url = "http://localhost:11434/api/generate"
    prompt = (
        "Sei un assistente AI. L'utente cerca un lavoro in smart working. "
        "Leggi la descrizione dell'annuncio. Se c'è scritto esplicitamente 'NO SMART WORKING', 'solo in presenza', 'di persona', o simili, rispondi 'NO'. "
        "Se c'è scritto che è in smart working, da remoto o ibrido, rispondi 'SI'. "
        "RISPONDI SOLO CON LA PAROLA 'SI' OPPURE 'NO', SENZA AGGIUNGERE ALTRO.\n\n"
        f"Descrizione: {description[:1500]}"
    )
    
    data = {
        "model": "llama3:latest",
        "prompt": prompt,
        "stream": False,
        "options": {"temperature": 0.0, "num_predict": 5}
    }
    
    try:
        req = urllib.request.Request(url, data=json.dumps(data).encode('utf-8'), headers={'Content-Type': 'application/json'})
        with urllib.request.urlopen(req, timeout=40) as response:
            result = json.loads(response.read().decode('utf-8'))
            testo = result.get('response', '').strip().upper()
            if 'NO' in testo and 'SI' not in testo:
                return False
            return True
    except urllib.error.URLError as e:
        logging.warning(f"Ollama non raggiungibile: {e}")
        return True
    except Exception as e:
        logging.error(f"Errore in Ollama: {e}")
        return True

def estrai_annunci(tentativi=3):
    annunci_trovati = []

    for tentativo in range(tentativi):
        try:
            logging.info(f"Connessione a Subito.it (Tentativo {tentativo+1}/{tentativi})...")
            
            # Usiamo curl_cffi per impersonare Chrome e bypassare il blocco Datacenter di Subito
            response = requests.get(URL_RICERCA, impersonate="chrome110", timeout=15)
            
            if response.status_code != 200:
                logging.error(f"Errore HTTP da Subito.it: {response.status_code}")
                time.sleep(5)
                continue
                
            html = response.text
                
            match = re.search(r'<script id="__NEXT_DATA__" type="application/json">({.*?})</script>', html)
            if not match:
                logging.warning("JSON di Subito non trovato nel DOM. Riprovo...")
                time.sleep(5)
                continue
                
            data = json.loads(match.group(1))
            items = data.get('props', {}).get('pageProps', {}).get('initialState', {}).get('items', {}).get('originalList', [])
            
            logging.info(f"Trovati {len(items)} annunci nella pagina.")

            for item in items:
                try:
                    urn = item.get('urn', '')
                    annuncio_id = urn.split(':')[-1] if ':' in urn else str(item.get('id', ''))
                    titolo = item.get('subject', 'Titolo non trovato')
                    azienda = item.get('advertiser', {}).get('name', 'Azienda non specificata')
                    locazione = item.get('geo', {}).get('town', {}).get('value', 'Da remoto')
                    link_completo = item.get('urls', {}).get('default', '')
                    descrizione = item.get('body', '')

                    # 1. Filtro Veloce tramite Regex
                    if re.search(r'(no|senza)\s+smart\s*working', descrizione, re.IGNORECASE) or \
                       re.search(r'non\s+in\s+smart\s*working', descrizione, re.IGNORECASE) or \
                       re.search(r'solo\s+in\s+presenza', descrizione, re.IGNORECASE):
                        logging.info(f"Annuncio scartato (Regex): {titolo} - {azienda}")
                        continue
                        
                    # 2. Filtro Intelligente tramite Ollama
                    if descrizione:
                        is_smart = check_smart_working_ollama(descrizione)
                        if not is_smart:
                            logging.info(f"Annuncio scartato (Ollama): {titolo} - {azienda}")
                            continue

                    if link_completo and annuncio_id:
                        annunci_trovati.append({
                            'id': annuncio_id,
                            'titolo': titolo,
                            'azienda': azienda,
                            'locazione': locazione,
                            'link': link_completo
                        })
                except Exception as e:
                    logging.warning(f"Errore durante il parsing di un annuncio json: {e}")
                    continue
            
            return annunci_trovati

        except Exception as e:
            logging.error(f"Errore generale: {e}")
            time.sleep(5)
            
    return annunci_trovati

def invia_messaggio_telegram(annuncio):
    messaggio = (
        f"🚀 <b>Nuova Opportunità di Lavoro Verificata!</b>\n\n"
        f"📌 <b>Ruolo:</b> {annuncio['titolo']}\n"
        f"🏢 <b>Azienda:</b> {annuncio['azienda']}\n"
        f"🌍 <b>Luogo:</b> {annuncio['locazione']}\n\n"
        f"🤖 <i>L'AI ha confermato che si tratta di smart working/remoto.</i>\n\n"
        f"🔗 <a href='{annuncio['link']}'>Clicca qui per candidarti</a>"
    )
    bot.send_message(CHAT_ID, messaggio, parse_mode='HTML', disable_web_page_preview=True)

def job_routine():
    logging.info("Avvio ricerca nuovi annunci...")
    nuovi_annunci = estrai_annunci()
    storico = carica_storico()
    nuovi_inviati = 0

    for annuncio in nuovi_annunci:
        if annuncio['id'] not in storico and annuncio['id'] != "":
            try:
                invia_messaggio_telegram(annuncio)
                storico.append(annuncio['id'])
                nuovi_inviati += 1
                time.sleep(random.uniform(1.5, 3.0))
            except Exception as e:
                logging.error(f"Errore nell'invio a Telegram: {e}")

    salva_storico(storico)
    logging.info(f"Ricerca completata. Inviati {nuovi_inviati} nuovi annunci.")

if __name__ == "__main__":
    logging.info("Bot avviato con successo.")
    try:
        bot.send_message(CHAT_ID, "✅ <b>Bot AI avviato su Oracle!</b> In attesa di nuove offerte in smart working...", parse_mode='HTML')
    except Exception as e:
        logging.error(f"Impossibile inviare messaggio di start a Telegram: {e}")
        
    while True:
        job_routine()
        attesa_secondi = random.randint(7200, 10800)
        logging.info(f"Prossima ricerca tra {attesa_secondi // 60} minuti.")
        time.sleep(attesa_secondi)
