"""KASMBS/MBSAQIP-호환 quality improvement 리포트 생성 (ko/en, md + optional docx).

Inputs are already-computed bundles from eras / procedure / hypo / outpatient
modules. Produces:
  - Markdown KPI report
  - Optional .docx via python-docx (falls back to .md if not installed)

Disclaimer for research / synthetic data is ALWAYS included.
"""
from __future__ import annotations

import os
from typing import Any, Dict, List, Optional

DISCLAIMER_KO = (
    "본 리포트는 합성 데이터 기반 참고용·연구용 KPI 리포트입니다. "
    "임상 의사결정에 직접 사용하지 마십시오. "
    "(For research / synthetic data only — NOT for clinical decision.)"
)
DISCLAIMER_EN = (
    "This report is generated from synthetic data for research / educational use only. "
    "NOT for clinical decision making."
)


def _hdr(title: str, lang: str) -> str:
    today = "auto-generated"
    if lang == "ko":
        return (
            f"# BariERASRecov-Kor — 비만수술 perioperative ERAS recovery 리포트\n\n"
            f"_{title}_  |  _{today}_\n\n"
            f"> {DISCLAIMER_KO}\n\n"
        )
    return (
        f"# BariERASRecov-Kor — Bariatric Perioperative ERAS Recovery Report\n\n"
        f"_{title}_  |  _{today}_\n\n"
        f"> {DISCLAIMER_EN}\n\n"
    )


def _table(rows: List[List[Any]], header: List[str]) -> str:
    out = ["| " + " | ".join(header) + " |",
           "| " + " | ".join(["---"] * len(header)) + " |"]
    for r in rows:
        out.append("| " + " | ".join(str(x) for x in r) + " |")
    return "\n".join(out) + "\n\n"


