"""
Stahování dokumentů ze ZPMVČR portálu (eforms.zpmvcr.cz).

Stahuje Zúčtovací zprávy a Avíza za celou dostupnou historii.

Použij po 01_prihlaseni.py (ten uloží zpmvcr_cookies.json).

JAK TO FUNGUJE:
  Portál používá POST formuláře. Stažení souboru:
    POST /eforms/.../zuctovaci_zprava
    data: bin=1, dl=1, historie=1, doc_id=<id>

POUŽITÍ:
  pip install playwright
  playwright install chrome
  python 02_stahuj_vse.py
"""

import glob
import json
import os
import re
import sys
import time
from datetime import datetime

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

BASE_URL   = "https://eforms.zpmvcr.cz"
ZPRAVY_URL = f"{BASE_URL}/eforms/smluvni_zdravotnicke_zarizeni/dokumenty_ke_stazeni/zuctovaci_zprava"
AVIZA_URL  = f"{BASE_URL}/eforms/smluvni_zdravotnicke_zarizeni/dokumenty_ke_stazeni/aviza"

COOKIES_FILE = os.path.abspath(os.path.join(os.path.dirname(__file__), "zpmvcr_cookies.json"))
DOWNLOAD_DIR = os.path.join(get_dropbox_root(), "Ordinace", "Dokumentace_ke_zpracování", "Zúčtovací zprávy", "211 ZPMVČR")

# Konfigurace sekcí — sloupce se liší podle stránky:
#   Zúčtovací zprávy: IČ | VarSymb | IntČ | Typ | Velikost | Období | Pobočka | Staženo
#   Avíza:            IČ | Dokument | Typ | Velikost | Období | Pobočka | Staženo
SEKCE = [
    {
        "name":          "Zúčtovací zprávy",
        "url":           ZPRAVY_URL,
        "need_history":  True,   # je třeba kliknout "Zobrazit historii"
        "dl_historie":   "1",    # hodnota pole 'historie' při stahování souboru
        "ident_col":     1,      # Variabilní symbol
        "typ_col":       3,      # Typ (pdf)
        "obdobi_col":    5,      # Období (01.02.2026)
        "ident_prefix":  "VS-",
    },
    {
        "name":          "Avíza",
        "url":           AVIZA_URL,
        "need_history":  False,  # Avíza zobrazuje vše rovnou
        "dl_historie":   "0",    # Avíza nevyužívá history mode — musí být 0
        "ident_col":     1,      # Název dokumentu
        "typ_col":       2,      # Typ (pdf)
        "obdobi_col":    4,      # Období (jen rok: 2024)
        "ident_prefix":  "",
    },
]


def parse_period(raw: str) -> str:
    """01.02.2026 → 2026-02  |  2024 → 2024"""
    try:
        return datetime.strptime(raw.strip()[:10], "%d.%m.%Y").strftime("%Y-%m")
    except Exception:
        cleaned = raw.strip()[:7].replace(".", "-")
        return cleaned if cleaned else "0000"


def safe_filename(name: str) -> str:
    return re.sub(r'[\\/:*?"<>|]', "_", name).strip()


def make_js_extract(ident_col: int, typ_col: int, obdobi_col: int) -> str:
    return f"""() => {{
        const KNOWN_EXTS = new Set(['pdf', 'xml', 'txt', 'zip', 'doc', 'xls', 'csv']);
        const docs = [];
        for (const inp of document.querySelectorAll('input[name="doc_id"]')) {{
            const docId = inp.value;
            if (!docId) continue;
            const td  = inp.closest('td');
            const tr  = td ? td.closest('tr') : null;
            let ident  = '', typ = 'pdf', obdobi = '';
            if (tr) {{
                const tds = Array.from(tr.querySelectorAll('td')).map(t => t.innerText.trim());
                ident   = tds[{ident_col}]  || '';
                const t = (tds[{typ_col}]   || '').toLowerCase().trim();
                typ     = KNOWN_EXTS.has(t) ? t : 'pdf';
                obdobi  = tds[{obdobi_col}] || '';
            }}
            docs.push({{ docId, ident, typ, obdobi }});
        }}
        return docs;
    }}"""


def click_next_page(page, page_num: int) -> bool:
    """Klikne na stránkovací input[name='page'][value='N+1']. Vrátí True pokud existoval."""
    # Stránkovací prvky jsou input[type=submit] s name="page" a value=číslo stránky
    # Příklad: <input name="page" type="submit" value="2" title="2. Strana">
    next_val = str(page_num + 1)
    btn = page.locator(f"input[name='page'][value='{next_val}']")
    if btn.count() == 0:
        return False
    btn.first.click()
    page.wait_for_load_state("networkidle", timeout=20_000)
    return True


