from datetime import datetime, timedelta from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, func from app.models.bet import Bet from app.models.bankroll import Bankroll async def calculate_risk_score(user_id, db: AsyncSession) -> dict: score = 0 factors = [] now = datetime.utcnow() # 1. Horário noturno (22h-5h) +15 hour = now.hour if hour >= 22 or hour < 5: score += 15 factors.append("Apostando em horário noturno") # 2. Valor crescente +25 recent = await db.execute( select(Bet).where(Bet.user_id == user_id).order_by(Bet.created_at.desc()).limit(5) ) recent_bets = recent.scalars().all() if len(recent_bets) >= 3: amounts = [float(b.amount) for b in recent_bets[:3]] if amounts[0] > amounts[1] > amounts[2]: score += 25 factors.append("Valores de aposta crescentes") # 3. Recuperação (aposta logo após loss) +30 if len(recent_bets) >= 2: last = recent_bets[0] prev = recent_bets[1] if prev.result == "loss" and last.created_at and prev.created_at: diff = (last.created_at - prev.created_at).total_seconds() if diff < 1800: # 30 min score += 30 factors.append("Tentativa de recuperação após perda") # 4. Frequência alta (>5 apostas em 24h) +20 day_ago = now - timedelta(hours=24) count_result = await db.execute( select(func.count()).select_from(Bet).where(Bet.user_id == user_id, Bet.created_at >= day_ago) ) bet_count = count_result.scalar() or 0 if bet_count > 5: score += 20 factors.append(f"Alta frequência: {bet_count} apostas em 24h") # 5. Limite estourado +25 br_result = await db.execute(select(Bankroll).where(Bankroll.user_id == user_id)) bankroll = br_result.scalar_one_or_none() if bankroll and float(bankroll.month_spent) > float(bankroll.monthly_budget): score += 25 factors.append("Limite mensal ultrapassado") # 6. Emoção negativa +15 if recent_bets and recent_bets[0].emotion in ["😤", "😰", "tilt", "ansioso", "frustrado"]: score += 15 factors.append("Emoção negativa detectada") # 7. Sequência de perdas +20 loss_streak = 0 for b in recent_bets: if b.result == "loss": loss_streak += 1 else: break if loss_streak >= 3: score += 20 factors.append(f"Sequência de {loss_streak} perdas consecutivas") if score <= 30: level = "green" elif score <= 60: level = "yellow" else: level = "red" return {"score": score, "level": level, "factors": factors}