from fastapi import APIRouter, Depends from sqlmodel import Session, select, func from app.core.database import get_session from app.models.analytics import AnalyticsEvent from app.models.user import User from typing import Optional, Dict from datetime import datetime, timedelta from app.api.deps import get_current_user_optional router = APIRouter() @router.post("/event") async def log_event( event: Dict, session: Session = Depends(get_session), current_user: Optional[User] = Depends(get_current_user_optional) ): user_id = current_user.id if current_user else None new_event = AnalyticsEvent( event_name=event.get("event_name"), user_id=user_id, screen_name=event.get("screen_name"), item_id=event.get("item_id"), properties=event.get("properties", {}) ) session.add(new_event) session.commit() return {"status": "ok"} @router.get("/strategic") async def get_strategic_analysis( session: Session = Depends(get_session) ): """Deep analysis of how businesses and shuttles are performing.""" # 1. SHUTTLE PERFORMANCE shuttle_previews = session.exec( select(AnalyticsEvent.item_id, func.count(AnalyticsEvent.id)) .where(AnalyticsEvent.event_name == "shuttle_view") .group_by(AnalyticsEvent.item_id) ).all() shuttle_contacts = session.exec( select(AnalyticsEvent.item_id, func.count(AnalyticsEvent.id)) .where(AnalyticsEvent.event_name == "shuttle_contact") .group_by(AnalyticsEvent.item_id) ).all() shuttle_map = {r[0]: {"views": r[1], "contacts": 0} for r in shuttle_previews if r[0]} for r in shuttle_contacts: if r[0] in shuttle_map: shuttle_map[r[0]]["contacts"] = r[1] else: shuttle_map[r[0]] = {"views": 0, "contacts": r[1]} # 2. BUSINESS PERFORMANCE biz_views = session.exec( select(AnalyticsEvent.item_id, func.count(AnalyticsEvent.id)) .where(AnalyticsEvent.event_name == "business_view") .group_by(AnalyticsEvent.item_id) ).all() promo_clicks = session.exec( select(AnalyticsEvent.item_id, func.count(AnalyticsEvent.id)) .where(AnalyticsEvent.event_name == "promo_click") .group_by(AnalyticsEvent.item_id) ).all() biz_map = {r[0]: {"views": r[1], "promos": 0} for r in biz_views if r[0]} for r in promo_clicks: if r[0] in biz_map: biz_map[r[0]]["promos"] = r[1] else: biz_map[r[0]] = {"views": 0, "promos": r[1]} # 3. TOP STOPS (CASETAS CON MÁS GENTE) top_stops = session.exec( select(AnalyticsEvent.item_id, func.count(AnalyticsEvent.id)) .where(AnalyticsEvent.event_name == "stop_selected") .group_by(AnalyticsEvent.item_id) .order_by(func.count(AnalyticsEvent.id).desc()) .limit(10) ).all() # 4. ACTIVE USERS total_active_users = session.exec(select(func.count(func.distinct(AnalyticsEvent.user_id))).where(AnalyticsEvent.user_id != None)).one() # 5. PEAK HOURS BY USER TYPE hour_expr = func.extract('hour', AnalyticsEvent.timestamp) reg_usage = session.exec(select(hour_expr, func.count(AnalyticsEvent.id)).where(AnalyticsEvent.user_id != None).group_by(hour_expr)).all() guest_usage = session.exec(select(hour_expr, func.count(AnalyticsEvent.id)).where(AnalyticsEvent.user_id == None).group_by(hour_expr)).all() usage_patterns = { "registered": {int(h): c for h, c in reg_usage}, "guests": {int(h): c for h, c in guest_usage} } return { "shuttles": shuttle_map, "businesses": biz_map, "top_stops": [{"id": r[0], "count": r[1]} for r in top_stops], "users": { "registered_active": total_active_users, "patterns": usage_patterns }, "summary": { "total_shuttle_contacts": sum(sh[1] for sh in shuttle_contacts), "total_promo_clicks": sum(p[1] for p in promo_clicks), "total_biz_views": sum(b[1] for b in biz_views) } } @router.get("/dashboard/stats") async def get_dashboard_stats( session: Session = Depends(get_session) ): # Base dashboard stats for general overview total_events = session.exec(select(func.count(AnalyticsEvent.id))).one() return { "total_events": total_events }