import os
import time
import fdb
import openpyxl
import xlwings as xw
from datetime import datetime, date
from openpyxl.utils import get_column_letter
from openpyxl.styles import Font, PatternFill, Alignment

# --- Konfigurace ---
PathToSaveCSV = r"u:\Dropbox\!!!Days\Downloads Z230"
timestr = time.strftime("%Y-%m-%d_%H-%M-%S_")
output_path = os.path.join(PathToSaveCSV, timestr + "Pacienti.xlsx")

# --- Smazání předchozích verzí ---
for fname in os.listdir(PathToSaveCSV):
    if fname.endswith("Pacienti.xlsx"):
        try:
            os.remove(os.path.join(PathToSaveCSV, fname))
        except Exception as e:
            print(f"Nelze smazat {fname}: {e}")

# --- Připojení k DB ---
con = fdb.connect(
    host='localhost', database=r'c:\MEDICUS 3\data\medicus.FDB',
    user='sysdba', password='masterkey', charset='WIN1250'
)
cur = con.cursor()

wb = openpyxl.Workbook()

# =====================
# Pomocné funkce
# =====================

# Styly pro posudky
HEADER_FILL = PatternFill('solid', fgColor='2F5496')
HEADER_FONT = Font(bold=True, color='FFFFFF')
ZEBRA_FILL  = PatternFill('solid', fgColor='DCE6F1')
GREEN_FILL  = PatternFill('solid', fgColor='C6EFCE')
GREEN_FONT  = Font(bold=True, color='276221')

def style_header(ws):
    for cell in ws[1]:
        cell.fill = HEADER_FILL
        cell.font = HEADER_FONT
        cell.alignment = Alignment(horizontal='center')

def autofit_ws(ws):
    for col in ws.columns:
        max_len = max((len(str(cell.value)) if cell.value is not None else 0) for cell in col)
        ws.column_dimensions[get_column_letter(col[0].column)].width = min(max_len + 2, 50)

def sanitize(val):
    """Nahradí znaky neplatné pro Excel: µ → u, ostatní → _"""
    if not isinstance(val, str):
        return val
    result = []
    for ch in val:
        if ch == 'µ':
            result.append('u')
        elif ord(ch) < 32 and ch not in '\t\n\r':
            result.append('_')
        elif ord(ch) in (0xFFFE, 0xFFFF) or 0xD800 <= ord(ch) <= 0xDFFF:
            result.append('_')
        else:
            result.append(ch)
    return ''.join(result)

def fmt(val):
    return '' if val is None else sanitize(val)

def parse_data(data_str):
    """Parsuje key=value text z HISTDOC.DATA do slovníku."""
    result = {}
    if not data_str:
        return result
    for line in data_str.splitlines():
        if '=' in line:
            key, _, val = line.partition('=')
            result[key.strip()] = val.strip()
    return result

def parse_date(val):
    """Převede 'D:DD.MM.YYYY' na datetime.date."""
    if val and val.startswith('D:'):
        try:
            return datetime.strptime(val[2:], '%d.%m.%Y').date()
        except ValueError:
            return val
    return val

VYKONY_CONDITION = """
    (datose >= vykony.platiod AND datose <= vykony.platido)
    OR (datose >= vykony.platiod AND vykony.platido IS NULL)
"""
VYKONY_HEADERS = ["Rodne cislo", "Jmeno", "Datum vykonu", "Kod", "Název", "Dg.", "Body"]

def add_vykony_sheet(sheet_name, kody):
    """Přidá list s výkony filtrovanými podle seznamu kódů."""
    kod_list = ", ".join(str(k) for k in kody)
    cur.execute(f"""
        SELECT dokladd.rodcis,
               TRIM(prijmeni) || ', ' || TRIM(jmeno),
               dokladd.datose, dokladd.kod, vykony.naz, dokladd.ddgn, dokladd.body
        FROM dokladd
        LEFT JOIN kar ON dokladd.rodcis = kar.rodcis
        JOIN vykony ON dokladd.kod = vykony.kod
        WHERE ({VYKONY_CONDITION})
          AND dokladd.kod IN ({kod_list})
        ORDER BY datose DESC, dokladd.rodcis, dokladd.kod
    """)
    rows = cur.fetchall()
    print(f"{sheet_name}: {len(rows)}")
    ws = wb.create_sheet(sheet_name)
    ws.append(VYKONY_HEADERS)
    for row in rows:
        ws.append(list(row))

