import os
import re
import requests
from datetime import datetime
from bs4 import BeautifulSoup
from newspaper import Article as NewspaperArticle
from newspaper import Config as NewspaperConfig
import ollama
from langdetect import detect
from difflib import SequenceMatcher
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Preformatted
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.pagesizes import letter
from concurrent.futures import ThreadPoolExecutor
import threading
import unicodedata
import zipfile
import io
import time


# Configurare newspaper
config = NewspaperConfig()
config.browser_user_agent = 'Mozilla/5.0'
config.request_timeout = 20

# Surse suspecte
SURSE_FALS = ["clickbait.ro", "fake-news-site.com"]

# --- FUNCȚII UTILE ---

def remove_diacritics(text):
    """Șterge diacriticele pentru salvare curată"""
    return ''.join(
        c for c in unicodedata.normalize('NFKD', text) if not unicodedata.combining(c)
    )

def similaritate(a, b):
    return SequenceMatcher(None, a.lower(), b.lower()).ratio()

def traduce_en_ro(text):
    try:
        from argostranslate.package import update_package_index, install_from_path, get_available_packages
        from argostranslate.translate import translate as argo_translate

        update_package_index()
        available_pkgs = get_available_packages()
        pkg = next((p for p in available_pkgs if p.from_code == 'en' and p.to_code == 'ro'), None)
        if not pkg:
            raise Exception("Pachetul EN->RO nu este disponibil.")

        install_from_path(pkg.download())
        translated_text = argo_translate(text, from_code='en', to_code='ro')
        return remove_diacritics(translated_text)

    except Exception as e:
        print(f"[EROARE TRADUCERE] {e}")
        return "[Traducere indisponibilă]"

# --- FUNCȚII PRINCIPALE ---

def extrage_articol(url):
    try:
        article = NewspaperArticle(url, config=config)
        article.download()
        article.parse()

        headers = {'User-Agent': 'Mozilla/5.0'}
        r = requests.get(url, headers=headers, timeout=10)
        soup = BeautifulSoup(r.text, 'html.parser')

        data = None

        # Din meta tags obișnuiți
        for meta in soup.find_all('meta'):
            if 'name' in meta.attrs and meta.attrs['name'].lower() == 'date':
                data = meta.attrs.get('content')
            elif 'property' in meta.attrs and meta.attrs['property'] == 'article:published_time':
                data = meta.attrs.get('content')

        # Din URL
        if not data:
            match = re.search(r'(\d{4})[/-]?(\d{2})[/-]?(\d{2})', url)
            if match:
                year, month, day = match.groups()
                data = f"{year}-{month}-{day}"

        date_str = None
        if data:
            try:
                from dateutil import parser as date_parser
                parsed_date = date_parser.parse(data, ignoretz=True)
                date_str = parsed_date.strftime("%Y%m%d")
            except Exception as e:
                print(f"Eroare la parsarea datei: {e}")

        autor = None
        for byline in soup.select('.author, .byline, .author-name'):
            if byline:
                autor = byline.get_text().strip()
                break

        authors_clean = [a for a in article.authors if isinstance(a, str)]
        if not authors_clean and autor:
            authors_clean = [autor]
        if not authors_clean:
            authors_clean = ["Autor necunoscut"]

        return {
            "url": url,
            "title": article.title,
            "text": article.text,
            "authors": authors_clean,
            "publish_date": date_str,
            "lang": detect(article.text) if article.text else 'necunoscut'
        }

    except Exception as e:
        print(f"Eroare la extragere: {e}")
        return None


def genereaza_rezumat(text):
    prompt = f"Rezumă următorul articol în maxim 5 propoziții:\n\n{text[:2048]}"
    response = ollama.generate(model="llama3", prompt=prompt)
    return response["response"].strip()


def analiza_fact_check(text):
    prompt = f"""
Ai primit următorul articol. Analizează-l și răspunde doar cu un verdict între 0 și 100 despre cât de probabil este real, explicând foarte scurt de ce:
0 = Foarte probabil fals
100 = Foarte probabil real

Articol:
{text[:2048]}
"""
    response = ollama.generate(model="llama3", prompt=prompt)
    return response["response"].strip()


