"""
02 - Stažení VŠECH zpráv ze všech schránek VoZP portálu (jednorázová akce)
Prochází stránkování, stahuje všechny soubory a pojmenuje je:
  YYYY-MM-DD Popis (původní_název).přípona
Použití: python 02_stahuj_vse.py
"""

import json
import os
import re
import sys
import time
import winreg
from datetime import datetime
from pathlib import Path

sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", ".."))
from Knihovny.najdi_dropbox import get_dropbox_root

LOGIN_URL    = "https://portal.vozp.cz/app/prihlaseni"
BASE_URL     = "https://portal.vozp.cz"
INBOX_URL    = f"{BASE_URL}/app/prehled-zprav-ve-schrankach"
DOWNLOAD_URL = f"{BASE_URL}/html/prehled-zprav-ve-schrankach/zobrazit-prilohu"

CHROME_PROFILE = os.path.abspath(os.path.join(os.path.dirname(__file__), "chrome_profile"))
COOKIES_FILE   = os.path.abspath(os.path.join(os.path.dirname(__file__), "vozp_cookies.json"))
DOWNLOAD_DIR   = os.path.join(get_dropbox_root(), "Ordinace", "Dokumentace_ke_zpracování", "Zúčtovací zprávy", "201 VoZP")

# Všechny schránky — ID-segment : zobrazovaný název
SCHRANKY = {
    "171-schranka-poskytovatele-zdravotnich-sluzeb": "Schránka PZS",
    "183-schranka-klientu-portalu":                  "Schránka klientů portálu",
    "185-schranka-pzs":                              "Schránka PZS2",
    "187-schranka-klienta":                          "Schránka klienta",
    "198-vypis-registrovanych-pacientu":             "Výpis registrovaných pacientů",
    "200-zuctovaci-zpravy":                          "Zúčtovací zprávy",
    "205-vypis-osobnich-uctu-pojistencu":            "Výpis osobních účtů pojištěnců",
}


def load_cookies(context) -> int:
    if not os.path.exists(COOKIES_FILE):
        return 0
    try:
        with open(COOKIES_FILE, "r", encoding="utf-8") as f:
            cookies = json.load(f)
        context.add_cookies(cookies)
        return len(cookies)
    except Exception:
        return 0


def save_cookies(context) -> int:
    try:
        all_cookies = context.cookies()
        vozp = [c for c in all_cookies if any(
            d in c.get("domain", "") for d in ["vozp.cz", "portalzp.cz"]
        )]
        with open(COOKIES_FILE, "w", encoding="utf-8") as f:
            json.dump(vozp, f, indent=2, ensure_ascii=False)
        return len(vozp)
    except Exception:
        return 0


def _delete_chrome_cert_policy() -> None:
    key_path = r"SOFTWARE\Policies\Google\Chrome\AutoSelectCertificateForUrls"
    try:
        key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, key_path, access=winreg.KEY_SET_VALUE)
        winreg.DeleteValue(key, "1")
        winreg.CloseKey(key)
    except Exception:
        pass


def parse_date(date_str: str) -> str:
    """Převede 'DD.MM.YYYY HH:MM:SS' na 'YYYY-MM-DD'."""
    try:
        dt = datetime.strptime(date_str.strip()[:19], "%d.%m.%Y %H:%M:%S")
        return dt.strftime("%Y-%m-%d")
    except Exception:
        try:
            dt = datetime.strptime(date_str.strip()[:10], "%d.%m.%Y")
            return dt.strftime("%Y-%m-%d")
        except Exception:
            return "0000-00-00"


def safe_filename(name: str) -> str:
    """Odstraní znaky nevhodné pro název souboru."""
    return re.sub(r'[\\/:*?"<>|]', "_", name).strip()


def parse_row(cells: list[str]) -> dict:
    """
    Zpracuje buňky řádku tabulky.
    cells[1] = datum
    cells[2] = víceřádkový popis
    cells[3] = 'název_souboru.ext (DD.MM.YYYY)'
    """
    date_raw  = cells[1].strip() if len(cells) > 1 else ""
    desc_raw  = cells[2].strip() if len(cells) > 2 else ""
    fname_raw = cells[3].strip() if len(cells) > 3 else ""

    # Parsuj popis — řádky odděleny \n
    desc_lines = [l.strip() for l in desc_raw.split("\n") if l.strip()]
    if len(desc_lines) >= 3:
        description = desc_lines[2]   # "Odpověď na podání č. 123 (...)"
    elif len(desc_lines) >= 2:
        description = desc_lines[1]   # "01.02.2026 - 26.02.2026"
    else:
        description = desc_lines[0] if desc_lines else ""

    # Zkrať příliš dlouhý popis
    description = description[:80]

    # Parsuj název souboru: "Protokol-OK.html (15.04.2026)" → stem="Protokol-OK", ext=".html"
    fname_match = re.match(r'^(.+?)\s*\(\d{2}\.\d{2}\.\d{4}\)\s*$', fname_raw)
    original = fname_match.group(1).strip() if fname_match else fname_raw.split("(")[0].strip()
    orig_path = Path(original)
    stem = orig_path.stem or "zprava"
    ext  = orig_path.suffix or ""

    date_iso = parse_date(date_raw)
    name = f"{date_iso} {safe_filename(description)} ({safe_filename(stem)}){ext}"
    if len(name) > 240:
        name = f"{date_iso} ({safe_filename(stem)}){ext}"

    return {
        "date":     date_iso,
        "desc":     description,
        "original": original,
        "filename": name,
    }


