"""
Report posledních receptů — export do Excelu.

Soubor se ukládá do adresáře report/ s verzováním:
    report_predpisy_RRRR-MM-DD.xlsx
    report_predpisy_RRRR-MM-DD_v2.xlsx  (pokud základní existuje)
    atd.

Spuštění:
    python report/report_predpisy_excel.py
"""

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

import pymysql
import pymysql.cursors
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.utils import get_column_letter

if hasattr(sys.stdout, "reconfigure"):
    sys.stdout.reconfigure(errors="replace")

# ── Konfigurace ───────────────────────────────────────────────────────────────
DB = dict(
    host        = "192.168.1.76",
    user        = "root",
    password    = "Vlado9674+",
    database    = "medicus",
    charset     = "utf8mb4",
    cursorclass = pymysql.cursors.DictCursor,
)

LIMIT      = 100
VYSTUP_DIR = Path(__file__).parent   # adresář report/

# ── Barvy (stejné jako prehled_pacienta_excel.py) ────────────────────────────
C_HEADER_BG = "1F4E79"
C_HEADER_FG = "FFFFFF"
C_TITLE_BG  = "2E75B6"
C_TITLE_FG  = "FFFFFF"
C_INFO_BG   = "DEEAF1"
C_ROW_ODD   = "FFFFFF"
C_ROW_EVEN  = "EBF3FB"
C_NEVYZV_BG = "FCE4D6"
C_BORDER    = "B8CCE4"

# ── Pomocné funkce stylování ─────────────────────────────────────────────────
def thin_border():
    s = Side(style="thin", color=C_BORDER)
    return Border(left=s, right=s, top=s, bottom=s)

def fill(color):
    return PatternFill("solid", fgColor=color)

def zapis_nadpis_sekce(ws, row, text, n_cols):
    ws.merge_cells(start_row=row, start_column=1, end_row=row, end_column=n_cols)
    cell = ws.cell(row=row, column=1, value=text)
    cell.font      = Font(name="Arial", bold=True, size=11, color=C_TITLE_FG)
    cell.fill      = fill(C_TITLE_BG)
    cell.alignment = Alignment(horizontal="left", vertical="center", indent=1)
    ws.row_dimensions[row].height = 22
    return row + 1

def zapis_hlavicku(ws, row, hlavicka):
    for col, text in enumerate(hlavicka, 1):
        cell = ws.cell(row=row, column=col, value=text)
        cell.font      = Font(name="Arial", bold=True, size=10, color=C_HEADER_FG)
        cell.fill      = fill(C_HEADER_BG)
        cell.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)
        cell.border    = thin_border()
    ws.row_dimensions[row].height = 28
    return row + 1

def zapis_radek(ws, row, hodnoty, highlight=False):
    bg = C_NEVYZV_BG if highlight else (C_ROW_EVEN if row % 2 == 0 else C_ROW_ODD)
    f  = fill(bg)
    for col, val in enumerate(hodnoty, 1):
        cell = ws.cell(row=row, column=col, value=val)
        cell.font      = Font(name="Arial", size=10)
        cell.fill      = f
        cell.alignment = Alignment(vertical="center", wrap_text=True)
        cell.border    = thin_border()
    ws.row_dimensions[row].height = 18
    return row + 1

def autofit(ws, min_w=5, max_w=60, pad=2):
    col_widths = {}
    for row in ws.iter_rows():
        for cell in row:
            if cell.value is None:
                continue
            factor = 1.15 if (cell.font and cell.font.bold) else 1.0
            w = len(str(cell.value)) * factor + pad
            c = get_column_letter(cell.column)
            col_widths[c] = max(col_widths.get(c, min_w), w)
    for c, w in col_widths.items():
        ws.column_dimensions[c].width = min(max(w, min_w), max_w)

# ── Data ──────────────────────────────────────────────────────────────────────
def nacti_odbornosti(conn):
    with conn.cursor() as cur:
        cur.execute("""
            SELECT vp.icp, o.nazev
            FROM vzp_pracoviste vp
            JOIN odbornost o ON o.kod = vp.odbornost
            WHERE CURDATE() BETWEEN vp.platnost_od AND vp.platnost_do
            ORDER BY vp.platnost_od DESC
        """)
        result = {}
        for row in cur.fetchall():
            result.setdefault(row["icp"], row["nazev"])
        return result

def odbornost_z_icp(icp, slovnik):
    if not icp or len(icp) < 3:
        return ""
    return slovnik.get(icp, f"odb. {icp[-3:]}")

def nacti_predpisy(conn, limit):
    with conn.cursor() as cur:
        cur.execute("""
            SELECT
                p.datum_vystaveni,
                z.pacient_prijmeni,
                z.pacient_jmena,
                z.pacient_datum_narozeni,
                COALESCE(v.nazev, p.nazev)  AS vydany_lek,
                v.nazev IS NULL             AS nevyzvednuto,
                p.atc,
                p.navod,
                pr.prijmeni                 AS lekar_prijmeni,
                pr.jmena                    AS lekar_jmena,
                pr.icp,
                pr.pzs_nazev,
                pr.ulice,
                pr.psc,
                pr.mesto,
                rd.stav,
                rd.druh_pojisteni
            FROM predpis p
            JOIN zprava z           ON z.id               = p.zprava_id
            JOIN predepisujici pr   ON pr.lekar_kod        = p.kod_predepisujiciho
            LEFT JOIN vydej v       ON v.id_lp_predpis     = p.id_lp_predpis
            LEFT JOIN recept_plp rp ON rp.id_lp            = p.id_lp_predpis
            LEFT JOIN recept_doklad rd ON rd.id_dokladu    = rp.id_dokladu
            ORDER BY p.datum_vystaveni DESC, p.id DESC
            LIMIT %s
        """, (limit,))
        return cur.fetchall()

