File size: 6,643 Bytes
ed5d5d7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
"""
Human+ β€” Page 2: AI Analysis
Refactored: loading states & biomarker rows pakai Streamlit native.
"""

import streamlit as st
from ui.components import (
    render_loading_steps,
    render_progress_bar,
    render_section_label,
    render_error_state,
    render_biomarker_summary_banner,
    render_biomarker_row,
    render_success_banner,
    ANALYSIS_STEPS,
)
from ui.chart_components import (
    render_gauge_grid,
    render_biomarker_bar_chart,
    render_status_donut,
)


def render_analysis_page():
    if not st.session_state.get("uploaded_pdf_bytes"):
        render_error_state(
            title="Tidak ada file PDF",
            message="Silakan kembali ke langkah pertama dan upload hasil lab Anda.",
        )
        if st.button("← Kembali ke Upload", use_container_width=True):
            st.session_state.step = 1
            st.rerun()
        return

    if st.session_state.get("extracted_biomarkers") is not None:
        _render_biomarker_results()
        return

    _run_analysis()


# ── Analysis runner ──────────────────────────────────────────────────

def _run_analysis():
    render_section_label("MENGANALISIS LAB ANDA", "⚑")

    status_ph   = st.empty()
    progress_ph = st.empty()
    steps_ph    = st.empty()

    def _update(step_idx: int, msg: str):
        with status_ph:
            st.caption(f"βš™οΈ {msg}...")
        with progress_ph:
            render_progress_bar((step_idx + 0.5) / len(ANALYSIS_STEPS))
        with steps_ph:
            render_loading_steps(ANALYSIS_STEPS, step_idx)

    # Step 0 β€” warm up vector store
    _update(0, ANALYSIS_STEPS[0])
    try:
        from core.rag_engine import get_vector_store
        get_vector_store()
    except Exception:
        pass

    # Step 1 β€” Gemini PDF extraction
    _update(1, ANALYSIS_STEPS[1])
    try:
        from core.pdf_processor import extract_biomarkers
        biomarkers = extract_biomarkers(st.session_state.uploaded_pdf_bytes)
    except Exception as e:
        _clear(steps_ph, status_ph, progress_ph)
        render_error_state(
            title="Gagal Menganalisis PDF",
            message=f"{e}\n\nPastikan PDF berisi hasil lab yang valid dan terbaca.",
            show_contact=True,
        )
        col1, col2 = st.columns(2)
        with col1:
            if st.button("← Upload Lagi", use_container_width=True):
                st.session_state.step = 1
                st.session_state.uploaded_pdf_bytes = None
                st.rerun()
        with col2:
            if st.button("πŸ”„ Coba Lagi", type="primary", use_container_width=True):
                st.rerun()
        return

    # Step 2 & 3 β€” finalize
    _update(2, ANALYSIS_STEPS[2])
    import time; time.sleep(0.3)
    _update(3, ANALYSIS_STEPS[3])
    import time; time.sleep(0.3)

    st.session_state.extracted_biomarkers = biomarkers

    with progress_ph:
        render_progress_bar(1.0)
    with status_ph:
        st.caption("βœ… Analisis selesai")

    import time; time.sleep(0.4)
    st.rerun()


def _clear(*placeholders):
    for ph in placeholders:
        ph.empty()


# ── Results renderer ─────────────────────────────────────────────────

def _render_biomarker_results():
    biomarkers = st.session_state.extracted_biomarkers

    if not biomarkers:
        render_error_state(
            title="Tidak ada biomarker terdeteksi",
            message="Coba upload file PDF yang lebih jelas atau format hasil lab standar.",
            show_contact=True,
        )
        if st.button("← Upload Ulang", use_container_width=True):
            for k in ["uploaded_pdf_bytes", "extracted_biomarkers", "generated_protocol"]:
                st.session_state[k] = None
            st.session_state.step = 1
            st.rerun()
        return

    optimal = sum(1 for b in biomarkers if b["status"] == "optimal")
    warning  = sum(1 for b in biomarkers if b["status"] == "warning")
    danger   = sum(1 for b in biomarkers if b["status"] == "danger")

    render_success_banner(
        title=f"{len(biomarkers)} biomarker berhasil dianalisis",
        subtitle="Dibandingkan dengan Human+ optimal ranges β€” bukan range lab standar",
    )
    render_biomarker_summary_banner(optimal, warning, danger)

    # ── Charts ────────────────────────────────────────────────────
    render_section_label("VISUALISASI BIOMARKER", "πŸ“Š")

    col_donut, col_bar = st.columns([1, 2])
    with col_donut:
        render_status_donut(optimal, warning, danger)
    with col_bar:
        render_biomarker_bar_chart(biomarkers)

    render_section_label("GAUGE β€” MARKER PRIORITAS", "🎯")
    render_gauge_grid(biomarkers)

    # ── Biomarker rows ─────────────────────────────────────────────
    if danger:
        render_section_label(f"PERLU PERHATIAN β€” {danger} MARKER", "πŸ”΄")
        for b in biomarkers:
            if b["status"] == "danger":
                render_biomarker_row(b["name"], b["value"], b["unit"], b["status"], b.get("reference", ""))

    if warning:
        render_section_label(f"SUB-OPTIMAL β€” {warning} MARKER", "🟑")
        for b in biomarkers:
            if b["status"] == "warning":
                render_biomarker_row(b["name"], b["value"], b["unit"], b["status"], b.get("reference", ""))

    if optimal:
        render_section_label(f"SUDAH OPTIMAL β€” {optimal} MARKER", "🟒")
        for b in biomarkers:
            if b["status"] == "optimal":
                render_biomarker_row(b["name"], b["value"], b["unit"], b["status"], b.get("reference", ""))

    neutral = [b for b in biomarkers if b["status"] == "neutral"]
    if neutral:
        with st.expander(f"πŸ“Š {len(neutral)} marker lainnya"):
            for b in neutral:
                render_biomarker_row(b["name"], b["value"], b["unit"], "neutral", "")

    st.write("")
    if st.button("πŸ”¬ Generate Protocol Personal Saya", type="primary", use_container_width=True):
        st.session_state.step = 3
        st.rerun()

    if st.button("← Upload Lab Lain", use_container_width=True):
        for k in ["uploaded_pdf_bytes", "extracted_biomarkers", "generated_protocol", "pdf_filename"]:
            st.session_state[k] = None
        st.session_state.step = 1
        st.rerun()