#!/usr/bin/env python3
"""
main.py — GlycemicNIMargin-Kor CLI 진입점

Streamlit 없이 오프라인에서 핵심 계산을 시연/검증하기 위한 argparse CLI.

사용법:
    python3 main.py --help
    python3 main.py --demo                  예제 시나리오 전체 출력
    python3 main.py --margin-fixed 0.8 0.5  fixed-margin 마진만 계산
    python3 main.py --samplesize 0.4 1.0    NI MMRM 표본수만 계산
"""

import argparse
import sys

import core


BANNER = "GlycemicNIMargin-Kor — 당뇨 RCT 비열등성 마진·표본수 계산기 (CLI)"
LINE = "=" * 70


def _print_disclaimer():
    print()
    print("-" * 70)
    print(core.DISCLAIMER)
    print("-" * 70)


def cmd_demo():
    print(LINE)
    print(BANNER)
    print(LINE)
    res = core.run_demo_scenario()

    print()
    print("[프리셋 로드]", "성공" if res["presets_loaded"] else "실패(내장 기본값 사용)")

    print()
    print("### 1. NI 마진 정당화 엔진")
    mf = res["margin_fixed"]
    print(f"  - Fixed-margin: {mf['interpretation']}")
    ms = res["margin_synthesis"]
    print(f"  - Synthesis(95-95): {ms['interpretation']}")

    print()
    print("### 2. MMRM 표본수 계산")
    ss = res["sample_size_mmrm"]
    de = ss["mmrm_design_effect"]
    base = ss["base_single_timepoint"]
    print(f"  - 단일시점 NI t-test: 총 {base['n_total']}명 "
          f"(유효거리 {base['effective_distance']:g})")
    print(f"  - MMRM 종단 설계효과 DE={de['longitudinal_DE']:.3f}, "
          f"결측 inflation={de['missing_inflation']:.3f}, "
          f"총 DE={de['total_design_effect']:.3f}")
    print(f"  - {ss['interpretation']}")
    comp = ss["comparison_ancova_single"]
    print(f"  - 비교(단순 ANCOVA 단일시점): 총 {comp['n_total']}명")

    print()
    print("### 3. 공동 1차 endpoint 다중성 처리")
    jp = res["joint_primary"]
    print(f"  - {jp['interpretation']}")
    print(f"  - 절차: {jp['procedure_note']}")
    for pe in jp["per_endpoint"]:
        print(f"    · {pe['label']}: 단독 표본수 총 {pe['n_total']}명")

    print()
    print("### 4. 탈락 시나리오 시뮬레이터 (검정력 히트맵)")
    drop = res["dropout_sensitivity"]
    pats = drop["patterns"]
    header = "  탈락률 | " + " | ".join(f"{p:>10}" for p in pats)
    print(header)
    print("  " + "-" * (len(header) - 2))
    for row in drop["heatmap"]:
        cells = []
        for p in pats:
            c = row["cells"][p]
            cells.append(f"{c['power']*100:9.1f}%")
        print(f"  {row['dropout_rate']*100:5.0f}% | " + " | ".join(cells))
    print(f"  ({drop['note']})")

    print()
    print("### 5. 규제 제출 문서 생성 (국문)")
    print(LINE)
    print(res["regulatory_text_ko"])
    print()
    print("### 5b. Regulatory text (English)")
    print(LINE)
    print(res["regulatory_text_en"])

    _print_disclaimer()
    return 0


def cmd_margin_fixed(effect, preserved):
    print(BANNER)
    print(LINE)
    r = core.ni_margin_fixed(effect, preserved)
    for k, v in r.items():
        print(f"  {k}: {v}")
    _print_disclaimer()
    return 0


def cmd_samplesize(margin, sd):
    print(BANNER)
    print(LINE)
    ss = core.sample_size_mmrm_ni(
        margin=margin, sd=sd, true_diff=0.0,
        alpha=0.025, power=0.80, allocation_ratio=1.0,
        visit_weeks=(0, 12, 24, 52), rho=0.6,
        cov_structure="ar1", dropout_rate=0.15, missing_mechanism="MAR")
    print(f"  마진={margin}, SD={sd}, alpha=0.025, power=0.80, 탈락 15% (MAR)")
    print(f"  {ss['interpretation']}")
    de = ss["mmrm_design_effect"]
    print(f"  MMRM 총 설계효과: {de['total_design_effect']:.3f} "
          f"(종단DE {de['longitudinal_DE']:.3f} x 결측 {de['missing_inflation']:.3f})")
    _print_disclaimer()
    return 0


def build_parser():
    p = argparse.ArgumentParser(
        prog="main.py",
        description=BANNER + "\n\n" + core.DISCLAIMER,
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="예시:\n"
               "  python3 main.py --demo\n"
               "  python3 main.py --margin-fixed 0.8 0.5\n"
               "  python3 main.py --samplesize 0.4 1.0\n")
    g = p.add_mutually_exclusive_group()
    g.add_argument("--demo", action="store_true",
                   help="예제 시나리오(HbA1c 비열등성 RCT) 전체 계산·출력")
    g.add_argument("--margin-fixed", nargs=2, type=float,
                   metavar=("ACTIVE_VS_PLACEBO", "PRESERVED_FRACTION"),
                   help="Fixed-margin NI 마진 계산. 예: --margin-fixed 0.8 0.5")
    g.add_argument("--samplesize", nargs=2, type=float,
                   metavar=("MARGIN", "SD"),
                   help="MMRM 비열등성 표본수 계산. 예: --samplesize 0.4 1.0")
    return p


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

    if args.demo:
        return cmd_demo()
    if args.margin_fixed is not None:
        return cmd_margin_fixed(args.margin_fixed[0], args.margin_fixed[1])
    if args.samplesize is not None:
        return cmd_samplesize(args.samplesize[0], args.samplesize[1])

    # 인자 없으면 도움말
    parser.print_help()
    print()
    print("힌트: 빠른 확인은  python3 main.py --demo")
    return 0


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