# -*- coding: utf-8 -*-
"""
MASHGraveyardReframe-Kor — Streamlit UI
main.py의 핵심 로직을 그대로 재사용(import)하여 UI로 래핑.
네트워크 호출 없음. 로컬 data/mash_failures.json만 사용.

실행: streamlit run app.py
(streamlit/networkx 미설치 환경에서는 import 단계에서 안내 메시지 출력.
 핵심 로직은 main.py로 CLI 실행 가능.)
"""

import os
import sys

# main.py의 표준 라이브러리 로직 재사용
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import main as core  # noqa: E402

try:
    import streamlit as st
except ImportError:
    sys.stderr.write(
        "streamlit이 설치되어 있지 않습니다. "
        "이 환경에서는 'python3 main.py --help'로 CLI를 사용하세요.\n"
        "(전역 패키지 설치는 정책상 금지)\n"
    )
    sys.exit(0)

# networkx는 선택적(귀속 그래프 시각화용). 없으면 graph 섹션만 비활성.
try:
    import networkx as nx
    HAS_NX = True
except ImportError:
    HAS_NX = False


# --------------------------------------------------------------------------
def load():
    return core.load_registry()


def verdict_color(verdict):
    base = verdict.split("(")[0]
    return {
        "target_invalid": "#c0392b",   # 적색 = 폐기
        "trial_killed": "#27ae60",     # 녹색 = 재설계 여지
        "safety_killed": "#e67e22",    # 주황 = 차세대 분자
        "unknown": "#7f8c8d",
    }.get(base, "#2c3e50")


def main():
    st.set_page_config(page_title="MASHGraveyardReframe-Kor", layout="wide")
    st.title("MASHGraveyardReframe-Kor")
    st.caption("MASH 실패 trial을 '표적 무효 vs trial 설계 결함'으로 귀속하고 "
               "재설계·재포지셔닝 가설을 ranked 생성하는 연구용 도구 (오프라인)")

    st.warning(core.DISCLAIMER)

    registry = load()
    drugs = registry["drugs"]
    meta = registry["_meta"]

    st.info("맥락: " + meta.get("context", ""))

    tab_rank, tab_drug, tab_repo, tab_data = st.tabs(
        ["① 재설계 RANKED", "② 약물 상세·귀속", "③ 재포지셔닝", "④ 레지스트리"])

    # ---------------- ① RANKED ----------------
    with tab_rank:
        top = st.slider("상위 N", 3, len(drugs), 8)
        scored = core.rank_drugs(registry)
        for rank, (score, d, verd) in enumerate(scored[:top], 1):
            col1, col2 = st.columns([1, 5])
            with col1:
                st.metric("#%d" % rank, "%.3f" % score)
            with col2:
                lbl = core.verdict_label_kor(verd["verdict"])
                st.markdown(
                    "**%s** &nbsp; <span style='color:%s'>[%s]</span>"
                    % (d["drug"], verdict_color(verd["verdict"]), lbl),
                    unsafe_allow_html=True)
                _, hyps = core.generate_redesign_hypotheses(d)
                if hyps:
                    st.write("→ " + hyps[0]["text"])
            st.divider()

    # ---------------- ② 약물 상세 ----------------
    with tab_drug:
        names = {d["drug"]: d for d in drugs}
        sel = st.selectbox("약물 선택", list(names.keys()))
        d = names[sel]
        verd, hyps = core.generate_redesign_hypotheses(d)

        st.subheader(d["drug"])
        st.write("**표적**: %s &nbsp; | &nbsp; **기전**: %s" % (d["target"], d["mechanism"]))
        st.write("**phase %s** | trials: %s | sponsor: %s"
                 % (d["phase"], ", ".join(d.get("trials", [])), d.get("sponsor", "?")))
        st.write("**결과**: " + d["result_summary"])

        c1, c2, c3 = st.columns(3)
        c1.metric("placebo response", "%s%%" % d.get("placebo_response_pct", "?"))
        c2.metric("treatment response", "%s%%" % d.get("treatment_response_pct", "?"))
        c3.metric("실패 유형", d["failure_type"])

        st.markdown("#### 귀속 판정: " + core.verdict_label_kor(verd["verdict"]))
        nm = verd["normalized"]
        st.write("표적 무효 확률"); st.progress(min(1.0, nm["target_invalid"]))
        st.write("trial 설계 결함 확률"); st.progress(min(1.0, nm["trial_killed"]))
        if nm["safety_killed"] > 0:
            st.write("안전성 원인 확률"); st.progress(min(1.0, nm["safety_killed"]))

        if verd["evidence"]:
            st.markdown("**귀속 근거 (audit):**")
            for e in verd["evidence"]:
                st.write("• " + e)

        st.markdown("#### 재설계 가설")
        for i, h in enumerate(hyps, 1):
            st.write("%d. _(%s)_ %s" % (i, h["kind"], h["text"]))

        design = core.minimal_redesign_design(d, verd)
        if design:
            st.markdown("#### 최소 phase 2 재설계 초안")
            st.json(design)
        else:
            st.write("→ 표적 무효 우세: 재설계 초안 없음(폐기·인접표적 권고).")

        if HAS_NX:
            st.markdown("#### 귀속 그래프 (networkx 요약)")
            g = nx.DiGraph()
            g.add_node(d["drug"]); g.add_node(d["target"])
            g.add_edge(d["drug"], d["target"], rel="targets")
            for cause, prob in [("표적무효", nm["target_invalid"]),
                                ("trial결함", nm["trial_killed"]),
                                ("안전성", nm["safety_killed"])]:
                if prob > 0:
                    g.add_edge(d["target"], cause, weight=round(prob, 2))
            st.write({"nodes": list(g.nodes()),
                      "edges": [(u, v, g.edges[u, v]) for u, v in g.edges()]})

    # ---------------- ③ 재포지셔닝 ----------------
    with tab_repo:
        st.write("전례: elafibranor/PPAR — MASH 실패 후 PBC 재포지셔닝 승인(2024).")
        for d in drugs:
            rts = d.get("reposition_targets", [])
            if rts:
                st.markdown("**%s** (%s)" % (d["drug"], d["target"]))
                for rt in rts:
                    st.write("→ " + rt)

    # ---------------- ④ 레지스트리 ----------------
    with tab_data:
        rows = [{"id": d["id"], "drug": d["drug"], "target": d["target"],
                 "phase": d["phase"], "failure_type": d["failure_type"],
                 "verdict": core.verdict_label_kor(
                     core.attribution_verdict(d)["verdict"]),
                 "plausibility": d.get("plausibility")}
                for d in drugs]
        st.dataframe(rows, use_container_width=True)
        st.caption("출처: ClinicalTrials.gov v2 results / PubMed post-hoc / "
                   "Open Targets (무료 공개) 기반 curated 데모. 세부 수치는 합성·근사값.")


if __name__ == "__main__":
    main()
