#!/usr/bin/env python3
"""
main.py — MASLDNITSchedule-Kor CLI

MASLD/MASH 종단 관찰연구 NIT 측정 스케줄 설계 계산기 (오프라인 CLI).

사용법:
  python3 main.py --demo            예제 스케줄로 MDC·tradeoff·비용 전체 출력
  python3 main.py --help            도움말
  python3 main.py --nit VCTE_LSM --followups 2 --interval 12 --subjects 120
                                    개별 NIT 설계 리포트 출력
  python3 main.py --report VCTE_LSM 프로토콜 측정계획 섹션 리포트만 출력

면책: 참고용·연구용 도구. 실제 연구 설계는 생물통계학자 검토 필수.
NIT 변동성 값은 문헌 기반 추정치.
"""

import argparse
import sys

try:
    import core
except ImportError as e:
    print(f"core 모듈 로드 실패: {e}", file=sys.stderr)
    sys.exit(1)


def _print_header(title):
    print()
    print("#" * 72)
    print(f"# {title}")
    print("#" * 72)


def cmd_demo(args):
    """예제 스케줄로 MDC, tradeoff, 결측 시뮬, 비용효율 frontier 전체 출력."""
    lib = core.load_nit_library()

    _print_header("MASLDNITSchedule-Kor — 데모 실행")
    print(core.DISCLAIMER)
    print()
    print("예제 시나리오: MASH 의심 T2DM 코호트 120명, baseline + 추적 2회(12개월 간격),")
    print("              총 24개월 추적, visit window +-4주, 가정 결측률 15%.")

    n_subjects = 120
    n_followups = 2
    interval = 12
    sched = core.build_schedule(0, n_followups, interval)
    visit_months = sched["visit_months"]
    print(f"\nvisit 스케줄: {', '.join(f'{m:.0f}개월' for m in visit_months)} "
          f"(총 {sched['total_months']:.0f}개월, {sched['n_visits']}회)")

    # --- 기능 2: NIT별 MDC 표 ---
    _print_header("[기능 2] NIT별 최소검출변화(MDC) — 반복측정 1/2/3회")
    for key in core.list_nits(lib):
        tbl = core.mdc_table_for_nit(lib, key, repeats=(1, 2, 3))
        cells = "  ".join(f"n={r['n_repeat']}:{r['mdc']:.3f}" for r in tbl["rows"])
        print(f"  {tbl['label']:<26} ({tbl['unit']:<7}) SEM={tbl['sem']:.3f}  MDC[{cells}]")

    # --- 기능 3: tradeoff ---
    _print_header("[기능 3] 연구기간 vs 자연 진행률 tradeoff (subgroup=T2DM_or_MASH)")
    for key in core.list_nits(lib):
        nit = core.get_nit(lib, key)
        sg = "T2DM_or_MASH" if "T2DM_or_MASH" in nit["progression"].get("subgroups", {}) else None
        tc = core.tradeoff_curve(lib, key, subgroup=sg, n_repeat=1,
                                 max_months=120, step_months=12)
        ttm = tc["time_to_mdc_months"]
        ttm_str = "산출불가(진행률 0)" if ttm == float("inf") else f"약 {ttm:.1f}개월"
        det = tc["detectable_from_month"]
        det_str = f"{det}개월부터 검출가능" if det is not None else "120개월 내 검출 불가"
        print(f"  {nit['label']:<26} 진행률={tc['progression_per_year']:+.3f} {tc['unit']}/년"
              f"  MDC도달={ttm_str}  ({det_str})")

    # --- 기능 4: visit window 최적화 + 결측 시뮬 ---
    _print_header("[기능 4] visit window 최적화 + 결측 영향 (VCTE_LSM 예시)")
    nit = core.get_nit(lib, "VCTE_LSM")
    sem, unit, base = core.resolve_sem(nit)
    slope = nit["progression"]["subgroups"]["T2DM_or_MASH"]
    opt = core.optimize_visit_window(visit_months, n_subjects, sem, slope,
                                     window_candidates=(2, 4, 8, 12),
                                     missing_rate=0.15, n_sim=300)
    print("  (집단 검정력은 표본이 크면 포화 → 스케줄 비교는 '피험자 변화검출률' 사용)")
    for r in opt["results"]:
        print(f"  window +-{r['window_weeks']:>2}주:  변화검출률 {r['detect_rate']*100:5.1f}%"
              f"  (손실 {r['detect_rate_loss']*100:4.1f}%p, "
              f"엔드포인트완전성 {r['endpoint_completeness']*100:.1f}%, "
              f"집단검정력 {r['power']*100:.1f}%)")
    print(f"  => 권장 visit window: +-{opt['recommended_window_weeks']}주 "
          f"(변화검출률 {opt['recommended_detect_rate']*100:.1f}%)")

    # --- 기능 5: 비용효율 frontier ---
    _print_header("[기능 5] NIT 조합·비용 비교 — 비용효율 frontier")
    cef = core.cost_efficiency_frontier(lib, core.list_nits(lib), n_subjects,
                                        visit_months, n_repeat=1)
    rows = sorted(cef["rows"], key=lambda r: r["cost_per_subject"])
    print(f"  {'NIT':<26}{'1인당검사비':>14}{'검정력':>9}{'frontier':>10}")
    for r in rows:
        on_front = "O" if r["nit"] in cef["frontier_keys"] else "-"
        print(f"  {r['label']:<26}{r['cost_per_subject']:>12,}원"
              f"{r['power']*100:>7.1f}%{on_front:>10}")
    front_labels = [core.get_nit(lib, k)["label"] for k in cef["frontier_keys"]]
    print(f"  => 비용효율 frontier: {', '.join(front_labels)}")

    # --- 기능 6: 설계 리포트 ---
    _print_header("[기능 6] 설계 리포트 — VCTE_LSM 예시")
    print(core.generate_design_report(lib, "VCTE_LSM", n_subjects=n_subjects,
                                      n_followups=n_followups,
                                      interval_months=interval,
                                      subgroup="T2DM_or_MASH", n_repeat=1,
                                      window_weeks=4, missing_rate=0.15,
                                      budget_krw=50000000, n_sim=300))
    print()
    print("데모 종료. 개별 NIT 설계는: python3 main.py --nit <NIT> --help 참조")


