import os
import argostranslate.package
import argostranslate.translate
from tkinter import filedialog, Tk
import pdfplumber
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from tqdm import tqdm
import re

# Configurare traducere Argos
def setup_argos_translation(from_lang="en", to_lang="ro"):
    """
    Configurează pachetul de traducere Argos pentru limbile specificate.
    Returnează True dacă reușește, False dacă eșuează.
    """
    try:
        print("Se actualizează indexul pachetelor de traducere...")
        argostranslate.package.update_package_index()
        available_packages = argostranslate.package.get_available_packages()
        package = next(
            (p for p in available_packages if p.from_code == from_lang and p.to_code == to_lang),
            None
        )
        if not package:
            print(f"Nu există pachet de traducere pentru {from_lang} -> {to_lang}.")
            return False
        
        print(f"Se descarcă pachetul de traducere {from_lang} -> {to_lang}...")
        argostranslate.package.install_from_path(package.download())
        return True
    except Exception as e:
        print(f"Eroare la configurarea traducătorului: {e}")
        return False

# Extragere text din PDF
def extract_text_with_position(pdf_file):
    """
    Extrage textul din PDF linie cu linie, cu pozițiile sale.
    Returnează o listă de dicționare cu text și coordonate sau None dacă eșuează.
    """
    text_lines = []
    try:
        with pdfplumber.open(pdf_file) as pdf:
            total_pages = len(pdf.pages)
            print(f"Se procesează {total_pages} pagini...")
            for page_num, page in enumerate(pdf.pages, 1):
                lines = page.extract_text_lines()
                for line in lines:
                    text_lines.append({
                        "text": line["text"],
                        "x0": line["x0"],
                        "top": line["top"],
                        "page": page_num,
                        "width": page.width,
                        "height": page.height,
                        "x1": line["x1"]
                    })
                print(f"Pagina {page_num}/{total_pages} procesată.")
        return text_lines
    except Exception as e:
        print(f"Eroare la extragerea textului din PDF: {e}")
        return None

# Detectare și gestionare formule matematice
def handle_math_formulas(text):
    """
    Detectează formulele matematice între $...$ sau $$...$$ și le separă.
    Returnează o pereche: lista formulelor și textul cu placeholder.
    """
    math_pattern = r'\$\$?.*?\$\$?|\$.*?\$'
    formulas = re.findall(math_pattern, text)
    text_with_placeholder = re.sub(math_pattern, "###MATH###", text)
    return formulas, text_with_placeholder

# Traducere text
def translate_with_formulas(text, from_lang="en", to_lang="ro"):
    """
    Traduce textul păstrând formulele matematice intacte.
    Returnează textul tradus cu formulele reintroduse.
    """
    formulas, text_placeholder = handle_math_formulas(text)
    translated = argostranslate.translate.translate(text_placeholder, from_lang, to_lang)
    for formula in formulas:
        translated = translated.replace("###MATH###", formula, 1)
    return translated

# Generare PDF tradus
def generate_translated_pdf(text_data, translated_texts, output_file, page_sizes):
    """
    Creează un PDF nou cu textul tradus, păstrând pozițiile originale.
    Formulele sunt afișate ca text cu font matematic.
    """
    try:
        pdfmetrics.registerFont(TTFont("DejaVuSans", "DejaVuSans.ttf"))
        pdf_canvas = canvas.Canvas(output_file, pagesize=letter)
        current_page = 1

        print("Se generează PDF-ul tradus...")
        for i, item in enumerate(tqdm(text_data, desc="Generare PDF")):
            if item["page"] != current_page:
                pdf_canvas.showPage()
                current_page = item["page"]
                pdf_canvas.setPageSize((item["width"], item["height"]))

            translated_text = translated_texts[i]
            y_pos = item["height"] - item["top"]
            pdf_canvas.setFont("DejaVuSans", 12)

            # Ajustăm dimensiunea fontului dacă textul e prea lung
            original_width = item["x1"] - item["x0"]
            text_width = pdf_canvas.stringWidth(translated_text, "DejaVuSans", 12)
            if text_width > original_width:
                font_size = 12 * (original_width / text_width)
                font_size = max(font_size, 6)  # Minim 6pt pentru lizibilitate
                pdf_canvas.setFont("DejaVuSans", font_size)

            pdf_canvas.drawString(item["x0"], y_pos, translated_text)

        pdf_canvas.save()
        print(f"PDF generat cu succes: {output_file}")
    except Exception as e:
        print(f"Eroare la generarea PDF-ului: {e}")
        raise

# Funcția principală
def process_pdf_translation():
    """Procesează și traduce un PDF selectat de utilizator."""
    # Verificăm traducerea Argos
    if not setup_argos_translation("en", "ro"):
        return

    # Selectăm fișierul PDF
    root = Tk()
    root.withdraw()
    pdf_file = filedialog.askopenfilename(
        title="Selectează fișierul PDF de tradus",
        filetypes=[("PDF files", "*.pdf")]
    )
    root.destroy()

    if not pdf_file:
        print("Niciun fișier PDF selectat.")
        return

    # Setăm folderul de ieșire lângă script
    script_dir = os.path.dirname(os.path.abspath(__file__))
    output_dir = os.path.join(script_dir, "translated")
    os.makedirs(output_dir, exist_ok=True)

    # Extragem textul
    text_data = extract_text_with_position(pdf_file)
    if not text_data:
        return

    # Traducem textul
    original_texts = [item["text"] for item in text_data]
    translated_texts = []
    print("Se traduce textul...")
    for text in tqdm(original_texts, desc="Traducere"):
        translated_texts.append(translate_with_formulas(text, "en", "ro"))

    # Generăm PDF-ul tradus
    output_file = os.path.join(
        output_dir, f"{os.path.splitext(os.path.basename(pdf_file))[0]}_translated.pdf"
    )
    with pdfplumber.open(pdf_file) as pdf:
        page_sizes = [(page.width, page.height) for page in pdf.pages]

    generate_translated_pdf(text_data, translated_texts, output_file, page_sizes)

if __name__ == "__main__":
    process_pdf_translation()