def process_sekce(page, context, cfg: dict, already: set) -> tuple:
    name        = cfg["name"]
    url         = cfg["url"]
    ident_pfx   = cfg["ident_prefix"]
    js_extract  = make_js_extract(cfg["ident_col"], cfg["typ_col"], cfg["obdobi_col"])

    downloaded = 0
    skipped    = 0

    print(f"\n=== {name} ===")
    page.goto(url, wait_until="domcontentloaded", timeout=30_000)
    page.wait_for_load_state("networkidle", timeout=15_000)

    if cfg["need_history"]:
        hist = page.get_by_text("Zobrazit historii dokumentů za poslední 3 roky")
        if hist.count() > 0:
            hist.first.click()
            page.wait_for_load_state("networkidle", timeout=20_000)

    page_num  = 1
    seen_ids: set = set()

    while True:
        print(f"  Strana {page_num}...")
        docs = page.evaluate(js_extract)
        docs = [d for d in docs if d["docId"] not in seen_ids]

        if not docs:
            print(f"  Strana {page_num} — žádné nové dokumenty, konec sekce.")
            break

        seen_ids.update(d["docId"] for d in docs)
        print(f"  Nalezeno {len(docs)} dokumentů")

        for doc in docs:
            period  = parse_period(doc["obdobi"])
            ext     = doc["typ"] or "pdf"
            ident   = safe_filename(doc["ident"])
            label   = safe_filename(name)
            prefix  = ident_pfx + ident if ident else f"id-{doc['docId']}"
            filename = f"{period} {label} {prefix}.{ext}"
            target  = os.path.join(DOWNLOAD_DIR, filename)

            # Prefix je unikátní — soubor může mít různý suffix z Content-Disposition
            prefix_check = f"{period} {label} {prefix}"
            if any(f.startswith(prefix_check) for f in already) or glob.glob(
                os.path.join(DOWNLOAD_DIR, glob.escape(prefix_check) + "*")
            ):
                skipped += 1
                continue

            r = context.request.post(url, form={
                "bin": "1", "dl": "1", "historie": cfg["dl_historie"],
                "doc_id": doc["docId"], "save": "Stáhnout",
            }, timeout=60_000)

            if not r.ok:
                print(f"    HTTP {r.status} doc_id={doc['docId']}")
                time.sleep(1.0)
                continue

            # Content-Disposition pro originální název
            cd = r.headers.get("content-disposition", "")
            m  = re.search(r'filename=["\']?([^"\';\r\n]+)', cd)
            if m:
                orig      = m.group(1).strip()
                stem, suf = os.path.splitext(orig)
                ext2      = suf.lstrip(".").lower() or ext
                filename  = f"{period} {label} {prefix} ({safe_filename(stem)}).{ext2}"
                target    = os.path.join(DOWNLOAD_DIR, filename)

            with open(target, "wb") as f:
                f.write(r.body())
            print(f"    OK: {filename}")
            already.add(filename)
            downloaded += 1
            time.sleep(1.0)

        # Přejdi na další stránku
        if not click_next_page(page, page_num):
            break
        page_num += 1

    return downloaded, skipped


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

    os.makedirs(DOWNLOAD_DIR, exist_ok=True)

    if not os.path.exists(COOKIES_FILE):
        print(f"Soubor {COOKIES_FILE} nenalezen — spust 01_prihlaseni.py")
        sys.exit(1)

    with open(COOKIES_FILE, encoding="utf-8") as f:
        cookies = json.load(f)

    with sync_playwright() as p:
        context = p.chromium.launch_persistent_context(
            user_data_dir=os.path.join(os.path.dirname(__file__), "chrome_profile"),
            channel="chrome",
            headless=False,
            slow_mo=100,
            ignore_https_errors=True,
        )
        try:
            context.add_cookies(cookies)
            page = context.new_page()

            # Ověř přihlášení
            page.goto(ZPRAVY_URL, wait_until="domcontentloaded", timeout=30_000)
            page.wait_for_load_state("networkidle", timeout=15_000)
            if page.locator("input[name='pin']").count() > 0:
                print("Cookies expirovala — spust 01_prihlaseni.py")
                return
            print("Prihlaseni OK\n")

            already = set(os.listdir(DOWNLOAD_DIR))
            print(f"V archivu: {len(already)} souboru.")

            total_dl = total_skip = 0
            for cfg in SEKCE:
                dl, sk = process_sekce(page, context, cfg, already)
                print(f"  {cfg['name']}: stazeno {dl}, preskoceno {sk}")
                total_dl += dl
                total_skip += sk

            print(f"\nHotovo. Celkem stazeno: {total_dl}, preskoceno: {total_skip}")

        finally:
            context.close()


if __name__ == "__main__":
    main()