def cmd_single(args):
    """개별 NIT 설계 리포트 출력."""
    lib = core.load_nit_library()
    if args.nit not in core.list_nits(lib):
        print(f"오류: 알 수 없는 NIT '{args.nit}'. 가능: {core.list_nits(lib)}",
              file=sys.stderr)
        return 1
    report = core.generate_design_report(
        lib, args.nit,
        n_subjects=args.subjects,
        n_followups=args.followups,
        interval_months=args.interval,
        subgroup=args.subgroup,
        n_repeat=args.repeat,
        window_weeks=args.window,
        missing_rate=args.missing,
        budget_krw=args.budget,
        n_sim=args.nsim,
    )
    print(report)
    return 0


def build_parser():
    p = argparse.ArgumentParser(
        prog="main.py",
        description="MASLDNITSchedule-Kor — MASLD/MASH NIT 종단 측정 스케줄 설계 계산기 (오프라인 CLI)",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=(
            "예시:\n"
            "  python3 main.py --demo\n"
            "  python3 main.py --nit VCTE_LSM --followups 3 --interval 6 --subjects 150\n"
            "  python3 main.py --report MRE\n\n"
            "면책: 참고용·연구용 도구. 실제 연구 설계는 생물통계학자 검토 필수.\n"
            "NIT 변동성·진행률·단가는 문헌 기반 추정치."
        ),
    )
    p.add_argument("--demo", action="store_true",
                   help="예제 스케줄로 MDC·tradeoff·결측시뮬·비용 전체 출력")
    p.add_argument("--nit", type=str, default=None,
                   help="설계할 NIT (FIB-4, ELF, VCTE_LSM, MRE, MRI_PDFF)")
    p.add_argument("--report", type=str, default=None, metavar="NIT",
                   help="해당 NIT의 프로토콜 측정계획 리포트 출력 (--nit 와 동일 동작)")
    p.add_argument("--followups", type=int, default=2, help="추적 visit 수 (기본 2)")
    p.add_argument("--interval", type=int, default=12, help="visit 간격(개월, 기본 12)")
    p.add_argument("--subjects", type=int, default=120, help="표본 수 (기본 120)")
    p.add_argument("--subgroup", type=str, default="T2DM_or_MASH",
                   help="진행률 하위집단 (기본 T2DM_or_MASH)")
    p.add_argument("--repeat", type=int, default=1, help="visit당 반복측정 횟수 (기본 1)")
    p.add_argument("--window", type=int, default=4, help="visit window 폭(주, 기본 4)")
    p.add_argument("--missing", type=float, default=0.15, help="가정 결측률 (기본 0.15)")
    p.add_argument("--budget", type=int, default=None, help="가용 예산(원, 선택)")
    p.add_argument("--nsim", type=int, default=300, help="Monte-Carlo 반복 수 (기본 300)")
    return p


def main(argv=None):
    parser = build_parser()
    args = parser.parse_args(argv)

    if args.demo:
        cmd_demo(args)
        return 0

    target = args.nit or args.report
    if target:
        args.nit = target
        return cmd_single(args)

    # 인자 없음 → 도움말
    parser.print_help()
    print()
    print("힌트: 빠른 시연은 'python3 main.py --demo'")
    return 0


if __name__ == "__main__":
    sys.exit(main())
