import os
import io
import requests
import time
from urllib.parse import urlparse
import PyPDF2
from newspaper import Article
import tkinter as tk
from tkinter import messagebox, ttk
from youtube_transcript_api import YouTubeTranscriptApi, NoTranscriptFound, TranscriptsDisabled

# Încercăm să importăm python-docx pentru fișiere DOCX
try:
    import docx
except ImportError:
    docx = None

# Încercăm să importăm googlesearch-python pentru căutări
try:
    from googlesearch import search
except ImportError:
    print("Eroare: Modulul 'googlesearch' nu este instalat. Instalează-l cu 'pip install googlesearch-python'.")
    exit(1)

# Funcții de extragere a textului
def extract_text_from_pdf(content):
    """Extragerea textului din conținutul unui fișier PDF."""
    text = ""
    try:
        pdf_reader = PyPDF2.PdfReader(io.BytesIO(content))
        for page in pdf_reader.pages:
            page_text = page.extract_text()
            if page_text:
                text += page_text + "\n"
    except Exception as e:
        print(f"Eroare la extragerea textului din PDF: {e}")
    return text

def extract_text_from_txt(content):
    """Extragerea textului din fișiere TXT."""
    try:
        return content.decode('utf-8')
    except UnicodeDecodeError:
        return content.decode('latin-1', errors='ignore')

def extract_text_from_html(url):
    """Extragerea textului din fișiere HTML folosind newspaper3k."""
    try:
        article = Article(url)
        article.download()
        article.parse()
        text = f"Titlu: {article.title}\n\nText:\n{article.text}"
        return text
    except Exception as e:
        print(f"Eroare la extragerea textului HTML cu newspaper3k: {e}")
        return ""

def extract_text_from_docx(content):
    """Extragerea textului din fișiere DOCX direct din memorie."""
    if not docx:
        print("Eroare: Modulul 'python-docx' nu este instalat. Fișierele DOCX nu pot fi procesate.")
        return ""
    try:
        docx_file = io.BytesIO(content)
        document = docx.Document(docx_file)
        text = "\n".join([para.text for para in document.paragraphs])
        return text
    except Exception as e:
        print(f"Eroare la extragerea textului din DOCX: {e}")
        return ""

def extract_text_from_youtube(url):
    """Extragerea subtitrărilor din videoclipuri YouTube."""
    try:
        video_id = urlparse(url).query.split('v=')[1].split('&')[0] if 'v=' in urlparse(url).query else urlparse(url).path.strip('/')
        transcript = YouTubeTranscriptApi.get_transcript(video_id, languages=['en', 'ro'])  # Preferăm engleză sau română
        text = "\n".join([entry['text'] for entry in transcript])
        return f"Subtitrări YouTube:\n{text}"
    except (NoTranscriptFound, TranscriptsDisabled):
        print(f"Nu s-au găsit subtitrări pentru {url}")
        return ""
    except Exception as e:
        print(f"Eroare la extragerea subtitrărilor YouTube: {e}")
        return ""

# Funcție pentru descărcarea conținutului de la un URL
def download_file(url):
    """Descărcarea conținutului de la un URL și returnarea obiectului response."""
    try:
        response = requests.get(url, timeout=10)
        response.raise_for_status()
        return response
    except requests.exceptions.RequestException as e:
        print(f"Eroare la descărcarea {url}: {e}")
        return None

# Procesarea unui URL și extragerea textului
def process_url(url):
    """Procesarea unui URL: descărcare și extragerea textului conform tipului de conținut."""
    print(f"\nProcesare: {url}")
    if 'youtube.com' in url or 'youtu.be' in url:
        return extract_text_from_youtube(url)

    response = download_file(url)
    if not response:
        return None

    content = response.content
    content_type = response.headers.get('Content-Type', '').lower()
    text = ""

    if 'application/pdf' in content_type:
        text = extract_text_from_pdf(content)
    elif 'text/plain' in content_type:
        text = extract_text_from_txt(content)
    elif 'text/html' in content_type:
        text = extract_text_from_html(url)  # Folosim URL-ul direct cu newspaper3k
    elif 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' in content_type:
        text = extract_text_from_docx(content)
    else:
        print(f"Tip de conținut necunoscut: {content_type}")
    return text