# =====================
# List: Registrovaní
# =====================
cur.execute("""
    SELECT rodcis, prijmeni, jmeno, datum_registrace, registr.idpac, poj
    FROM registr
    JOIN kar ON registr.idpac = kar.idpac
    WHERE kar.vyrazen != 'A'
      AND kar.rodcis IS NOT NULL
      AND idicp != 0
      AND datum_zruseni IS NULL
""")
rows = cur.fetchall()
print(f"Registrovaní: {len(rows)}")
ws = wb.active
ws.title = 'Registrovani'
ws.append(["Rodne cislo", "Prijmeni", "Jmeno", "Datum registrace", "ID pacienta", "Pojistovna"])
for row in rows:
    ws.append(list(row))

# =====================
# List: Očkování
# =====================
cur.execute("""
    SELECT rodcis, prijmeni, jmeno, ockzaz.datum, kodmz, ockzaz.poznamka, latka, nazev, expire
    FROM registr
    JOIN kar ON registr.idpac = kar.idpac
    JOIN ockzaz ON registr.idpac = ockzaz.idpac
    WHERE datum_zruseni IS NULL
      AND kar.vyrazen != 'A'
      AND kar.rodcis IS NOT NULL
      AND idicp != 0
    ORDER BY ockzaz.datum DESC
""")
rows = cur.fetchall()
print(f"Očkování: {len(rows)}")
ws = wb.create_sheet("Očkování")
ws.append(["Rodne cislo", "Prijmeni", "Jmeno", "Datum ockovani", "Kod MZ", "Sarze", "Latka", "Nazev", "Expirace"])
for row in rows:
    ws.append(list(row))

# =====================
# List: Recepty
# =====================
cur.execute("""
    SELECT kar.rodcis,
           TRIM(kar.prijmeni) || ' ' || SUBSTRING(kar.jmeno FROM 1 FOR 1) || '.' AS jmeno,
           recept.datum,
           TRIM(recept.lek) || ' ' || TRIM(recept.dop) AS lek,
           recept.expori AS Poc,
           CASE WHEN recept.opakovani IS NULL THEN 1 ELSE recept.opakovani END AS OP,
           recept.uhrada,
           recept.dsig,
           recept.NOTIFIKACE_KONTAKT AS notifikace,
           recept_epodani.erp,
           recept_epodani.vystavitel_jmeno,
           recept.atc,
           recept.CENAPOJ,
           recept.cenapac
    FROM recept
    LEFT JOIN RECEPT_EPODANI ON recept.id_epodani = recept_epodani.id
    LEFT JOIN kar ON recept.idpac = kar.idpac
    ORDER BY datum DESC, erp DESC
""")
rows = cur.fetchall()
print(f"Recepty: {len(rows)}")
ws = wb.create_sheet("Recepty")
ws.append(["Rodné číslo", "Jméno", "Datum vystavení", "Název leku", "Poč.", "Op.", "Úhr.",
           "Da signa", "Notifikace", "eRECEPT", "Vystavil", "ATC", "Cena pojišťovna", "Cena pacient"])
for row in rows:
    ws.append([sanitize(v) if isinstance(v, str) else v for v in row])

# =====================
# List: Výkony všechny
# =====================
cur.execute(f"""
    SELECT dokladd.rodcis,
           TRIM(prijmeni) || ', ' || TRIM(jmeno),
           dokladd.datose, dokladd.kod, dokladd.pocvyk, dokladd.ddgn, dokladd.body, vykony.naz
    FROM kar
    JOIN dokladd ON kar.rodcis = dokladd.rodcis
    JOIN vykony ON dokladd.kod = vykony.kod
    WHERE {VYKONY_CONDITION}
    ORDER BY dokladd.datose DESC, dokladd.rodcis
""")
rows = cur.fetchall()
print(f"Výkony: {len(rows)}")
ws = wb.create_sheet("Vykony")
ws.append(["Rodne cislo", "Jmeno", "Datum vykonu", "Kod", "Pocet", "Dg.", "Body", "Nazev"])
for row in rows:
    ws.append(list(row))

