#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys as _sys
_sys.stdout.reconfigure(encoding="utf-8", errors="replace")
_sys.stderr.reconfigure(encoding="utf-8", errors="replace")
"""
06_nasledny_lekar.py
====================
Pro všechny ukončené pacienty (103) se dotáže VZP ke dni ukonceni+1
na jejich nového praktického lékaře (odbornost 001).

Výsledek je jeden ze tří stavů:
  nenalezen  → pacient u VZP neexistuje (zemřel / přestal být pojištěný)
  bez_lekare → pacient existuje, ale nemá GP (dosud se nepřehlásil)
  prehlasil  → přehlásil se k novému lékaři (ukládáme ICP, jméno, datum)

Ukládá do tabulky seznam_pojistencu_nasledny_lekar.
Přeskočí pacienty, kteří tam už jsou (resumovatelný běh).
"""

import sys
import time
import xml.etree.ElementTree as ET
from datetime import date, timedelta
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "Knihovny"))
from mysql_db import connect_mysql
from vzpb2b_client import VZPB2BClient

PFX_PATH     = str(Path(__file__).resolve().parents[1] / "Certificates" / "picka.pfx")
PFX_PASSWORD = "Vlado7309208104+"
ICZ          = "09305000"
API_PAUSE    = 2

CREATE_SQL = """
CREATE TABLE IF NOT EXISTS seznam_pojistencu_nasledny_lekar (
    id              INT          NOT NULL AUTO_INCREMENT PRIMARY KEY,
    cip             VARCHAR(12)  NOT NULL,
    prijmeni        VARCHAR(60)  NOT NULL,
    jmeno           VARCHAR(40)  NOT NULL,
    datum_ukonceni  DATE         NOT NULL COMMENT 'Datum ukončení u nás',
    datum_dotazu    DATE         NOT NULL COMMENT 'Dotaz k datu ukonceni+1',
    stav_vzp        VARCHAR(20)  NOT NULL COMMENT 'nenalezen / bez_lekare / prehlasil',
    stav_vyrizeni   VARCHAR(10)      NULL COMMENT 'stavVyrizeniPozadavku z VZP',
    novy_icp        VARCHAR(20)      NULL,
    novy_icz        VARCHAR(20)      NULL,
    novy_nazev      VARCHAR(200)     NULL COMMENT 'nazevSZZ — jméno lékaře',
    novy_ordinace   VARCHAR(200)     NULL COMMENT 'nazevICP — název ordinace',
    datum_prehlaseni DATE            NULL COMMENT 'datumRegistrace u nového lékaře',
    dotazeno_dne    DATE         NOT NULL,
    UNIQUE KEY uq_cip (cip)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
  COMMENT='Stav pojištěnce ke dni ukončení registrace u naší ordinace';
"""

NS = "http://xmlns.gemsystem.cz/B2B/RegistracePojistencePZSB2B/1"


def parse_nasledny(xml_text: str) -> dict:
    """
    Vrátí dict s klíči: stav_vzp, stav_vyrizeni, novy_icp, novy_icz,
    novy_nazev, novy_ordinace, datum_prehlaseni.
    """
    try:
        root = ET.fromstring(xml_text)
    except ET.ParseError:
        return {"stav_vzp": "chyba_xml", "stav_vyrizeni": None,
                "novy_icp": None, "novy_icz": None, "novy_nazev": None,
                "novy_ordinace": None, "datum_prehlaseni": None}

    def find(el, tag):
        e = el.find(f"{{{NS}}}{tag}")
        return e.text.strip() if e is not None and e.text else None

    stav_vyrizeni = find(root, "stavVyrizeniPozadavku")

    # Hledám odbornost 001 s jiným lékařem
    odbornosti = root.findall(f".//{{{NS}}}odbornost")
    for odb in odbornosti:
        # Vnější element — má ICZ
        icz = find(odb, "ICZ")
        icp = find(odb, "ICP")
        if not icp:
            continue
        # Ověřím odbornost (vnořený subelement)
        sub = odb.find(f"{{{NS}}}odbornost")
        if sub is None:
            continue
        kod = find(sub, "kod")
        if kod != "001":
            continue
        # Nalezen nový GP
        dr = date.fromisoformat(find(odb, "datumRegistrace")) \
             if find(odb, "datumRegistrace") else None
        return {
            "stav_vzp":        "prehlasil",
            "stav_vyrizeni":   stav_vyrizeni,
            "novy_icp":        icp,
            "novy_icz":        icz,
            "novy_nazev":      find(odb, "nazevSZZ"),
            "novy_ordinace":   find(odb, "nazevICP"),
            "datum_prehlaseni": dr,
        }

    # Žádná odbornost 001 nenalezena
    if stav_vyrizeni == "0":
        stav = "nenalezen"
    elif stav_vyrizeni == "1":
        stav = "bez_lekare"
    else:
        # Zkusím ještě — pokud jsou nějaké záznamy ale ne 001, je to bez_lekare
        stav = "nenalezen" if not odbornosti else "bez_lekare"

    return {"stav_vzp": stav, "stav_vyrizeni": stav_vyrizeni,
            "novy_icp": None, "novy_icz": None, "novy_nazev": None,
            "novy_ordinace": None, "datum_prehlaseni": None}


