#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
batch_stav0_20250101.py
========================
Zpracuje 50 pacientů, kteří k 1. 1. 2025 vrátili stavVyrizeniPozadavku=0
na dotaz registrace lékaře (= VZP pojištěnce nenašla).

Pro každého:
  1. Dotáže VZP stavPojisteni k 2025-01-01 → uloží do vzp_stav_pojisteni.
  2. Pokud stav != '1' a != '4', binárně hledá zlom pojištění
     a uloží do vzp_sledovani_pojisteni.

Resumovatelný — pacienty, kteří už mají záznam v vzp_stav_pojisteni
k 2025-01-01, přeskočí.
"""

import sys
import time
from pathlib import Path
from datetime import date, timedelta

PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
sys.path.insert(0, str(PROJECT_ROOT))

from Knihovny.mysql_db import connect_mysql
from Knihovny.vzpb2b_client import VZPB2BClient

# ── KONFIGURACE ───────────────────────────────────────────────────────────────

K_DATU    = date(2025, 1, 1)
API_DELAY = 1.5

PFX_PATH     = Path(__file__).resolve().parent.parent / "Certificates" / "picka.pfx"
PFX_PASSWORD = "Vlado7309208104+"
ICZ          = "00000000"
DIC          = "00000000"
ENV          = "prod"

# ── PACIENTI ─────────────────────────────────────────────────────────────────

PACIENTI = [
    ("415513130",  "Rohlíková",     "Marie"),
    ("420622031",  "Hamerník",      "Josef"),
    ("430127082",  "Anderle",       "Václav"),
    ("435625017",  "Kafková",       "Marie"),
    ("436005111",  "Plzáková",      "Ivana"),
    ("445624103",  "Kloučková",     "Vlasta"),
    ("446116017",  "Strnadová",     "Dagmar"),
    ("456016085",  "Kubcová",       "Anna"),
    ("485627038",  "Poustková",     "Jiřina"),
    ("506109148",  "Holubcová",     "Svatava"),
    ("6008040247", "Šulc",          "Jiří"),
    ("6054574130", "Přibová",       "Darina"),
    ("6102694070", "Elouchefoun",   "Aziz"),
    ("6654251978", "Svozilová",     "Ivana"),
    ("6808292018", "Moudrý",        "Jiří"),
    ("6853222079", "Milatová",      "Martina"),
    ("6909154934", "Novák",         "Petr"),
    ("7056764319", "Michlíková",    "Anna"),
    ("7157734210", "Moudry Molloy", "Joanne"),
    ("7309300449", "Vojáček",       "Aleš"),
    ("7410540709", "Torres blanco", "Jose maria"),
    ("7459303599", "Noháčová",      "Kateřina"),
    ("7651090106", "Matějková",     "Jana"),
    ("7803744597", "Barrell",       "Peter"),
    ("7855080420", "Vondřičková",   "Zuzana"),
    ("7908030427", "Smetana",       "Libor"),
    ("7957312099", "Nimeřická",     "Michaela"),
    ("7961794126", "Tomyshynets",   "Halyna"),
    ("8005291404", "Hanzl",         "František"),
    ("8156013041", "Maršíková",     "Simona"),
    ("8157544241", "Jarošová",      "Zuzana"),
    ("8203120299", "Otčenášek",     "Vojtěch"),
    ("8253215223", "Slavíková",     "Kateřina"),
    ("8301070558", "Kříž",          "Michal"),
    ("8352210438", "Bartáková",     "Jana"),
    ("8412175123", "Mičulka",       "Jan"),
    ("8454664262", "Feoktistová",   "Irina"),
    ("8462150147", "Říhová",        "Markéta"),
    ("8503120417", "Šindelář",      "Tomáš"),
    ("8552170517", "Slabá",         "Gabriela"),
    ("8558150227", "Horáková",      "Lucie"),
    ("8652034380", "Kopová",        "Jana"),
    ("8754280403", "Jindrová",      "Helena"),
    ("8755075153", "Babjáková",     "Jana"),
    ("8910584023", "Pham Van",      "Duy"),
    ("8953010330", "Špatná",        "Markéta"),
    ("8956039037", "Slavíková",     "Zuzana"),
    ("9002025956", "Banáš",         "Martin"),
    ("9010262448", "Bečica",        "Marek"),
    ("9811040305", "Sidej",         "Natan"),
]

# ── INIT ──────────────────────────────────────────────────────────────────────

vzp        = VZPB2BClient(ENV, str(PFX_PATH), PFX_PASSWORD, icz=ICZ, dic=DIC)
mysql      = connect_mysql()
call_count = 0
today      = date.today()

# ── HELPERS ───────────────────────────────────────────────────────────────────

def check_stav(rc: str, check_date: date) -> str:
    global call_count
    if call_count > 0:
        time.sleep(API_DELAY)
    call_count += 1
    print(f"    [{call_count}] {check_date.isoformat()} ...", end=" ", flush=True)
    xml  = vzp.stav_pojisteni(rc=rc, k_datu=check_date.isoformat())
    stav = vzp.parse_stav_pojisteni(xml)["stav"]
    print(f"stav = {stav!r}")
    return stav

def uloz_stav(rc, prijmeni, jmeno, k_datu, stav):
    xml = vzp.stav_pojisteni(rc=rc, k_datu=k_datu.isoformat())
    with mysql.cursor() as cur:
        cur.execute("""
            INSERT INTO vzp_stav_pojisteni (rc, prijmeni, jmeno, k_datu, stav, response_xml)
            VALUES (%s, %s, %s, %s, %s, %s)
            ON DUPLICATE KEY UPDATE stav=VALUES(stav), response_xml=VALUES(response_xml)
        """, (rc, prijmeni, jmeno, k_datu, stav, xml))

def najdi_zlom(rc: str, last_ok_mysql) -> tuple:
    if last_ok_mysql:
        low  = last_ok_mysql
        high = today
        print(f"    MySQL last stav='1': {low}  →  [{low} … {high}]")
    else:
        print("    MySQL: žádný stav='1' — hledám zpětně po rocích ...")
        prev_probe = today
        low = high = None
        for n in range(1, 21):
            y = today.year - n
            try:
                probe = date(y, today.month, today.day)
            except ValueError:
                probe = date(y, today.month, today.day - 1)
            stav = check_stav(rc, probe)
            if stav == "1":
                low  = probe
                high = prev_probe
                print(f"    Nalezeno stav='1' k {low}  →  [{low} … {high}]")
                break
            prev_probe = probe
        if low is None:
            print("    NELZE: stav='1' nenalezen ani 20 let zpět.")
            return None, None

    stav_low  = check_stav(rc, low)
    stav_high = check_stav(rc, high)

    if stav_low != "1":
        print(f"    NELZE: dolní mez {low} má stav='{stav_low}'.")
        return None, None
    if stav_high == "1":
        print(f"    INFO: horní mez {high} má stav='1' — aktuálně pojištěn.")
        return None, None

    print(f"    Binární hledání ({(high - low).days} dní) ...")
    while (high - low).days > 1:
        mid  = low + timedelta(days=(high - low).days // 2)
        stav = check_stav(rc, mid)
        if stav == "1":
            low  = mid
        else:
            high = mid

    return low, high   # insured_to, uninsured_from

# ── RESUME: načti již hotové ──────────────────────────────────────────────────

with mysql.cursor() as cur:
    cur.execute("SELECT rc FROM vzp_stav_pojisteni WHERE k_datu = %s", (K_DATU,))
    hotove = {row[0] for row in cur.fetchall()}

zbyvaji = [(rc, p, j) for rc, p, j in PACIENTI if rc not in hotove]
print(f"Celkem pacientů: {len(PACIENTI)}, již hotovo: {len(hotove)}, zbývá: {len(zbyvaji)}")
print(f"API prodleva: {API_DELAY}s  |  K_DATU: {K_DATU}\n")
print("=" * 60)

# ── HLAVNÍ SMYČKA ─────────────────────────────────────────────────────────────

vysledky = []

for i, (rc, prijmeni, jmeno) in enumerate(zbyvaji, 1):
    print(f"\n[{i}/{len(zbyvaji)}] {prijmeni} {jmeno}  (RC: {rc})")

    # Krok 1: stav k K_DATU
    if call_count > 0:
        time.sleep(API_DELAY)
    call_count += 1
    print(f"    [{call_count}] {K_DATU.isoformat()} ...", end=" ", flush=True)
    xml_hist  = vzp.stav_pojisteni(rc=rc, k_datu=K_DATU.isoformat())
    stav_hist = vzp.parse_stav_pojisteni(xml_hist)["stav"]
    print(f"stav = {stav_hist!r}")

    with mysql.cursor() as cur:
        cur.execute("""
            INSERT INTO vzp_stav_pojisteni (rc, prijmeni, jmeno, k_datu, stav, response_xml)
            VALUES (%s, %s, %s, %s, %s, %s)
            ON DUPLICATE KEY UPDATE stav=VALUES(stav), response_xml=VALUES(response_xml)
        """, (rc, prijmeni, jmeno, K_DATU, stav_hist, xml_hist))

    # Krok 2: zlom (jen pokud stav != '1' a != '4')
    insured_to = uninsured_from = None

    if stav_hist in ("1", "4"):
        print(f"    → pojištěn (stav={stav_hist!r}), zlom se nehledá")
    else:
        # Zkontroluj watchlist
        with mysql.cursor() as cur:
            cur.execute("SELECT insured_to, uninsured_from FROM vzp_sledovani_pojisteni WHERE rc = %s", (rc,))
            existuje = cur.fetchone()

        if existuje:
            insured_to, uninsured_from = existuje
            print(f"    → již ve watchlistu: insured_to={insured_to}, uninsured_from={uninsured_from}")
        else:
            with mysql.cursor() as cur:
                cur.execute(
                    "SELECT MAX(k_datu) FROM vzp_stav_pojisteni WHERE rc = %s AND stav = '1'",
                    (rc,)
                )
                r = cur.fetchone()
            last_ok = r[0] if r and r[0] else None

            insured_to, uninsured_from = najdi_zlom(rc, last_ok)

            with mysql.cursor() as cur:
                cur.execute("""
                    INSERT INTO vzp_sledovani_pojisteni
                        (rc, prijmeni, jmeno, insured_to, uninsured_from,
                         aktualni_stav, prvni_detekce, posledni_kontrola)
                    VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
                    ON DUPLICATE KEY UPDATE
                        insured_to=VALUES(insured_to),
                        uninsured_from=VALUES(uninsured_from),
                        aktualni_stav=VALUES(aktualni_stav),
                        posledni_kontrola=VALUES(posledni_kontrola)
                """, (rc, prijmeni, jmeno, insured_to, uninsured_from,
                      stav_hist, today, today))

    vysledky.append({
        "rc": rc, "prijmeni": prijmeni, "jmeno": jmeno,
        "stav_20250101": stav_hist,
        "insured_to": insured_to,
        "uninsured_from": uninsured_from,
    })

# ── SOUHRN ────────────────────────────────────────────────────────────────────

mysql.close()

print(f"\n{'=' * 60}")
print(f"  SOUHRN  —  {len(vysledky)} zpracovaných pacientů")
print(f"{'=' * 60}")
print(f"  {'Příjmení':<20} {'Jméno':<14} {'Stav':>5}  {'Pojištěn do':<13} {'Nepoj. od'}")
print(f"  {'-'*58}")
for v in vysledky:
    ins = str(v["insured_to"])     if v["insured_to"]     else "-"
    uni = str(v["uninsured_from"]) if v["uninsured_from"] else "-"
    print(f"  {v['prijmeni']:<20} {v['jmeno']:<14} {v['stav_20250101']:>5}  {ins:<13} {uni}")

print(f"\nCelkem VZP dotazů: {call_count}")