# =====================
# Listy: Neschopenky
# =====================
def pocet_dni(zacnes, konnes, pracne):
    dnes = date.today()
    if pracne == 'A':
        return (dnes - zacnes).days if zacnes else "NA"
    if pracne == 'N' and zacnes and konnes and zacnes <= konnes:
        return (konnes - zacnes).days
    return "NA"

def nes_row(r):
    return (r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7],
            pocet_dni(r[5], r[7], r[6]), r[8], r[9], r[10])

NES_HEADERS = ["ID pac", "Rodne cislo", "Jmeno", "Datum neschopenky", "Číslo neschopenky",
               "Zacatek", "Aktivní?", "Konec", "Pocet dni", "Diagnoza zacatel", "Diagnoza konec", "Aktualizovano"]

cur.execute("""
    SELECT nes.idpac, kar.rodcis,
           TRIM(prijmeni) || ', ' || TRIM(jmeno),
           nes.datnes, nes.ecn, nes.zacnes, nes.pracne, nes.konnes,
           nes.diagno, nes.kondia, nes.updated
    FROM nes
    LEFT JOIN kar ON nes.idpac = kar.idpac
    WHERE nes.datnes <= CURRENT_DATE
    ORDER BY datnes DESC
""")
vse = cur.fetchall()
aktivni = [r for r in vse if r[6] == 'A']
print(f"Neschopenky: {len(vse)} celkem, {len(aktivni)} aktivních")

ws = wb.create_sheet("Neschopenky všechny")
ws.append(NES_HEADERS)
for r in vse:
    ws.append(list(nes_row(r)))

ws = wb.create_sheet("Neschopenky aktivní")
ws.append(NES_HEADERS)
for r in aktivni:
    ws.append(list(nes_row(r)))

# =====================
# Výkonové listy – jednotlivé typy výkonů
# =====================
add_vykony_sheet('Preventivni prohlidky', [1022, 1021])
add_vykony_sheet('INR',       [1443])
add_vykony_sheet('CRP',       [2230, 9111])
add_vykony_sheet('Holter',    [17129])
add_vykony_sheet('Prostata',  [1130, 1131, 1132, 1133, 1134])
add_vykony_sheet('TOKS',      [15118, 15119, 15120, 15121])
add_vykony_sheet('COVID',     [1306])
add_vykony_sheet('Streptest', [2220])

# =====================
# List: Posudky řidičák – MOTORVO (ruční)
# =====================
cur.execute("SELECT IDPACI, DATUM FROM HISTDOC WHERE TYP = 'EPOSMRO'")
eposmro_keys = set((r[0], r[1]) for r in cur.fetchall())

cur.execute("""
    SELECT h.ID, h.DATUM, h.IDPACI,
           k.PRIJMENI, k.JMENO, k.RODCIS,
           h.DATA, h.PORCISLO, h.STAV, h.PRINTED, h.IDUZIV, h.CREATED
    FROM HISTDOC h
    JOIN KAR k ON k.IDPAC = h.IDPACI
    WHERE h.TYP = 'MOTORVO'
    ORDER BY h.ID DESC
""")
motorvo_rows = cur.fetchall()
print(f"MOTORVO: {len(motorvo_rows)}")

motorvo_headers = [
    'ID', 'DATUM', 'IDPACI', 'PRIJMENI', 'JMENO', 'RODCIS',
    'PorCislo', 'DatumVyd', 'DatKonec', 'DruhProh',
    'Posouzeni', 'ZpusobPodminka', 'SkupinaPodminka', 'Skupiny',
    'ePosudek', 'STAV', 'PRINTED', 'IDUZIV', 'CREATED'
]
ws = wb.create_sheet("Posudky řidičák")
ws.append(motorvo_headers)

epos_col_idx = motorvo_headers.index('ePosudek') + 1

