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

mock data 기반으로 5개 registry trial protocol amendment audit trail을 분석한다.
streamlit 없이도 `--help`가 동작하도록 import는 함수 안쪽에서 수행한다 (lazy import).

사용 예:
    python3 main.py --summary
    python3 main.py --top 10
    python3 main.py --alerts
    python3 main.py --trial NCT05556512
    python3 main.py --export-digest digest.md
    python3 main.py --export-csv trials.csv
    python3 main.py --rob2
    python3 main.py --korea
"""
from __future__ import annotations

import argparse
import csv
import json
import os
import sys


def build_parser() -> argparse.ArgumentParser:
    p = argparse.ArgumentParser(
        prog="obesity-trial-amend-kor",
        description=(
            "ObesityTrialProtocolAmend-Kor — ClinicalTrials.gov + EudraCT + jRCT + "
            "CRIS-Korea + ANZCTR 5개 registry의 항비만 trial protocol amendment "
            "audit trail을 일일 감시하고 중요도 채점·alert·weekly digest를 산출합니다. "
            "본 도구는 연구·참고용이며 mock data 기반입니다."
        ),
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    p.add_argument("--summary", action="store_true", help="전체 요약 출력")
    p.add_argument("--top", type=int, default=None, metavar="N", help="위기점수 상위 N개 trial 출력")
    p.add_argument("--alerts", action="store_true", help="leading indicator alert 목록 출력")
    p.add_argument("--trial", type=str, default=None, metavar="TRIAL_ID", help="특정 trial id 상세 amendment history 출력")
    p.add_argument("--korea", action="store_true", help="한국 sponsor / 한국 site trial만 출력")
    p.add_argument("--rob2", action="store_true", help="RoB2 보조 view 출력")
    p.add_argument(
        "--registry",
        type=str,
        default=None,
        metavar="NAME",
        help="특정 registry로 필터 (예: ClinicalTrials.gov, EudraCT, jRCT, CRIS-Korea, ANZCTR)",
    )
    p.add_argument("--export-digest", type=str, default=None, metavar="PATH", help="weekly digest Markdown 저장 경로")
    p.add_argument("--export-csv", type=str, default=None, metavar="PATH", help="trial-level 위기점수 CSV 저장 경로")
    p.add_argument("--data", type=str, default=None, metavar="PATH", help="trials.json 경로 (기본: data/trials.json)")
    p.add_argument("--rules", type=str, default=None, metavar="PATH", help="scoring_rules.json 경로 (기본: data/scoring_rules.json)")
    return p


def _load(args):
    # lazy import — streamlit이 없어도 --help는 동작
    from core import (
        load_trials,
        load_rules,
        filter_obesity,
        filter_by_registry,
        score_all_trials,
    )

    trials = load_trials(args.data)
    rules = load_rules(args.rules)
    trials = filter_obesity(trials)
    if args.registry:
        trials = filter_by_registry(trials, [args.registry])
    scores = score_all_trials(trials, rules)
    return trials, rules, scores


def cmd_summary(args) -> int:
    from core import summary_text

    _, rules, scores = _load(args)
    print(summary_text(scores, rules))
    return 0


def cmd_top(args) -> int:
    from core import top_n_text

    _, _, scores = _load(args)
    print(top_n_text(scores, n=args.top))
    return 0


def cmd_alerts(args) -> int:
    from core import leading_indicator_alerts, DISCLAIMER

    _, rules, scores = _load(args)
    alerts = leading_indicator_alerts(scores, rules)
    print("=== Leading indicator alerts ===")
    print(DISCLAIMER)
    print()
    if not alerts:
        print("(해당 없음)")
        return 0
    for a in alerts:
        flags = ", ".join(a["flags"]) if a["flags"] else "-"
        term = f" / 종료사유:{a['termination_reason']}" if a["termination_reason"] else ""
        print(
            f"[{a['level']}] {a['name']} ({a['trial_id']}) — "
            f"{a['sponsor']} — crisis {a['crisis_score']}점 · status={a['status']}{term}"
        )
        print(f"   flags: {flags}")
    return 0


def cmd_trial(args) -> int:
    from core import DISCLAIMER

    trials, _, scores = _load(args)
    target_id = args.trial
    score_map = {s.trial_id: s for s in scores}
    trial_map = {t["trial_id"]: t for t in trials}
    if target_id not in trial_map:
        print(f"[ERROR] trial_id not found: {target_id}", file=sys.stderr)
        print("사용 가능한 trial id 예시:", file=sys.stderr)
        for tid in list(trial_map.keys())[:8]:
            print(f"  - {tid}", file=sys.stderr)
        return 2
    t = trial_map[target_id]
    s = score_map[target_id]
    print(DISCLAIMER)
    print()
    print(f"# {t['name']} ({t['trial_id']})")
    print(f"- sponsor: {t['sponsor']} / country: {t['country']} / registry: {t['registry']}")
    print(f"- drug_class: {t['drug_class']} / intervention: {t['intervention']}")
    print(f"- condition: {t['condition']} / phase: {t['phase']} / status: {t['status']}")
    print(f"- n: {t['current_n']} / primary_completion: {t['primary_completion']} / readout_estimated: {t.get('readout_estimated')}")
    print(f"- 위기점수: {s.crisis_score}점 (amendment {len(s.amendment_scores)}건)")
    if s.flags:
        print(f"- flags: {', '.join(s.flags)}")
    if s.termination_reason:
        print(f"- 종료사유: {s.termination_reason}")
    print()
    print("## Amendment history")
    for a in s.amendment_scores:
        am = a["amendment"]
        rules_str = ", ".join(r.get("label", r.get("id")) for r in a["matched_rules"]) or "-"
        print(f"- {am.get('date')} [{am.get('type')}] score={a['score']}")
        print(f"    before : {am.get('before')}")
        print(f"    after  : {am.get('after')}")
        print(f"    reason : {am.get('reason')}")
        print(f"    note   : {am.get('note')}")
        print(f"    rules  : {rules_str}")
    return 0


def cmd_korea(args) -> int:
    from core import korean_sponsor_highlight, DISCLAIMER

    _, _, scores = _load(args)
    krs = korean_sponsor_highlight(scores)
    print("=== 한국 sponsor / 한국 site trial ===")
    print(DISCLAIMER)
    print()
    if not krs:
        print("(해당 없음)")
        return 0
    for s in krs:
        print(
            f"- {s.name} ({s.trial_id}) — sponsor: {s.sponsor} — "
            f"crisis {s.crisis_score}점 · amend {len(s.amendment_scores)}건 · status={s.status}"
        )
    return 0


def cmd_rob2(args) -> int:
    from core import rob2_view, DISCLAIMER

    _, _, scores = _load(args)
    print("=== RoB2 보조 view ===")
    print(DISCLAIMER)
    print()
    for row in rob2_view(scores):
        flags = [k for k, v in row["rob_signals"].items() if v]
        flag_str = ", ".join(flags) if flags else "-"
        print(
            f"- {row['name']} ({row['trial_id']}, {row['sponsor']}) — "
            f"crisis {row['crisis_score']}점 — concerns: {flag_str}"
        )
    return 0


def cmd_export_digest(args) -> int:
    from core import build_weekly_digest

    _, rules, scores = _load(args)
    md = build_weekly_digest(scores, rules)
    with open(args.export_digest, "w", encoding="utf-8") as f:
        f.write(md)
    print(f"[OK] weekly digest 저장: {args.export_digest} ({len(md):,} chars)")
    return 0


def cmd_export_csv(args) -> int:
    _, _, scores = _load(args)
    with open(args.export_csv, "w", encoding="utf-8", newline="") as f:
        w = csv.writer(f)
        w.writerow(
            [
                "trial_id",
                "name",
                "sponsor",
                "country",
                "registry",
                "drug_class",
                "status",
                "korean_site",
                "crisis_score",
                "amendment_count",
                "readout_dday",
                "primary_completion",
                "termination_reason",
                "flags",
            ]
        )
        for s in scores:
            w.writerow(
                [
                    s.trial_id,
                    s.name,
                    s.sponsor,
                    s.country,
                    s.registry,
                    s.drug_class,
                    s.status,
                    s.korean_site,
                    s.crisis_score,
                    len(s.amendment_scores),
                    s.readout_dday if s.readout_dday is not None else "",
                    s.primary_completion or "",
                    s.termination_reason or "",
                    "|".join(s.flags),
                ]
            )
    print(f"[OK] CSV 저장: {args.export_csv} ({len(scores)} rows)")
    return 0


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

    # 아무 옵션도 없으면 도움말 출력
    no_action = not any(
        [
            args.summary,
            args.top is not None,
            args.alerts,
            args.trial,
            args.korea,
            args.rob2,
            args.export_digest,
            args.export_csv,
        ]
    )
    if no_action:
        parser.print_help()
        return 0

    exit_code = 0
    if args.summary:
        exit_code = cmd_summary(args) or exit_code
    if args.top is not None:
        exit_code = cmd_top(args) or exit_code
    if args.alerts:
        exit_code = cmd_alerts(args) or exit_code
    if args.trial:
        exit_code = cmd_trial(args) or exit_code
    if args.korea:
        exit_code = cmd_korea(args) or exit_code
    if args.rob2:
        exit_code = cmd_rob2(args) or exit_code
    if args.export_digest:
        exit_code = cmd_export_digest(args) or exit_code
    if args.export_csv:
        exit_code = cmd_export_csv(args) or exit_code
    return exit_code


if __name__ == "__main__":
    raise SystemExit(main())