def calculeaza_scor(articol):
    scor_total = 50
    if len(articol["title"]) < 30 and "!" in articol["title"][-2:]:
        scor_total -= 15
    if not articol["authors"] or articol["authors"][0] == "Autor necunoscut":
        scor_total -= 10
    if articol["lang"] == "necunoscut":
        scor_total -= 10
    extracted = os.path.splitext(os.path.basename(articol["url"]))[0].split('.')
    domeniu = '.'.join(extracted[-2:])
    if domeniu in SURSE_FALS:
        scor_total -= 30
    scor_final = max(0, min(100, scor_total))
    return {"scor": scor_final, "verdict": 
           "Probabil real" if scor_final >= 75 else 
           "Necesită verificare suplimentară" if scor_final >= 50 else 
           "Probabil fals" if scor_final >= 25 else 
           "Foarte probabil fals"}


def extract_urls(content):
    """Extrage URL-urile din CSV-ul GDELT"""
    url_pattern = re.compile(
        r'https?://(?:www\.)?(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}(?:/[^\s"]*)?'
    )
    return list(set(url_pattern.findall(content)))


def cauta_in_gdelt_articol(articol, output_file="linkuri_similare.txt"):
    """
    Caută în arhiva GDELT pe data articolului.
    Returnează TOATE URL-urile comparate și cele similare găsite.
    Rulează în paralel pentru viteză.
    """
    if not articol["publish_date"]:
        print("⚠️ Nu s-a putut determina data → nu se poate căuta în GDELT.")
        return []

    date_str = articol["publish_date"]
    filename_zip = f"{date_str}.export.CSV.zip"
    url_zip = f"http://data.gdeltproject.org/events/{filename_zip}"

    try:
        print(f"⬇️ Descărcăm arhiva GDELT pentru {date_str}...")
        response = requests.get(url_zip, timeout=30)
        if response.status_code != 200:
            print("❌ Fișierul GDELT nu există pentru această dată.")
            return []

        with zipfile.ZipFile(io.BytesIO(response.content)) as zip_ref:
            csv_name = zip_ref.namelist()[0]
            with zip_ref.open(csv_name) as csv_file:
                content = csv_file.read().decode('utf-8', errors='ignore')

        urls = extract_urls(content)
        print(f"🔍 Găsite {len(urls)} URL-uri în arhiva GDELT pentru această zi.")

        target_title = articol["title"]
        rezultate_similare = []

        def proceseaza_url(url):
            try:
                a = NewspaperArticle(url, config=config)
                a.download()
                a.parse()
                if not a.title:
                    return None
                score = similaritate(target_title, a.title.strip())
                if score > 0.6:
                    return {"url": url, "title": a.title.strip(), "score": score}
            except Exception as e:
                print(f"❌ Eroare la procesarea articolului GDELT: {e}")
                return None

        MAX_THREADS = 50  # Poți crește și la 100 dacă ai conexiune bună

        print(f"🔄 Se compară titlul nostru cu {len(urls)} URL-uri...")

        with ThreadPoolExecutor(max_workers=MAX_THREADS) as executor:
            futures = [executor.submit(proceseaza_url, url) for url in urls]
            for future in futures:
                result = future.result()
                if result:
                    rezultate_similare.append(result)

        print(f"✅ Găsite {len(rezultate_similare)} potriviri în GDELT.")

        with open(output_file, "w", encoding="utf-8") as f:
            f.write("🔗 Articole similare găsite în GDELT:\n")
            for item in rezultate_similare:
                f.write(f"- {item['url']} | Scor: {item['score']:.2f}\n")

        print(f"📄 Linkurile GDELT salvate în: {output_file}")
        return output_file

    except Exception as e:
        print(f"❌ Eroare la descărcarea arhivei GDELT: {e}")
        return []


