import os
import re
import requests
from datetime import datetime
from bs4 import BeautifulSoup
from newspaper import Article
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
import zipfile
import io
import unicodedata


# 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):
    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()

# Traducere Română
def traduce_en_ro(text):
    try:
        from argostranslate.package import update_package_index, install_from_path
        from argostranslate.translate import translate as argo_translate
        update_package_index()
        available_pkgs = get_available_packages()
        pkg = next(filter(lambda x: x.from_code == 'en' and x.to_code == 'ro', available_pkgs))
        install_from_path(pkg.download())
        return argo_translate(text, from_code='en', to_code='ro')
    except Exception as e:
        return f"[EROARE TRADUCERE: {e}]"

# --- FUNCȚII PRINCIPALE ---

def extrage_articol(url):
    try:
        article = Article(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}"

        # Din taguri HTML personalizate
        if not data:
            for time_tag in soup.find_all(['time', 'span', 'div']):
                if 'class' in time_tag.attrs:
                    for cls in time_tag.attrs['class']:
                        if cls.lower() in ['date', 'post-date', 'publish-date']:
                            potential_date = time_tag.get_text(strip=True)
                            try:
                                parsed_date = datetime.strptime(potential_date, "%B %d, %Y")
                                data = parsed_date.strftime("%Y-%m-%d")
                                break
                            except:
                                pass

        date_str = None
        if data:
            try:
                date_str = datetime.strptime(data[:10], "%Y-%m-%d").strftime("%Y%m%d")
            except:
                pass

        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_final, "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 cauta_in_gdelt_articol(articol):
    """
    Caută în arhiva GDELT pe data articolului.
    Returnează o listă de URL-uri similare.
    """
    if not articol['publish_date']:
        print("⚠️ Nu s-a putut determina data articolului. 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.")

        rezultate_similare = []
        count = 0
        for idx, url in enumerate(urls):
            if count >= 100:  # Poți schimba la 200 sau mai mult
                break
            print(f"\n🔄 Analizăm articolul {idx+1}/100: {url}")
            try:
                article = Article(url, config=config)
                article.download()
                article.parse()
                if not article.title or not article.text:
                    continue

                titlu_gdelt = article.title.strip()
                scor_titlu = similaritate(articol['title'], titlu_gdelt)

                print(f"📌 Scor titlu: {scor_titlu:.2f}")

                if scor_titlu > 0.6:
                    print(f"✅ POTRIVIRE GĂSITĂ:\nTitlu: {titlu_gdelt}\nURL: {url}")
                    rezultate_similare.append({
                        "url": url,
                        "title": titlu_gdelt,
                        "score_title": scor_titlu
                    })
                    count += 1
            except Exception as e:
                print(f"❌ Eroare la procesarea articolului GDELT: {e}")
                continue

        return rezultate_similare

    except Exception as e:
        print(f"❌ Eroare la descărcarea arhivei GDELT: {e}")
        return []


def extract_urls(content):
    """Extrage URL-urile din conținutul CSV"""
    url_pattern = re.compile(
        r'https?://(?:www\.)?(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}(?:/[^\s"]*)?'
    )
    return list(set(url_pattern.findall(content)))


def genereaza_raport_pdf(articol, gdelt_matches):
    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(remove_diacritics("<b>Rezumat:</b>"), styles['Heading2']))
    rezumat = genereaza_rezumat(articol["text"])
    flowables.append(Paragraph(remove_diacritics(rezumat), styles['Normal']))

    flowables.append(Spacer(1, 12))
    flowables.append(Paragraph(remove_diacritics("<b>Verdict AI:</b>"), styles['Heading2']))
    verdict_ai = analiza_fact_check(articol["text"])
    flowables.append(Paragraph(remove_diacritics(verdict_ai), styles['Code']))

    flowables.append(Spacer(1, 12))
    scor, verdict = calculeaza_scor(articol)
    flowables.append(Paragraph(f"<b>Scor estimat:</b> {scor}%", styles['Normal']))
    flowables.append(Paragraph(f"<b>Verdict final:</b> {remove_diacritics(verdict)}", styles['Normal']))

    flowables.append(Spacer(1, 12))
    flowables.append(Paragraph(remove_diacritics("<b>Căutare în GDELT:</b>"), styles['Heading2']))
    if gdelt_matches:
        flowables.append(Paragraph(remove_diacritics("Au fost găsite articole similare:"), styles['Normal']))
        for item in gdelt_matches:
            flowables.append(Paragraph(f"🔗 <a href='{item['url']}' color='blue'>{remove_diacritics(item['title'])}</a>", styles['Normal']))
    else:
        flowables.append(Paragraph(remove_diacritics("Nu au fost găsite potriviri în GDELT."), styles['Normal']))

    doc.build(flowables)
    print(f"\n✅ Raportul a fost salvat: {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']}")

        # Dacă nu am găsit data automat, întrebăm utilizatorul
        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--- REZUMAT AUTOMAT ---")
        rezumat = genereaza_rezumat(articol["text"])
        print(rezumat)

        print("\n--- ANALIZĂ IA (LLM) ---")
        verdict_ai = analiza_fact_check(articol["text"])
        print(verdict_ai)

        print("\n--- SCOR GENERAL ---")
        scor, verdict = calculeaza_scor(articol)
        print(f"Scor final: {scor}%")
        print(f"Verdict: {verdict}")

        print("\n--- VERIFICARE ÎN GDELT ---")
        gdelt_results = []
        if articol["publish_date"]:
            gdelt_results = cauta_in_gdelt_articol(articol)
        else:
            print("🚫 Verificarea în GDELT omisă (nu am putut determina data)")

        print("\n--- GENERARE RAPORT PDF ---")
        genereaza_raport_pdf(articol, gdelt_results)
