import subprocess
from pathlib import Path
from datetime import datetime
import zipfile
import time
import traceback

from EmailMessagingGraph import send_mail

# ============================================================
# CONFIG
# ============================================================

GBAK = r"C:\Program Files\Firebird\Firebird_2_5_CGM\bin\gbak.exe"
DB = r"localhost/3050:Z:\Medicus 3\data\MEDICUS.FDB"
BACKUP_DIR = Path(r"D:\medicusbackup")

FB_USER = "SYSDBA"
FB_PASS = "masterkey"

MAIL_TO = "vladimir.buzalka@buzalka.cz"

CHUNK = 8 * 1024 * 1024  # 8 MB


# ============================================================
# MAIN
# ============================================================

def main():
    BACKUP_DIR.mkdir(parents=True, exist_ok=True)

    now = datetime.now()
    ts = now.strftime("%Y-%m-%d_%H-%M-%S")

    fbk = BACKUP_DIR / f"MEDICUS_{ts}.fbk"
    zipf = fbk.with_suffix(".zip")
    log = BACKUP_DIR / f"MEDICUS_{ts}.log"

    report = []
    report.append(f"Čas spuštění: {now}")
    report.append(f"Databáze: {DB}")
    report.append("")

    try:
        # ====================================================
        # 1) GBAK
        # ====================================================
        t0 = time.time()

        cmd = [
            GBAK,
            "-b",
            "-user", FB_USER,
            "-pas", FB_PASS,
            DB,
            str(fbk),
            "-v",
        ]

        with open(log, "w", encoding="utf-8") as f:
            subprocess.run(
                cmd,
                stdout=f,
                stderr=subprocess.STDOUT,
                check=True,
            )

        t_gbak = time.time() - t0
        fbk_size = fbk.stat().st_size

        report.append("GBAK záloha: OK")
        report.append(f"FBK soubor: {fbk}")
        report.append(f"Velikost FBK: {fbk_size/1024/1024:.1f} MB")
        report.append(f"Čas GBAK: {t_gbak:.1f} s")
        report.append("")

        # ====================================================
        # 2) ZIP
        # ====================================================
        t1 = time.time()
        processed = 0

        with zipfile.ZipFile(
            zipf,
            "w",
            compression=zipfile.ZIP_DEFLATED,
            compresslevel=9,
        ) as zf:

            zi = zipfile.ZipInfo(fbk.name)
            zi.compress_type = zipfile.ZIP_DEFLATED

            with zf.open(zi, "w", force_zip64=True) as z:
                with open(fbk, "rb") as src:
                    while buf := src.read(CHUNK):
                        z.write(buf)
                        processed += len(buf)
                        pct = processed * 100 / fbk_size
                        print(
                            f"\rZIP: {pct:6.2f}% "
                            f"({processed//1024//1024} MB)",
                            end="",
                            flush=True,
                        )

        print("\nZIP hotov.")

        t_zip = time.time() - t1
        zip_size = zipf.stat().st_size

        report.append("ZIP komprese: OK")
        report.append(f"ZIP soubor: {zipf}")
        report.append(f"Velikost ZIP: {zip_size/1024/1024:.1f} MB")
        report.append(
            f"Kompresní poměr: "
            f"{100 * (1 - zip_size / fbk_size):.1f} %"
        )
        report.append(f"Čas ZIP: {t_zip:.1f} s")
        report.append("")

        # ====================================================
        # 3) DELETE FBK
        # ====================================================
        fbk.unlink()

        report.append("FBK soubor byl po úspěšné kompresi smazán.")
        report.append("")
        report.append(f"LOG: {log}")

        # ====================================================
        # MAIL OK
        # ====================================================
        send_mail(
            MAIL_TO,
            "✅ MEDICUS – záloha + ZIP OK",
            "\n".join(report),
        )

    except Exception:
        err = traceback.format_exc()

        send_mail(
            MAIL_TO,
            "❌ MEDICUS – chyba při záloze / ZIP",
            f"""Při záloze MEDICUS došlo k chybě.

Čas: {now}

Chyba:
{err}

FBK (pokud existuje): {fbk}
LOG: {log}
""",
        )
        raise


if __name__ == "__main__":
    main()
