# -*- coding: utf-8 -*-
"""
ObesityRecruitFeas-Kor — CLI 진입점
====================================

Streamlit 없이 오프라인에서 feasibility 분석을 실행하는 argparse CLI.

사용 예
-------
  python3 main.py --help
  python3 main.py --demo
  python3 main.py --bmi-min 30 --age-max 65 --target-n 150 --sites 8
  python3 main.py --comorbidity t2dm --comorbidity htn --comorbidity-count 1

면책: 참고용·연구용 도구. 실제 임상시험 feasibility는 CRO/생물통계
전문가 검토 필수.
"""

import argparse
import sys

try:
    import pandas  # noqa: F401
    import numpy   # noqa: F401
except ImportError as e:
    sys.stderr.write(
        "[오류] 필수 패키지(pandas/numpy)가 설치되어 있지 않습니다.\n"
        f"  세부: {e}\n"
        "  설치: pip install pandas numpy\n"
        "  (README.md의 '실행법' 참고)\n"
    )
    sys.exit(1)

import core


def build_parser():
    p = argparse.ArgumentParser(
        prog="main.py",
        description=(
            "ObesityRecruitFeas-Kor — 항비만 임상연구 모집 feasibility 계산기 "
            "(합성 KNHANES microdata 기반). 참고용·연구용 도구."
        ),
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
        epilog=core.DISCLAIMER,
    )
    p.add_argument("--demo", action="store_true",
                   help="예제 적격성 기준으로 전체 feasibility 분석을 출력")
    p.add_argument("--data", default=None,
                   help="합성 microdata CSV 경로 (기본: data/knhanes_synthetic.csv)")

    g = p.add_argument_group("적격성 — 포함 기준")
    g.add_argument("--bmi-min", type=float, default=None, help="BMI 하한 (>=)")
    g.add_argument("--bmi-max", type=float, default=None, help="BMI 상한 (<=)")
    g.add_argument("--age-min", type=int, default=None, help="연령 하한 (>=)")
    g.add_argument("--age-max", type=int, default=None, help="연령 상한 (<=)")
    g.add_argument("--waist-min", type=float, default=None,
                   help="허리둘레 하한 cm (0=미적용)")
    g.add_argument("--comorbidity", action="append", default=None,
                   choices=["t2dm", "htn", "dyslipidemia", "masld", "osa"],
                   help="동반질환 후보 (반복 지정 가능)")
    g.add_argument("--comorbidity-count", type=int, default=None,
                   help="동반질환 후보 중 요구 보유 개수")

    e = p.add_argument_group("적격성 — 제외 기준")
    e.add_argument("--exclude-t2dm", action="store_true",
                   help="T2DM 보유자 제외")
    e.add_argument("--no-exclude-glp1ra", action="store_true",
                   help="최근 GLP-1RA 사용자 제외를 해제(기본 제외)")
    e.add_argument("--exclude-smoker", action="store_true",
                   help="현재 흡연자 제외")
    e.add_argument("--no-exclude-severe-htn", action="store_true",
                   help="중증 고혈압 제외를 해제(기본 제외)")
    e.add_argument("--no-exclude-high-alt", action="store_true",
                   help="ALT>3xULN 제외를 해제(기본 제외)")

    t = p.add_argument_group("모집 timeline 설정")
    t.add_argument("--target-n", type=int, default=200, help="목표 등록 환자 수")
    t.add_argument("--sites", type=int, default=10, help="참여 사이트 수")
    t.add_argument("--screening-per-site", type=float, default=8.0,
                   help="사이트당 월간 스크리닝 capacity")
    t.add_argument("--attrition", type=float, default=0.10,
                   help="동의철회 등 추가 운영 손실 비율(0~1)")
    t.add_argument("--site-activation", type=float, default=2.0,
                   help="사이트 가동까지 평균 소요 개월")
    return p


def args_to_criteria(args):
    """argparse 네임스페이스 → core 기준 dict (None 항목은 기본값 유지)."""
    crit = {}
    if args.bmi_min is not None:
        crit["bmi_min"] = args.bmi_min
    if args.bmi_max is not None:
        crit["bmi_max"] = args.bmi_max
    if args.age_min is not None:
        crit["age_min"] = args.age_min
    if args.age_max is not None:
        crit["age_max"] = args.age_max
    if args.waist_min is not None:
        crit["waist_min"] = args.waist_min
    if args.comorbidity:
        crit["comorbidities"] = args.comorbidity
    if args.comorbidity_count is not None:
        crit["comorbidity_required_count"] = args.comorbidity_count
    if args.exclude_t2dm:
        crit["exclude_t2dm"] = True
    if args.no_exclude_glp1ra:
        crit["exclude_recent_glp1ra"] = False
    if args.exclude_smoker:
        crit["exclude_current_smoker"] = True
    if args.no_exclude_severe_htn:
        crit["exclude_severe_htn"] = False
    if args.no_exclude_high_alt:
        crit["exclude_high_alt"] = False
    return crit


# 데모용 예제 적격성 기준 — 항비만제 RCT 전형 (BMI>=30 또는 BMI>=27+동반질환)
DEMO_CRITERIA = {
    "bmi_min": 30.0,
    "bmi_max": 45.0,
    "age_min": 19,
    "age_max": 70,
    "comorbidities": ["t2dm", "htn", "dyslipidemia"],
    "comorbidity_required_count": 1,
    "exclude_recent_glp1ra": True,
    "exclude_severe_htn": True,
    "exclude_high_alt": True,
}


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

    # microdata 로드
    try:
        df = core.load_microdata(args.data)
    except (FileNotFoundError, ValueError) as e:
        sys.stderr.write(f"[오류] microdata 로드 실패:\n  {e}\n")
        return 2

    if args.demo:
        print(">>> 데모 모드: 예제 적격성 기준으로 전체 feasibility 분석\n")
        print("    (BMI>=30, 19~70세, [T2DM/고혈압/이상지질혈증] 중 1개 이상,")
        print("     제외: 최근 GLP-1RA·중증 고혈압·ALT>3xULN)\n")
        criteria = DEMO_CRITERIA
        target_n, sites, sps = 200, 10, 8.0
        attrition, activation = 0.10, 2.0
    else:
        criteria = args_to_criteria(args)
        target_n, sites, sps = args.target_n, args.sites, args.screening_per_site
        attrition, activation = args.attrition, args.site_activation

    report = core.generate_report(
        df, criteria,
        target_n=target_n, n_sites=sites,
        screening_per_site_month=sps,
        extra_attrition=attrition,
        site_activation_months=activation,
    )
    print(report)
    return 0


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