# ── Verzování souboru ─────────────────────────────────────────────────────────
def versioned_path(dir_: Path, dnes: str) -> Path:
    zaklad = dir_ / f"report_predpisy_{dnes}.xlsx"
    if not zaklad.exists():
        return zaklad
    v = 2
    while True:
        p = dir_ / f"report_predpisy_{dnes}_v{v}.xlsx"
        if not p.exists():
            return p
        v += 1

# ── Sestavení sešitu ──────────────────────────────────────────────────────────
def vytvor_excel(rows, odbornosti, dnes):
    wb = Workbook()
    ws = wb.active
    ws.title = "Predpisy"

    N = 8   # počet sloupců

    # ── Záhlaví ───────────────────────────────────────────────────────────────
    ws.merge_cells(start_row=1, start_column=1, end_row=1, end_column=N)
    title = ws.cell(row=1, column=1,
                    value=f"PŘEHLED RECEPTŮ — posledních {LIMIT}")
    title.font      = Font(name="Arial", bold=True, size=14, color=C_HEADER_FG)
    title.fill      = fill(C_HEADER_BG)
    title.alignment = Alignment(horizontal="left", vertical="center", indent=1)
    ws.row_dimensions[1].height = 32

    info_radky = [
        ("Datum tisku:",      datetime.today().strftime("%d.%m.%Y")),
        ("Počet záznamů:",    str(len(rows))),
        ("Nejstarší datum:",  str(rows[-1]["datum_vystaveni"]) if rows else ""),
        ("Nejnovější datum:", str(rows[0]["datum_vystaveni"])  if rows else ""),
    ]
    for i, (label, val) in enumerate(info_radky, 2):
        ws.merge_cells(start_row=i, start_column=1, end_row=i, end_column=2)
        ws.merge_cells(start_row=i, start_column=3, end_row=i, end_column=N)
        lbl = ws.cell(row=i, column=1, value=label)
        lbl.font      = Font(name="Arial", bold=True, size=10)
        lbl.fill      = fill(C_INFO_BG)
        lbl.alignment = Alignment(vertical="center", indent=1)
        v = ws.cell(row=i, column=3, value=val)
        v.font      = Font(name="Arial", size=10)
        v.fill      = fill(C_INFO_BG)
        v.alignment = Alignment(vertical="center")
        ws.row_dimensions[i].height = 16

    row = len(info_radky) + 3   # prázdný řádek

    # ── Tabulka ───────────────────────────────────────────────────────────────
    row = zapis_nadpis_sekce(ws, row, f"RECEPTY  (celkem {len(rows)})", N)
    row = zapis_hlavicku(ws, row, [
        "#", "Datum", "Pacient", "Vydaný lék / ATC", "Návod",
        "Lékař", "Odbornost", "Pracoviště a adresa",
    ])

    for i, r in enumerate(rows, 1):
        nevyzv  = bool(r["nevyzvednuto"])
        pacient = f"{r['pacient_prijmeni']} {r['pacient_jmena']}".strip()
        lekar   = f"{r['lekar_prijmeni']} {r['lekar_jmena']}".strip()
        odb     = odbornost_z_icp(r["icp"], odbornosti)
        adresa  = ", ".join(filter(None, [
            r.get("pzs_nazev") or "",
            r.get("ulice") or "",
            f"{r.get('psc') or ''} {r.get('mesto') or ''}".strip(),
        ]))
        lek_atc = r["vydany_lek"] or ""
        if r.get("atc"):
            lek_atc += f"\n{r['atc']}"
        stav_text = ""
        if nevyzv:
            stav_text = " *NV"
        elif r.get("stav") == "ZRUSENY":
            stav_text = " *ZR"

        datum_str = (r["datum_vystaveni"].strftime("%d.%m.%Y")
                     if r["datum_vystaveni"] else "")

        row = zapis_radek(ws, row, [
            i,
            datum_str,
            pacient,
            lek_atc + stav_text,
            r.get("navod") or "",
            lekar,
            odb,
            adresa,
        ], highlight=nevyzv)

    # ── Dokončení ─────────────────────────────────────────────────────────────
    autofit(ws)
    ws.freeze_panes = "A7"   # zmraz záhlaví + info řádky

    return wb


def main():
    conn = pymysql.connect(**DB)
    print("Nacitam odbornosti...")
    odbornosti = nacti_odbornosti(conn)
    print(f"Nacitam poslednich {LIMIT} receptu...")
    rows = nacti_predpisy(conn, LIMIT)
    conn.close()
    print(f"  Nacteno: {len(rows)} zaznamu")

    dnes   = date.today().isoformat()
    wb     = vytvor_excel(rows, odbornosti, dnes)
    soubor = versioned_path(VYSTUP_DIR, dnes)
    wb.save(soubor)
    print(f"Ulozeno: {soubor}")


if __name__ == "__main__":
    main()