# ── Načtení ukončených pacientů ───────────────────────────────────────────────

conn = connect_mysql()
cur  = conn.cursor()
cur.execute(CREATE_SQL)

# Ukončení z vzp_registrace_lekari
cur.execute("""
    SELECT r.rc, r.prijmeni, r.jmeno, r.datum_ukonceni
    FROM vzp_registrace_lekari r
    INNER JOIN (
        SELECT rc, MAX(k_datu) mk
        FROM vzp_registrace_lekari
        WHERE kod_odbornosti='001' AND ICP='09305001' AND ma_lekare=1
        GROUP BY rc
    ) l ON r.rc=l.rc AND r.k_datu=l.mk
    WHERE r.kod_odbornosti='001' AND r.ICP='09305001'
      AND r.datum_ukonceni < '3000-01-01' AND r.datum_ukonceni < CURDATE()
""")
pacienti = [(r[0], r[1] or "", r[2] or "", r[3]) for r in cur.fetchall()]

# Doplním ze zlomů (13 nespárovaných)
cur.execute("""
    SELECT cip, prijmeni, jmeno, zlom_datum
    FROM seznam_pojistencu_zlomy
    WHERE stav='ukončen' AND zlom_datum IS NOT NULL AND zlom_datum < CURDATE()
""")
for r in cur.fetchall():
    if r[0] not in {p[0] for p in pacienti}:
        pacienti.append((r[0], r[1], r[2], r[3]))

# Přeskočím již zpracované
cur.execute("SELECT cip FROM seznam_pojistencu_nasledny_lekar")
hotovi = {r[0] for r in cur.fetchall()}
ke_zpracovani = [(c, p, j, d) for c, p, j, d in pacienti if c not in hotovi]

print(f"Ukončených celkem:    {len(pacienti)}")
print(f"Již zpracováno:       {len(hotovi)}")
print(f"Ke zpracování:        {len(ke_zpracovani)}")

if not ke_zpracovani:
    print("Vše již zpracováno.")
    cur.close(); conn.close(); sys.exit(0)

vzp = VZPB2BClient("prod", PFX_PATH, PFX_PASSWORD, icz=ICZ)

# ── Hlavní smyčka ─────────────────────────────────────────────────────────────
print()
sirka = max(len(f"{p} {j}") for _, p, j, _ in ke_zpracovani) + 2

for i, (cip, pri, jme, du) in enumerate(ke_zpracovani, 1):
    datum_dotazu = du + timedelta(days=1)
    jmeno_str = f"{pri} {jme}"
    print(f"[{i:>3}/{len(ke_zpracovani)}] {jmeno_str:<{sirka}} ({cip})  k {datum_dotazu}", end="  ", flush=True)

    try:
        xml = vzp.registrace_lekare(cip, datum_dotazu.isoformat(), odbornosti=["001"])
        time.sleep(API_PAUSE)
        vysl = parse_nasledny(xml)
    except Exception as e:
        print(f"CHYBA: {e}")
        vysl = {"stav_vzp": "chyba", "stav_vyrizeni": str(e),
                "novy_icp": None, "novy_icz": None, "novy_nazev": None,
                "novy_ordinace": None, "datum_prehlaseni": None}

    # Výpis
    stav = vysl["stav_vzp"]
    if stav == "prehlasil":
        print(f"→ přehlásil se: {vysl['novy_nazev']} (ICP {vysl['novy_icp']}, od {vysl['datum_prehlaseni']})")
    elif stav == "bez_lekare":
        print("→ bez nového lékaře")
    elif stav == "nenalezen":
        print("→ nenalezen (zemřel / nepojištěný)")
    else:
        print(f"→ {stav}")

    cur.execute("""
        INSERT INTO seznam_pojistencu_nasledny_lekar
            (cip, prijmeni, jmeno, datum_ukonceni, datum_dotazu, stav_vzp,
             stav_vyrizeni, novy_icp, novy_icz, novy_nazev, novy_ordinace,
             datum_prehlaseni, dotazeno_dne)
        VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)
        ON DUPLICATE KEY UPDATE
            datum_ukonceni=VALUES(datum_ukonceni),
            datum_dotazu=VALUES(datum_dotazu),
            stav_vzp=VALUES(stav_vzp), stav_vyrizeni=VALUES(stav_vyrizeni),
            novy_icp=VALUES(novy_icp), novy_icz=VALUES(novy_icz),
            novy_nazev=VALUES(novy_nazev), novy_ordinace=VALUES(novy_ordinace),
            datum_prehlaseni=VALUES(datum_prehlaseni),
            dotazeno_dne=VALUES(dotazeno_dne)
    """, (cip, pri, jme, du, datum_dotazu, stav,
          vysl["stav_vyrizeni"], vysl["novy_icp"], vysl["novy_icz"],
          vysl["novy_nazev"], vysl["novy_ordinace"], vysl["datum_prehlaseni"],
          date.today()))

cur.close()
conn.close()

# ── Souhrn ────────────────────────────────────────────────────────────────────
print(f"\nHotovo. Zpracováno {len(ke_zpracovani)} pacientů.")
