File size: 6,583 Bytes
f4d0231
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f82669f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
"""Response formatting utilities"""

from typing import Dict

def format_card_display(card_data: Dict) -> str:
    """Format card recommendation for display"""
    card_name = card_data.get("card_name", "Unknown Card")
    reward_rate = card_data.get("reward_rate", 0)
    reward_amount = card_data.get("reward_amount", 0)
    category = card_data.get("category", "General")
    reasoning = card_data.get("reasoning", "")
    
    return f"""
### ๐Ÿ’ณ {card_name}

**Reward Rate:** {reward_rate}x points  
**Reward Amount:** ${reward_amount:.2f}  
**Category:** {category}  
**Why:** {reasoning}
"""

def format_full_recommendation(response: Dict) -> str:
    """Format complete recommendation response"""
    if response.get("error"):
        return f"โŒ **Error:** {response.get('message', 'Unknown error')}"
    
    # Header
    output = f"""
# ๐ŸŽฏ Recommendation for {response.get('merchant', 'Unknown')}

**Amount:** ${response.get('amount_usd', 0):.2f}  
**Date:** {response.get('transaction_date', 'N/A')}  
**User:** {response.get('user_id', 'N/A')}

---

## ๐Ÿ† Best Card to Use

"""
    
    # Recommended card
    recommended = response.get("recommended_card", {})
    output += format_card_display(recommended)
    
    # RAG Insights
    rag_insights = response.get("rag_insights")
    if rag_insights:
        output += f"""
---

## ๐Ÿ“š Card Benefits

{rag_insights.get('benefits', 'No additional information available.')}
"""
        if rag_insights.get('tips'):
            output += f"""
๐Ÿ’ก **Pro Tip:** {rag_insights.get('tips')}
"""
    
    # Forecast Warning
    forecast = response.get("forecast_warning")
    if forecast:
        risk_level = forecast.get("risk_level", "low")
        message = forecast.get("message", "")
        
        if risk_level == "high":
            emoji = "๐Ÿšจ"
        elif risk_level == "medium":
            emoji = "โš ๏ธ"
        else:
            emoji = "โœ…"
        
        output += f"""
---

## {emoji} Spending Status

{message}

**Current Spend:** ${forecast.get('current_spend', 0):.2f}  
**Spending Cap:** ${forecast.get('cap', 0):.2f}  
**Projected Spend:** ${forecast.get('projected_spend', 0):.2f}
"""
    
    # Alternative cards
    alternatives = response.get("alternative_cards", [])
    if alternatives:
        output += "\n---\n\n## ๐Ÿ”„ Alternative Cards\n\n"
        for i, alt in enumerate(alternatives[:2], 1):
            output += f"### Option {i}\n"
            output += format_card_display(alt)
    
    # Metadata
    services = response.get("services_used", [])
    time_ms = response.get("orchestration_time_ms", 0)
    
    output += f"""
---

**Services Used:** {', '.join(services)}  
**Response Time:** {time_ms:.0f}ms
"""
    
    return output

def format_comparison_table(cards: list) -> str:
    """Format card comparison as markdown table"""
    if not cards:
        return "No cards to compare."
    
    table = """
| Card | Reward Rate | Reward Amount | Category |
|------|-------------|---------------|----------|
"""
    
    for card in cards:
        name = card.get("card_name", "Unknown")
        rate = card.get("reward_rate", 0)
        amount = card.get("reward_amount", 0)
        category = card.get("category", "N/A")
        table += f"| {name} | {rate}x | ${amount:.2f} | {category} |\n"
    
    return table

# utils/formatters.py

def format_analytics_metrics(analytics: Dict[str, Any]) -> tuple:
    """
    Format analytics data for display
    
    Returns:
        Tuple of (metrics_html, table_md, insights_md, forecast_md)
    """
    # Format metric cards
    metrics_html = f"""
    <div style="display: flex; gap: 10px; flex-wrap: wrap;">
        <div class="metric-card" style="flex: 1; min-width: 200px;">
            <h2>${analytics['annual_savings']}</h2>
            <p>๐Ÿ’ฐ Potential Annual Savings</p>
        </div>
        <div class="metric-card metric-card-green" style="flex: 1; min-width: 200px;">
            <h2>{analytics['rate_increase']}%</h2>
            <p>๐Ÿ“ˆ Rewards Rate Increase</p>
        </div>
        <div class="metric-card metric-card-orange" style="flex: 1; min-width: 200px;">
            <h2>{analytics['optimized_transactions']}</h2>
            <p>โœ… Optimized Transactions</p>
        </div>
        <div class="metric-card metric-card-blue" style="flex: 1; min-width: 200px;">
            <h2>{analytics['optimization_score']}/100</h2>
            <p>โญ Optimization Score</p>
        </div>
    </div>
    """
    
    # Format spending breakdown table
    table_rows = []
    for cat in analytics['category_breakdown']:
        table_rows.append(
            f"| {cat['category']} | ${cat['monthly_spend']:.2f} | {cat['best_card']} | "
            f"${cat['rewards']:.2f} | {cat['rate']} |"
        )
    
    table_md = f"""
| Category | Monthly Spend | Best Card | Rewards | Rate |
|----------|---------------|-----------|---------|------|
{chr(10).join(table_rows)}
| **Total** | **${analytics['total_monthly_spend']:.2f}** | - | **${analytics['total_monthly_rewards']:.2f}** | **{analytics['average_rate']}%** |
    """
    
    # Format insights
    top_cats = "\n".join([
        f"{i+1}. {cat['name']}: ${cat['amount']:.2f} ({cat['change']})"
        for i, cat in enumerate(analytics['top_categories'])
    ])
    
    insights_md = f"""
**๐Ÿ”ฅ Top Spending Categories:**
{top_cats}

**๐Ÿ’ก Optimization Opportunities:**
- โœ… You're using optimal cards {analytics['optimization_score']}% of the time
- ๐ŸŽฏ Switch to Chase Freedom for Q4 5% grocery bonus
- โš ๏ธ Amex Gold dining cap approaching ($2,000 limit)
- ๐Ÿ’ณ Consider applying for Citi Custom Cash

**๐Ÿ† Best Performing Card:**
{analytics['category_breakdown'],[object Object],['best_card']} - ${analytics['category_breakdown'],[object Object],['rewards']:.2f} rewards earned

**๐Ÿ“Š Year-to-Date:**
- Total Rewards: ${analytics['ytd_rewards']:.2f}
- Potential if optimized: ${analytics['ytd_potential']:.2f}
- **Money left on table: ${analytics['money_left']:.2f}**
    """
    
    # Format forecast
    forecast = analytics['forecast']
    recommendations = "\n".join([f"{i+1}. {rec}" for i, rec in enumerate(analytics['recommendations'])])
    
    forecast_md = f"""
### ๐Ÿ”ฎ Next Month Forecast

Based on your spending patterns:
- **Predicted Spend:** ${forecast['next_month_spend']:.2f}
- **Predicted Rewards:** ${forecast['next_month_rewards']:.2f}
- **Cards to Watch:** {', '.join(forecast['cards_to_watch'])}

**Recommendations:**
{recommendations}
    """
    
    return metrics_html, table_md, insights_md, forecast_md