import fitz  # PyMuPDF
import pytesseract
from PIL import Image
import io
import os
import re
import fdb  # Firebeird database library

# ==========================================
#              KONFIGURACE
# ==========================================

# 1. Cesty k souborům
INPUT_FOLDER = r'u:\Dropbox\Ordinace\Dokumentace_ke_zpracování\AdobeMakeSmaller'
OUTPUT_FOLDER = os.path.join(INPUT_FOLDER, '_HOTOVO_MEDICUS')

# 2. Tesseract OCR
PATH_TO_TESSERACT = r'C:\Program Files\Tesseract-OCR\tesseract.exe'

# 3. Kvalita výstupu (Ultimate metoda)
VISUAL_DPI = 150  # Pro zobrazení (malé)
VISUAL_THRESHOLD = 150  # Práh černé
OCR_DPI = 300  # Pro čtení (velké)

# 4. Databáze MEDICUS (Firebird)
DB_CONFIG = {
    'host': "192.168.1.4",
    'port': 3050,
    'database': r"z:\Medicus 3\data\MEDICUS.FDB",
    'user': "SYSDBA",
    'password': "masterkey",
    'charset': "WIN1250"  # Čeština ve Windows
}


# ==========================================
#              FUNKCE
# ==========================================

def setup_tesseract():
    if not os.path.exists(PATH_TO_TESSERACT):
        print(f"CHYBA: Tesseract nenalezen na: {PATH_TO_TESSERACT}")
        return False
    pytesseract.pytesseract.tesseract_cmd = PATH_TO_TESSERACT
    return True


def get_rc_candidates(text):
    """Vrátí seznam RČ nalezených v textu, očistěných od mezer a lomítek."""
    candidates = set()
    # Regex bere i mezery: 75 05 12 / 1234
    pattern = r'\b\d{2}\s*\d{2}\s*\d{2}\s*[\/]?\s*\d{3,4}\b'
    matches = re.findall(pattern, text)

    for match in matches:
        # Odstraníme vše kromě čísel -> vznikne čisté RČ pro DB
        clean = re.sub(r'[^\d]', '', match)
        if len(clean) in [9, 10]:
            candidates.add(clean)
    return list(candidates)


def get_patient_from_db(rc_clean):
    """
    Vrátí (True, "Prijmeni, Jmeno") pokud najde RČ v tabulce KAR.
    """
    con = None
    try:
        con = fdb.connect(**DB_CONFIG)
        cur = con.cursor()

        # Medicus má RČ bez lomítka, takže se ptáme rovnou
        sql = "SELECT prijmeni, jmeno FROM kar WHERE rodcis = ?"
        cur.execute(sql, (rc_clean,))
        row = cur.fetchone()

        if row:
            # row[0] = Prijmeni, row[1] = Jmeno
            # .strip() je nutný, databáze vrací mezery na konci (CHAR field)
            prijmeni = str(row[0]).strip()
            jmeno = str(row[1]).strip()

            formatted_name = f"{prijmeni}, {jmeno}"
            return True, formatted_name
        else:
            return False, None

    except Exception as e:
        print(f"   [DB ERROR] {e}")
        return False, None
    finally:
        if con:
            con.close()


def process_medicus_final():
    if not setup_tesseract():
        return

    if not os.path.exists(OUTPUT_FOLDER):
        os.makedirs(OUTPUT_FOLDER)

    files = [f for f in os.listdir(INPUT_FOLDER) if f.lower().endswith('.pdf')]
    print(f"Startuji zpracování {len(files)} souborů.")
    print(f"Výstupní formát: 'RC Prijmeni, Jmeno.pdf'")
    print("-" * 70)

    for filename in files:
        input_path = os.path.join(INPUT_FOLDER, filename)

        try:
            print(f"Zpracovávám: {filename}")

            doc_src = fitz.open(input_path)
            final_doc = fitz.open()

            found_rc = None
            found_name = None

            # --- 1. PRŮCHOD STRÁNKAMI ---
            for page_num, page in enumerate(doc_src):

                # A) PŘÍPRAVA OCR VRSTVY (High Res)
                mat_ocr = fitz.Matrix(OCR_DPI / 72, OCR_DPI / 72)
                pix_ocr = page.get_pixmap(matrix=mat_ocr, colorspace=fitz.csGRAY)
                img_ocr = Image.frombytes("L", [pix_ocr.width, pix_ocr.height], pix_ocr.samples)

                # Tesseract vytvoří PDF stránku
                pdf_bytes = pytesseract.image_to_pdf_or_hocr(img_ocr, extension='pdf', lang='ces')
                ocr_page_doc = fitz.open("pdf", pdf_bytes)
                ocr_page = ocr_page_doc[0]

                # B) HLEDÁNÍ PACIENTA (pokud ještě nemáme)
                if not found_rc:
                    text = ocr_page.get_text()
                    candidates = get_rc_candidates(text)

                    for cand in candidates:
                        print(f"   -> Ověřuji v DB: {cand} ...", end=" ")
                        exists, name_str = get_patient_from_db(cand)

                        if exists:
                            print(f"NALEZEN: {name_str}")
                            found_rc = cand
                            found_name = name_str
                            break  # Máme ho!
                        else:
                            print("Nenalezen.")

                # C) PŘÍPRAVA VIZUÁLNÍ VRSTVY (Low Res - Zmenšení)
                mat_vis = fitz.Matrix(VISUAL_DPI / 72, VISUAL_DPI / 72)
                pix_vis = page.get_pixmap(matrix=mat_vis, colorspace=fitz.csGRAY)
                img_vis = Image.frombytes("L", [pix_vis.width, pix_vis.height], pix_vis.samples)
                # Threshold
                img_vis_bw = img_vis.point(lambda x: 255 if x > VISUAL_THRESHOLD else 0, mode='1')

                buffer_vis = io.BytesIO()
                img_vis_bw.save(buffer_vis, format="PNG", optimize=True)

                # D) PROHOZENÍ OBRÁZKŮ (Ultimate trick)
                images = ocr_page.get_images()
                if images:
                    xref = images[0][0]
                    ocr_page.delete_image(xref)  # Smaže velký

                # Vloží malý
                ocr_page.insert_image(ocr_page.rect, stream=buffer_vis.getvalue(), keep_proportion=True)

                # Přidá stránku do finálního PDF
                final_doc.insert_pdf(ocr_page_doc)

            # --- 2. ULOŽENÍ SOUBORU ---
            if found_rc and found_name:
                # Formát: 1234567890 NOVAK, JAN.pdf
                # Odstraníme případné nepovolené znaky ve jméně (pro jistotu)
                safe_name = re.sub(r'[\\/*?:"<>|]', "", found_name)
                new_filename = f"{found_rc} {safe_name}.pdf"
            else:
                new_filename = f"{os.path.splitext(filename)[0]}_neovereno.pdf"

            # Řešení konfliktů (kdyby soubor už existoval)
            counter = 1
            base_name = os.path.splitext(new_filename)[0]
            while os.path.exists(os.path.join(OUTPUT_FOLDER, new_filename)):
                new_filename = f"{base_name}_{counter}.pdf"
                counter += 1

            output_path = os.path.join(OUTPUT_FOLDER, new_filename)

            final_doc.save(output_path, garbage=4, deflate=True)
            final_doc.close()
            doc_src.close()

            size_kb = os.path.getsize(output_path) / 1024
            print(f"   -> Uloženo: {new_filename} ({size_kb:.1f} kB)")
            print("-" * 70)

        except Exception as e:
            print(f"CHYBA: {e}")

    print("\nHOTOVO.")


if __name__ == "__main__":
    process_medicus_final()