#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Najde přesný den zlomu pojištění pro konkrétního pacienta.

Algoritmus:
  1. Z MySQL vezme MAX(k_datu) WHERE stav='1' pro daného pacienta.
     Pokud neexistuje, prochází zpět po 1 roce a hledá první stav='1'.
  2. Binárním hledáním najde přesný den:
       low  = poslední den kdy byl stav='1'
       high = první den kdy byl stav!='1'
"""

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       = "500208129"
PRIJMENI = "Zuzák"
JMENO    = "Viktor"

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

API_DELAY = 2  # sekundy mezi dotazy na VZP

# ── INIT VZP ──────────────────────────────────────────────────────────────────

if not PFX_PATH.exists():
    print(f"CHYBA: PFX certifikat nenalezen: {PFX_PATH}")
    sys.exit(1)

vzp = VZPB2BClient(ENV, str(PFX_PATH), PFX_PASSWORD, icz=ICZ, dic=DIC)

call_count = 0

def check_stav(rc: str, check_date: date) -> str | None:
    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

# ── KROK 1: DOLNÍ MEZ ─────────────────────────────────────────────────────────

print(f"\nHledám zlom pojištění pro {PRIJMENI} {JMENO}  (RC: {RC})\n")
print("── Krok 1: dolní mez ──────────────────────────────────────────────────")

mysql = connect_mysql()
with mysql.cursor() as cur:
    cur.execute(
        "SELECT MAX(k_datu) FROM vzp_stav_pojisteni WHERE rc = %s AND stav = '1'",
        (RC,)
    )
    row = cur.fetchone()
mysql.close()

today     = date.today()
last_ok   = row[0] if row and row[0] else None

if last_ok:
    low  = last_ok
    high = today
    print(f"   MySQL: poslední stav='1' k datu {low}")
    print(f"   → binary search  [{low}  …  {high}]")
else:
    print("   MySQL: žádný záznam se stavem='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"\n   Nalezeno stav='1' k {low}")
            print(f"   → binary search  [{low}  …  {high}]")
            break

        prev_probe = probe

    if low is None:
        print("CHYBA: Stav='1' nenalezen ani 20 let zpatky. Nelze urcit zlom.")
        sys.exit(1)

# ── KROK 2: OVĚŘENÍ HRANIC ────────────────────────────────────────────────────

print("\n── Krok 2: ověření hranic ─────────────────────────────────────────────")

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

if stav_low != "1":
    print(f"CHYBA: Dolni mez {low} ma stav='{stav_low}' (ocekavam '1'). Nelze pokracovat.")
    sys.exit(1)

if stav_high == "1":
    print(f"INFO: Horni mez {high} ma stav='1' — pacient je aktualne pojisten, zadny zlom nenalezen.")
    sys.exit(0)

print(f"   OK {low} -> '{stav_low}'  |  {high} -> '{stav_high}'  — rozsah v poradku")

# ── KROK 3: BINÁRNÍ HLEDÁNÍ ───────────────────────────────────────────────────

print(f"\n── Krok 3: binární hledání  ({(high - low).days} dní v rozsahu) ─────────")

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

# ── VÝSLEDEK ──────────────────────────────────────────────────────────────────

print(f"\n{'=' * 55}")
print(f"  VYSLEDEK  -  {PRIJMENI} {JMENO}  (RC: {RC})")
print(f"{'=' * 55}")
print(f"  Posledni den POJISTEN :  {low}")
print(f"  Prvni den BEZ pojisteni: {high}")
print(f"  Celkem VZP dotazu       : {call_count}")
print(f"{'=' * 55}\n")