# Funcția principală de procesare
def run_search(query, num_results, filetype, output_file, status_label):
    """Rulează căutarea și procesarea, actualizând interfața grafică."""
    if filetype:
        query += f" filetype:{filetype}"

    status_label.config(text=f"Se efectuează căutarea pentru: {query}")
    root.update()

    results = []
    try:
        search_results = search(query)
        for i, url in enumerate(search_results, 1):
            if i > num_results:
                break
            results.append(url)
            if i < num_results:
                time.sleep(2)  # Pauză manuală de 2 secunde
    except Exception as e:
        status_label.config(text=f"Eroare în timpul căutării: {e}")
        return

    status_label.config(text=f"Număr de rezultate găsite: {len(results)}")
    root.update()

    if output_file:
        with open(output_file, "w", encoding="utf-8") as f:
            for i, url in enumerate(results, 1):
                status_label.config(text=f"Procesare URL {i}/{len(results)}: {url}")
                root.update()
                extracted_text = process_url(url)
                if extracted_text:
                    f.write(f"\n--- Text extras din {url} ---\n")
                    f.write(extracted_text)
                    f.write("\n-------------------\n")
                else:
                    f.write(f"Nu s-a putut extrage textul din {url}\n")
    else:
        for i, url in enumerate(results, 1):
            status_label.config(text=f"Procesare URL {i}/{len(results)}: {url}")
            root.update()
            extracted_text = process_url(url)
            if extracted_text:
                print(f"\n--- Text extras din {url} ---\n{extracted_text}\n-------------------")
            else:
                print(f"Nu s-a putut extrage textul din {url}")

    status_label.config(text="Procesare finalizată!")
    messagebox.showinfo("Succes", "Am terminat de colectat!")

# Configurarea interfeței grafice
def create_gui():
    global root
    root = tk.Tk()
    root.title("Căutare și Extragere Text")
    root.geometry("500x400")

    # Etichete și câmpuri de introducere
    tk.Label(root, text="Termen de căutare:").pack(pady=5)
    query_entry = tk.Entry(root, width=50)
    query_entry.pack()

    tk.Label(root, text="Număr de rezultate:").pack(pady=5)
    num_entry = tk.Entry(root, width=10)
    num_entry.insert(0, "10")
    num_entry.pack()

    tk.Label(root, text="Tip de fișier (pdf, txt, html, docx):").pack(pady=5)
    filetype_entry = tk.Entry(root, width=20)
    filetype_entry.pack()

    tk.Label(root, text="Fișier de ieșire (ex. rezultat.txt):").pack(pady=5)
    output_entry = tk.Entry(root, width=50)
    output_entry.pack()

    # Etichetă pentru status
    status_label = tk.Label(root, text="Aștept introducerea datelor...", wraplength=450)
    status_label.pack(pady=10)

    # Buton de start
    def start_processing():
        query = query_entry.get().strip()
        num_results = int(num_entry.get().strip() or 10)
        filetype = filetype_entry.get().strip().lower()
        output_file = output_entry.get().strip()

        if not query:
            messagebox.showerror("Eroare", "Introdu un termen de căutare!")
            return
        if filetype and filetype not in ['pdf', 'txt', 'html', 'docx']:
            messagebox.showerror("Eroare", "Tip de fișier invalid! Opțiuni: pdf, txt, html, docx")
            return

        run_search(query, num_results, filetype, output_file, status_label)

    tk.Button(root, text="Începe procesarea", command=start_processing).pack(pady=20)

    root.mainloop()

if __name__ == "__main__":
    if not docx:
        print("Avertisment: Modulul 'python-docx' nu este instalat. Fișierele DOCX nu vor fi procesate.")
    try:
        import newspaper
    except ImportError:
        print("Eroare: Modulul 'newspaper3k' nu este instalat. Instalează-l cu 'pip install newspaper3k'.")
        exit(1)
    try:
        from youtube_transcript_api import YouTubeTranscriptApi
    except ImportError:
        print("Eroare: Modulul 'youtube_transcript_api' nu este instalat. Instalează-l cu 'pip install youtube-transcript-api'.")
        exit(1)
    create_gui()
