#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
zkontroluj_rc_jednorazove.py
=============================
Jednorázový skript pro libovolné RC:
  1. Dotáže VZP na stav pojištění k zadanému K_DATU.
  2. Uloží do vzp_stav_pojisteni.
  3. Pokud stav != '1' a != '4', spustí binární hledání zlomu
     a uloží do vzp_sledovani_pojisteni.
"""

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 ───────────────────────────────────────────────────────────────

RC       = "430127082"
PRIJMENI = "Anderle"
JMENO    = "Václav"
K_DATU   = date(2025, 1, 1)     # datum pro první dotaz

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

API_DELAY = 2

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

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

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}] VZP dotaz k {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):
    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, last_ok_mysql):
    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' — pacient je aktuálně pojištěn, žádný zlom.")
        return None, None

    print(f"  Binární hledání v rozsahu {(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

# ── KROK 1: Dotaz k zadanému datu ─────────────────────────────────────────────

print(f"\n{PRIJMENI} {JMENO}  (RC: {RC})")
print(f"── Krok 1: stav pojištění k {K_DATU} ─────────────────────────────────")

xml_hist  = vzp.stav_pojisteni(rc=RC, k_datu=K_DATU.isoformat())
stav_hist = vzp.parse_stav_pojisteni(xml_hist)["stav"]
call_count += 1
print(f"  stav k {K_DATU}: {stav_hist!r}")

uloz_stav(RC, PRIJMENI, JMENO, K_DATU, stav_hist, xml_hist)
print(f"  Uloženo do vzp_stav_pojisteni (k_datu={K_DATU})")

# ── KROK 2: Pokud není pojištěn, najdi zlom ───────────────────────────────────

if stav_hist in ("1", "4"):
    print(f"\nStav '{stav_hist}' = pojištěn (nebo cizinec), zlom se nehledá.")
else:
    print(f"\nStav '{stav_hist}' = nepojištěn/nenalezen")
    print(f"── Krok 2: hledám zlom pojištění ─────────────────────────────────────")

    # Zkontroluj, zda je pacient již ve watchlistu
    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:
        print(f"  Pacient již ve watchlistu: insured_to={existuje[0]}, uninsured_from={existuje[1]}")
        print(f"  Přeskakuji hledání zlomu.")
    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))

        print(f"\n{'=' * 50}")
        print(f"  VÝSLEDEK  —  {PRIJMENI} {JMENO}  (RC: {RC})")
        print(f"{'=' * 50}")
        print(f"  Stav k {K_DATU}          : {stav_hist!r}")
        print(f"  Poslední den pojištěn    : {insured_to or 'nezjištěno'}")
        print(f"  První den bez pojištění  : {uninsured_from or 'nezjištěno'}")
        print(f"  Celkem VZP dotazů        : {call_count}")
        print(f"{'=' * 50}\n")

mysql.close()
print(f"Hotovo. Celkem VZP dotazů: {call_count}")