def collect_rows(page) -> list[dict]:
    """Vrátí seznam řádků aktuální stránky tabulky."""
    data = page.evaluate("""() => {
        const rows = [];
        for (const tr of document.querySelectorAll('table tr')) {
            const cells = Array.from(tr.querySelectorAll('td')).map(td => td.innerText.trim());
            if (cells.length < 4) continue;
            const dlLink = tr.querySelector('a[onclick*="SchrPolOpenFile"]');
            if (!dlLink) continue;
            const m = dlLink.getAttribute('onclick').match(/\\d+/);
            rows.push({ cells, fileId: m ? m[0] : null });
        }
        return rows;
    }""")
    return [r for r in data if r["fileId"]]


def download_file(context, file_id: str, target: str) -> bool:
    """Stáhne soubor přes Playwright request context (sdílí cookies se session)."""
    url = f"{DOWNLOAD_URL}?zprava_id={file_id}"
    try:
        r = context.request.get(url, headers={"Referer": INBOX_URL})
        if not r.ok:
            print(f"    HTTP {r.status} (id={file_id})")
            return False
        with open(target, "wb") as f:
            f.write(r.body())
        return True
    except Exception as e:
        print(f"    Chyba stahování (id={file_id}): {e}")
        return False


def process_schránka(page, context, segment: str, name: str, already: set) -> tuple[int, int]:
    """Projde všechny stránky schránky a stáhne soubory. Vrací (staženo, přeskočeno)."""
    downloaded = 0
    skipped = 0
    page_num = 1
    seen_ids: set = set()

    while True:
        url = f"{INBOX_URL}/{segment}/stranka-{page_num}"
        print(f"  Stránka {page_num}: {url}")
        try:
            page.goto(url, wait_until="domcontentloaded", timeout=30_000)
        except Exception as e:
            print(f"  Navigace selhala: {e}")
            break

        page.wait_for_load_state("networkidle", timeout=15_000)
        rows = collect_rows(page)

        if not rows:
            print(f"  Stránka {page_num} — žádné řádky, končím schránku.")
            break

        # Portál vrátí poslední stránku znovu místo prázdné — detekuj opakování
        current_ids = {r["fileId"] for r in rows}
        if current_ids & seen_ids:
            print(f"  Stránka {page_num} — opakující se obsah, končím schránku.")
            break
        seen_ids.update(current_ids)

        print(f"  Nalezeno {len(rows)} zpráv.")

        for row in rows:
            info = parse_row(row["cells"])
            target = os.path.join(DOWNLOAD_DIR, info["filename"])

            if info["filename"] in already or os.path.exists(target):
                skipped += 1
                continue

            print(f"    Stahuji: {info['filename']}")
            if download_file(context, row["fileId"], target):
                already.add(info["filename"])
                downloaded += 1
            time.sleep(0.3)

        page_num += 1

    return downloaded, skipped


def ensure_logged_in(page, context) -> bool:
    """Ověří přihlášení. Pokud cookies nestačí, upozorní na spuštění 01."""
    try:
        page.goto(INBOX_URL, wait_until="domcontentloaded", timeout=30_000)
    except Exception as e:
        print(f"Navigace: {e}")

    if "prihlaseni" in page.url or "login" in page.url.lower():
        print("=" * 60)
        print("Cookies neplatné nebo vypršely.")
        print("Spusť znovu:  python 01_prihlaseni.py")
        print("=" * 60)
        return False

    print(f"Přihlášení OK (přes cookies). URL: {page.url}")
    return True


def main() -> None:
    try:
        from playwright.sync_api import sync_playwright
    except ImportError:
        print("Chybí playwright: pip install playwright && playwright install chrome")
        sys.exit(1)

    os.makedirs(DOWNLOAD_DIR, exist_ok=True)
    _delete_chrome_cert_policy()

    with sync_playwright() as p:
        context = p.chromium.launch_persistent_context(
            user_data_dir=CHROME_PROFILE,
            channel="chrome",
            headless=False,
            slow_mo=100,
            ignore_https_errors=True,
            args=["--force-renderer-accessibility"],
        )
        logged_in = False
        try:
            loaded = load_cookies(context)
            print(f"Cookies načtené z JSON: {loaded}")

            page = context.new_page()

            if not ensure_logged_in(page, context):
                return

            logged_in = True
            already = set(os.listdir(DOWNLOAD_DIR))
            print(f"V archivu: {len(already)} souborů.\n")

            total_dl = 0
            total_skip = 0

            for segment, name in SCHRANKY.items():
                print(f"\n=== Schránka: {name} ===")
                dl, sk = process_schránka(page, context, segment, name, already)
                print(f"  Schránka {name}: staženo {dl}, přeskočeno {sk}")
                total_dl += dl
                total_skip += sk

            print(f"\n{'='*50}")
            print(f"Hotovo. Celkem staženo: {total_dl}, přeskočeno: {total_skip}")

        finally:
            if logged_in:
                saved = save_cookies(context)
                print(f"Uloženo {saved} VoZP cookies.")
            context.close()


if __name__ == "__main__":
    main()