def genereaza_raport_pdf(articol, rezumat_ai, verdict_ai, scor_info):
    pdf_filename = f"raport_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf"
    doc = SimpleDocTemplate(pdf_filename, pagesize=letter)
    styles = getSampleStyleSheet()
    flowables = []

    flowables.append(Paragraph(remove_diacritics("Raport de Verificare al unei Stiri"), styles['Title']))
    flowables.append(Spacer(1, 12))

    flowables.append(Paragraph(f"<b>Titlu:</b> {remove_diacritics(articol['title'])}", styles['Normal']))
    flowables.append(Paragraph(f"<b>URL:</b> {articol['url']}", styles['Normal']))
    flowables.append(Paragraph(f"<b>Data publicării:</b> {articol['publish_date'] or 'Necunoscută'}", styles['Normal']))
    flowables.append(Paragraph(f"<b>Autor(i):</b> {', '.join(articol['authors'])}", styles['Normal']))
    flowables.append(Paragraph(f"<b>Limbă:</b> {articol['lang']}", styles['Normal']))

    flowables.append(Spacer(1, 12))
    flowables.append(Paragraph("<b>Rezumat (Original)</b>", styles['Heading2']))
    flowables.append(Paragraph(rezumat_ai, styles['Normal']))

    flowables.append(Spacer(1, 6))
    flowables.append(Paragraph("<b>Rezumat (Română)</b>", styles['Heading2']))
    flowables.append(Paragraph(traduce_en_ro(rezumat_ai), styles['Normal']))

    flowables.append(Spacer(1, 12))
    flowables.append(Paragraph("<b>Verdict AI (Original)</b>", styles['Heading2']))
    flowables.append(Paragraph(verdict_ai, styles['Normal']))

    flowables.append(Spacer(1, 6))
    flowables.append(Paragraph("<b>Verdict AI (Română)</b>", styles['Heading2']))
    flowables.append(Paragraph(traduce_en_ro(verdict_ai), styles['Normal']))

    flowables.append(Spacer(1, 12))
    flowables.append(Paragraph(f"<b>Scor estimat:</b> {scor_info['scor']}%", styles['Normal']))
    flowables.append(Paragraph(f"<b>Verdict general:</b> {scor_info['verdict']}", styles['Normal']))

    doc.build(flowables)
    print(f"\n📄 Raportul inițial a fost salvat: {pdf_filename}")
    return pdf_filename


# --- MAIN ---
if __name__ == "__main__":
    url = input("Introduceți link-ul articolului: ")
    articol = extrage_articol(url)

    if not articol:
        print("❌ Nu s-a putut procesa articolul.")
    else:
        print("\n--- INFORMAȚII EXTRASE ---")
        print(f"Titlu: {articol['title']}")
        print(f"Autor(i): {', '.join(articol['authors'])}")
        print(f"Limbă detectată: {articol['lang']}")

        data_man = None
        if articol["publish_date"]:
            print(f"Data publicării: {articol['publish_date']}")
        else:
            data_input = input("📅 Introduceți data manual (YYYYMMDD) sau apăsați Enter pentru a ignora GDELT: ").strip()
            if data_input:
                try:
                    data_man = datetime.strptime(data_input, "%Y%m%d").strftime("%Y%m%d")
                    articol["publish_date"] = data_man
                except ValueError:
                    print("📅 Data introdusă nu este validă. Ignorăm GDELT.")

        print("\n--- GENERARE REZUMAT AUTOMAT ---")
        rezumat = genereaza_rezumat(articol["text"])
        print(f"🔹 EN: {rezumat}")
        print(f"🔹 RO: {traduce_en_ro(rezumat)}")

        print("\n--- ANALIZĂ IA (LLM) ---")
        verdict_ai = analiza_fact_check(articol["text"])
        print(f"🔹 EN: {verdict_ai}")
        print(f"🔹 RO: {traduce_en_ro(verdict_ai)}")

        print("\n--- CALCUL SCOR GENERAL ---")
        scor_info = calculeaza_scor(articol)
        print(f"🔹 Scor: {scor_info['scor']}%")
        print(f"🔹 Verdict: {scor_info['verdict']}")

        print("\n--- GENERARE RAPORT PDF ---")
        raport_pdf = genereaza_raport_pdf(articol, rezumat, verdict_ai, scor_info)

        print("\n--- CAUTARE ÎN FUNDAL ÎN GDELT (TOATE URL-URILE DIN ACEA ZI) ---")
        def ruleaza_cautare():
            txt_salvat = cauta_in_gdelt_articol(articol)
            print(f"📄 Finalizat! Linkurile GDELT sunt salvate în: {txt_salvat}")

        if articol["publish_date"]:
            gdelt_thread = threading.Thread(target=ruleaza_cautare, daemon=False)
            gdelt_thread.start()
        else:
            print("🚫 Cautarea în GDELT omisă (nu am determinat data)")

        print("\n📌 Așteptăm finalizarea căutării în GDELT... (poți închide doar după ce apare mesajul de finalizare)")
        
        # Ținem terminalul deschis până threadul se termină
        while not hasattr(gdelt_thread, 'done'):
            time.sleep(1)

        print("\n✅ Procesare completă. Ai toate informațiile necesare.")