def build_markdown(*, ingest_report,
                   ward_radar_rows,
                   mbsaqip_rows,
                   procedure_rows,
                   hypo_bucket_rows,
                   hypo_proc_rows,
                   outpt_proc_rows,
                   transition,
                   km_readmit_rows,
                   language: str = "ko") -> str:
    lang = language
    ko = (lang == "ko")
    md = _hdr("KPI 요약" if ko else "KPI Summary", lang)

    # 1. Ingest summary
    md += ("## 1. 데이터 개요\n\n" if ko else "## 1. Data overview\n\n")
    md += (f"- 환자 N: **{ingest_report.n_patients}**\n"
           f"- intraop rows: {ingest_report.n_intraop}, "
           f"POD0-3 rows: {ingest_report.n_pod03}, "
           f"POD4-30 rows: {ingest_report.n_pod430}, "
           f"POD90 outpt rows: {ingest_report.n_pod90}\n"
           f"- hypo events: {ingest_report.n_hypo}\n"
           f"- de-identification: {ingest_report.deid_method}\n\n")

    # 2. ERAS bundle radar
    md += ("## 2. ERAS Society 비만수술 protocol 부합률 (ward radar)\n\n"
           if ko else
           "## 2. ERAS Society bariatric protocol compliance (ward radar)\n\n")
    md += _table(
        [[w.ward, w.n_patients, w.preop_pct, w.intraop_pct,
          w.pod03_pct, w.pod430_pct, w.overall_pct]
         for w in ward_radar_rows],
        ["ward", "N", "preop %", "intraop %", "POD0-3 %", "POD4-30 %", "overall %"],
    )

    # 3. MBSAQIP measures
    md += ("## 3. MBSAQIP / ASMBS quality measure 패널\n\n" if ko else
           "## 3. MBSAQIP / ASMBS quality-measure panel\n\n")
    md += _table(
        [[m.measure, f"{m.rate_pct}%", m.n_events, m.n_denominator,
          f"{m.target_pct}%",
          ("PASS" if m.rate_pct <= m.target_pct else "WATCH")]
         for m in mbsaqip_rows],
        ["measure", "rate", "events", "N", "target", "flag"],
    )

    # 4. Procedure stratification
    md += ("## 4. 5+ 술식별 stratification (RYGB / SG / OAGB / SADI / DJB)\n\n"
           if ko else
           "## 4. Procedure stratification (RYGB / SG / OAGB / SADI / DJB)\n\n")
    md += _table(
        [[p.procedure, p.n, p.mean_age, p.mean_bmi,
          f"{p.pct_t2dm}%", f"{p.leak_rate_pct}%",
          f"{p.marginal_ulcer_pct}%", f"{p.dumping_any_pct}%",
          f"{p.readmit_30d_pct}%", f"{p.mortality_30d_pct}%",
          (p.oe_leak if p.oe_leak is not None else "—"),
          (p.oe_readmit if p.oe_readmit is not None else "—")]
         for p in procedure_rows],
        ["proc", "N", "age", "BMI", "T2DM",
         "leak", "margUlcer", "dumping", "readmit30",
         "mort30", "O/E leak", "O/E readmit"],
    )

    # 5. Hypoglycemia + dumping distribution
    md += ("## 5. post-bariatric hypoglycemia + dumping 시간 분포\n\n" if ko else
           "## 5. Post-bariatric hypoglycemia + dumping time distribution\n\n")
    md += _table(
        [[b.time_bucket, b.hypo_type, b.n_events, b.n_unique_patients,
          b.mean_glucose, f"{b.pct_L2_or_worse}%",
          ("YES" if b.kda_action_recommended else "—")]
         for b in hypo_bucket_rows],
        ["bucket", "type", "events", "uniq pts",
         "mean BG", "L2+%", "KDA action"],
    )
    md += "\n"
    md += _table(
        [[h.procedure, h.n_patients, h.n_immediate_events,
          h.n_delayed_events, h.n_dumping_events,
          f"{h.immediate_rate_pct}%", f"{h.delayed_rate_pct}%",
          f"{h.dumping_rate_pct}%"]
         for h in hypo_proc_rows],
        ["proc", "N", "imm ev", "delayed ev", "dump ev",
         "imm rate", "delayed rate", "dump rate"],
    )

    # 6. POD0-90 outpatient transition
    md += ("## 6. POD0-90 외래 follow-up & 전이\n\n" if ko else
           "## 6. POD0-90 outpatient follow-up & transition\n\n")
    md += _table(
        [[o.key, o.n_total, f"{o.pct_pod7}%", f"{o.pct_pod30}%",
          f"{o.pct_pod60}%", f"{o.pct_pod90}%",
          o.mean_twl_pct,
          (o.mean_hba1c if o.mean_hba1c is not None else "—"),
          f"{o.glp1_added_pct}%", f"{o.reop_trigger_pct}%"]
         for o in outpt_proc_rows],
        ["proc", "N", "POD7", "POD30", "POD60", "POD90",
         "%TWL", "HbA1c", "GLP-1RA", "reop trig"],
    )

    # 7. Transition summary & KM
    md += ("## 7. 30-day readmission / mortality\n\n" if ko else
           "## 7. 30-day readmission / mortality\n\n")
    md += (f"- N total: **{transition.n_total}**\n"
           f"- 30-day readmission: {transition.n_readmit_30d} "
           f"({transition.readmit_rate_pct}%)\n"
           f"- median time to readmit: "
           f"{transition.median_time_to_readmit_d} day(s)\n"
           f"- 30-day mortality: {transition.n_mort_30d} "
           f"({transition.mort_rate_pct}%)\n"
           f"- readmit reason mix: {transition.readmit_reason_mix}\n\n")

    md += ("### Kaplan-Meier (30-day readmission, head)\n\n" if ko else
           "### Kaplan-Meier (30-day readmission, head)\n\n")
    md += _table(
        [[d, s, n] for (d, s, n) in km_readmit_rows[:15]],
        ["day", "S(t)", "n at risk"],
    )

    # 8. KASMBS quality summary (Korean)
    md += ("## 8. KASMBS / KSSO / KOSSO 학술대회 호환 quality summary\n\n"
           if ko else
           "## 8. KASMBS / KSSO / KOSSO-compatible quality summary\n\n")
    md += (("- 본 합성 코호트는 한국 비만수술 5+ 술식 분포(RYGB/SG/OAGB/SADI/DJB)를 "
            "반영합니다.\n"
            "- ERAS Society 비만수술 protocol 부합률·MBSAQIP analog 측정값·KDA 저혈당 가이드 "
            "기반 post-bariatric hypoglycemia surveillance를 한 화면에서 제공합니다.\n"
            "- 본 도구는 임상 의사결정용이 아니며, perioperative QI 회의·KASMBS 학술대회 "
            "초록·외과 PI·ward별 quality dashboard 시연에 활용하십시오.\n\n")
           if ko else
           ("- This synthetic cohort reflects Korean bariatric procedure mix "
            "(RYGB/SG/OAGB/SADI/DJB).\n"
            "- The dashboard combines ERAS Society bariatric pathway compliance, "
            "MBSAQIP-analog measures, and KDA-aligned post-bariatric hypoglycemia "
            "surveillance in a single view.\n"
            "- Not for clinical decision-making. Use for perioperative QI rounds "
            "and KASMBS/KSSO abstract preparation only.\n\n"))

    md += "---\n\n"
    md += DISCLAIMER_KO if ko else DISCLAIMER_EN
    md += "\n"
    return md


def write_markdown(path: str, md: str) -> str:
    os.makedirs(os.path.dirname(path) or ".", exist_ok=True)
    with open(path, "w", encoding="utf-8") as f:
        f.write(md)
    return path


def write_docx(path: str, md: str, title: str = "BariERASRecov-Kor 리포트") -> str:
    """Try python-docx; fall back to .md if not installed."""
    try:
        from docx import Document
        from docx.shared import Pt
    except ImportError:
        fallback = path.rsplit(".", 1)[0] + ".md"
        write_markdown(fallback, md)
        return fallback

    os.makedirs(os.path.dirname(path) or ".", exist_ok=True)
    doc = Document()
    style = doc.styles["Normal"]
    style.font.name = "Malgun Gothic"
    style.font.size = Pt(10)

    for line in md.splitlines():
        if line.startswith("# "):
            doc.add_heading(line[2:].strip(), level=0)
        elif line.startswith("## "):
            doc.add_heading(line[3:].strip(), level=1)
        elif line.startswith("### "):
            doc.add_heading(line[4:].strip(), level=2)
        elif line.startswith("|"):
            # very simple: dump as monospaced paragraph
            doc.add_paragraph(line)
        elif line.startswith("- "):
            doc.add_paragraph(line[2:], style="List Bullet")
        elif line.strip():
            doc.add_paragraph(line)
    doc.save(path)
    return path