for i, row in enumerate(motorvo_rows, start=2):
    (hid, datum, idpac, prijmeni, jmeno, rodcis,
     data_blob, porcislo, stav, printed, iduziv, created) = row
    data = parse_data(data_blob)

    if data.get('Posouzeni2') == 'T':
        posouzeni = 'nezpůsobilý'
    elif data.get('ZpusobPodminka') == 'B:1':
        posouzeni = 'způsobilý s podmínkou'
    elif data.get('Posouzeni') == 'T':
        posouzeni = 'způsobilý'
    else:
        posouzeni = ''

    ws.append([
        hid, fmt(datum), idpac, fmt(prijmeni), fmt(jmeno), fmt(rodcis),
        fmt(porcislo or data.get('PorCislo', '')),
        parse_date(data.get('DatumVyd', '')),
        parse_date(data.get('DatKonec', '')),
        fmt(data.get('DruhProh', '')),
        posouzeni,
        fmt(data.get('ZpusobPodminka', '')),
        fmt(data.get('SkupinaPodminka', '')),
        fmt(data.get('ZpusobJe', '')),
        'ANO' if (idpac, datum) in eposmro_keys else 'NE',
        fmt(stav), fmt(printed), fmt(iduziv), fmt(created),
    ])

    if i % 2 == 0:
        for cell in ws[i]:
            cell.fill = ZEBRA_FILL
    cell = ws.cell(row=i, column=epos_col_idx)
    if cell.value == 'ANO':
        cell.fill = GREEN_FILL
        cell.font = GREEN_FONT

style_header(ws)
ws.freeze_panes = 'A2'
autofit_ws(ws)

# =====================
# List: Posudky řidičák – EPOSMRO (elektronická podání)
# =====================
cur.execute("""
    SELECT h.ID, h.DATUM, h.IDPACI,
           k.PRIJMENI, k.JMENO, k.RODCIS,
           h.DATA, h.STAV, h.CREATED,
           e.ID_PODANI, e.ODESLANO, e.STATUS
    FROM HISTDOC h
    JOIN KAR k ON k.IDPAC = h.IDPACI
    LEFT JOIN HISTDOC_EPOSUDEK e ON e.ID_HISTDOC = h.ID
    WHERE h.TYP = 'EPOSMRO'
    ORDER BY h.ID DESC
""")
epos_rows = cur.fetchall()
print(f"EPOSMRO: {len(epos_rows)}")

ws = wb.create_sheet("ePosudky registr")
ws.append([
    'ID', 'DATUM', 'IDPACI', 'PRIJMENI', 'JMENO', 'RODCIS',
    'DatumVyd', 'DatKonec', 'DruhProhlidky', 'DruhPosudku',
    'Vysledek', 'StavPosudku', 'TypAkce',
    'STAV', 'CREATED', 'ID_PODANI', 'ODESLANO', 'STATUS_ODESL'
])

for i, row in enumerate(epos_rows, start=2):
    (hid, datum, idpac, prijmeni, jmeno, rodcis,
     data_blob, stav, created, id_podani, odeslano, status_odesl) = row
    data = parse_data(data_blob)

    ws.append([
        hid, fmt(datum), idpac, fmt(prijmeni), fmt(jmeno), fmt(rodcis),
        parse_date(data.get('DatumVystaveni', '')),
        parse_date(data.get('PlatnostDo', '')),
        fmt(data.get('DruhProhlidkyNazev', '')),
        fmt(data.get('DruhPosudkuNazev', '')),
        fmt(data.get('VysledekNazev', '')),
        fmt(data.get('StavPosudkuNazev', '')),
        fmt(data.get('TypAkceNazev', '')),
        fmt(stav), fmt(created), fmt(id_podani), fmt(odeslano), fmt(status_odesl),
    ])

    if i % 2 == 0:
        for cell in ws[i]:
            cell.fill = ZEBRA_FILL

style_header(ws)
ws.freeze_panes = 'A2'
autofit_ws(ws)

# =====================
# Autofilter na všech listech
# =====================
for ws in wb.worksheets:
    ws.auto_filter.ref = f"A1:{get_column_letter(ws.max_column)}{ws.max_row}"

# =====================
# Uložení
# =====================
con.close()
wb.save(output_path)
print(f"Uloženo: {output_path}")

# =====================
# xlwings: autofit + centrování Recepty
# =====================
with xw.App(visible=False) as app:
    wb_xw = xw.Book(output_path)
    for sheet in wb_xw.sheets:
        sheet.autofit()
    for sloupec in ["C:C", "E:E", "F:F", "G:G", "I:I", "M:M", "N:N"]:
        wb_xw.sheets['Recepty'].range(sloupec).api.HorizontalAlignment = 3
    wb_xw.save()
    wb_xw.close()

print("Hotovo.")
