File size: 5,144 Bytes
ef78361
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Trigger analysis section β€” date picker, run, preview, save.

Separated from overview.py so that CRUD operations work even when
trigger_rules module is unavailable (e.g., standalone HuggingFace Space).
"""
from datetime import date, timedelta

import streamlit as st

from core.supabase_client import (
    get_campaign_date_range,
    save_action_items_batch,
)
from .triggers import TRIGGERS_AVAILABLE
from .utils import priority_level, CATEGORY_CONFIG


def render_analysis_section(campaign_id: int, base_ctx: dict):
    """Render trigger analysis: date picker, run button, preview, save."""
    with st.expander("πŸ” 트리거 뢄석 μ‹€ν–‰", expanded=True):
        if not TRIGGERS_AVAILABLE:
            st.info(
                "트리거 뢄석 κΈ°λŠ₯을 μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€. "
                "전체 ν”„λ‘œμ νŠΈ ν™˜κ²½μ—μ„œλ§Œ μ§€μ›λ©λ‹ˆλ‹€."
            )
            return

        # Date range
        date_range = get_campaign_date_range(campaign_id)
        if not date_range:
            st.info("캠페인 데이터가 아직 λ™κΈ°ν™”λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.")
            return

        _, last_date_str = date_range
        last_date = date.fromisoformat(last_date_str)
        default_start = last_date - timedelta(days=6)

        date_cols = st.columns(2)
        with date_cols[0]:
            start_date = st.date_input(
                "μ‹œμž‘μΌ",
                value=default_start,
                key="ai_trigger_start",
            )
        with date_cols[1]:
            end_date = st.date_input(
                "μ’…λ£ŒμΌ",
                value=last_date,
                key="ai_trigger_end",
            )

        if st.button("πŸ” 뢄석 μ‹€ν–‰", key="ai_run_triggers", type="primary", use_container_width=True):
            with st.spinner("14개 트리거 κ·œμΉ™μ„ 평가 쀑..."):
                try:
                    from .triggers import evaluate_triggers

                    results = evaluate_triggers(
                        campaign_id,
                        start_date.isoformat(),
                        end_date.isoformat(),
                    )
                    st.session_state["ai_trigger_results"] = results
                except Exception as e:
                    st.error(f"뢄석 였λ₯˜: {e}")
                    return

        # Show results if available
        results = st.session_state.get("ai_trigger_results")
        if results is None:
            return

        if not results:
            st.success("λͺ¨λ“  μ§€ν‘œκ°€ 정상 λ²”μœ„μž…λ‹ˆλ‹€. νƒμ§€λœ μ‹ ν˜Έκ°€ μ—†μŠ΅λ‹ˆλ‹€.")
            return

        st.markdown(f"**{len(results)}개 μ‹ ν˜Έ 탐지됨**")

        # Preview cards
        for item in results:
            p_label, p_color, p_bg = priority_level(item["priority"])
            cat_cfg = CATEGORY_CONFIG.get(item["category"], {"color": "#666", "icon": "πŸ“Œ"})
            st.markdown(f"""
            <div style="background:#FAFAFA;border:1px solid #E5E7EB;border-radius:8px;
                        padding:12px;margin-bottom:8px;border-left:3px solid {p_color}">
                <div style="display:flex;gap:8px;align-items:center;margin-bottom:6px">
                    <span style="background:{p_bg};color:{p_color};padding:1px 8px;
                          border-radius:10px;font-size:11px;font-weight:600">{p_label}</span>
                    <span style="font-size:11px;color:{cat_cfg['color']}">{cat_cfg['icon']} {item['category']}</span>
                </div>
                <div style="font-size:14px;font-weight:600;color:#1F2937;margin-bottom:4px">{item['label']}</div>
                <div style="font-size:12px;color:#6B7280">{item.get('evidence', '')}</div>
            </div>
            """, unsafe_allow_html=True)

        # Save button
        if st.button("πŸ’Ύ μ•‘μ…˜μ•„μ΄ν…œμœΌλ‘œ μ €μž₯", key="ai_save_triggers", use_container_width=True):
            _save_trigger_results(campaign_id, results, base_ctx)


def _save_trigger_results(campaign_id: int, results: list[dict], base_ctx: dict):
    """Save trigger analysis results as action items."""
    try:
        from core.supabase_client import get_supabase_client

        user_client = get_supabase_client()
        key_result = (
            user_client.table("api_keys")
            .select("user_id")
            .limit(1)
            .execute()
        )
        user_id = str(key_result.data[0]["user_id"]) if key_result.data else "unknown"

        result = save_action_items_batch(
            campaign_id=campaign_id,
            user_id=user_id,
            items=results,
        )

        created = result.get("created", 0)
        skipped = result.get("skipped", 0)
        if result.get("error"):
            st.error(f"μ €μž₯ 였λ₯˜: {result['error']}")
        elif created > 0:
            st.success(f"βœ… {created}개 μ €μž₯ μ™„λ£Œ (쀑볡 {skipped}개 μŠ€ν‚΅)")
            st.session_state.pop("ai_trigger_results", None)
            st.rerun()
        else:
            st.info(f"λͺ¨λ“  ν•­λͺ©μ΄ 이미 μ‘΄μž¬ν•©λ‹ˆλ‹€ ({skipped}개 μŠ€ν‚΅)")
    except Exception as e:
        st.error(f"μ €μž₯ μ‹€νŒ¨: {e}")