from typing import Dict, Any, Optional, List from datetime import datetime, timedelta from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, func, and_ from app.models.preference import MarketingEffect import hashlib import logging logger = logging.getLogger(__name__) class MarketingEffectService: def __init__(self, db: AsyncSession): self.db = db async def track_event( self, user_id: str, content: str, product_id: Optional[str] = None, product_name: Optional[str] = None, channel: str = "copy", event_type: str = "copy", target_audience: str = "", metadata: Optional[Dict] = None, ) -> Dict[str, Any]: content_hash = hashlib.sha256(content.encode()).hexdigest() event = MarketingEffect( user_id=user_id, content_hash=content_hash, product_id=product_id, product_name=product_name, channel=channel, event_type=event_type, target_audience=target_audience, metadata=metadata or {}, ) self.db.add(event) await self.db.flush() return { "id": str(event.id), "event_type": event_type, "content_hash": content_hash, } async def get_effects( self, user_id: str, page: int = 1, size: int = 20 ) -> Dict[str, Any]: query = ( select(MarketingEffect) .where(MarketingEffect.user_id == user_id) .order_by(MarketingEffect.created_at.desc()) .offset((page - 1) * size) .limit(size) ) count_query = select(func.count(MarketingEffect.id)).where( MarketingEffect.user_id == user_id ) total = await self.db.execute(count_query) result = await self.db.execute(query) events = result.scalars().all() return { "items": [ { "id": str(e.id), "product_name": e.product_name, "channel": e.channel, "event_type": e.event_type, "target_audience": e.target_audience, "created_at": e.created_at.isoformat() if e.created_at else None, } for e in events ], "total": total.scalar() or 0, "page": page, "size": size, } async def get_stats(self, user_id: str) -> Dict[str, Any]: today = datetime.utcnow().date() week_ago = today - timedelta(days=7) total_query = select(func.count(MarketingEffect.id)).where( MarketingEffect.user_id == user_id ) today_query = select(func.count(MarketingEffect.id)).where( and_( MarketingEffect.user_id == user_id, func.date(MarketingEffect.created_at) == today, ) ) week_query = select(func.count(MarketingEffect.id)).where( and_( MarketingEffect.user_id == user_id, func.date(MarketingEffect.created_at) >= week_ago, ) ) copy_query = select(func.count(MarketingEffect.id)).where( and_( MarketingEffect.user_id == user_id, MarketingEffect.event_type == "copy", ) ) send_query = select(func.count(MarketingEffect.id)).where( and_( MarketingEffect.user_id == user_id, MarketingEffect.event_type == "send", ) ) totals = await self.db.execute(total_query) todays = await self.db.execute(today_query) weeks = await self.db.execute(week_query) copies = await self.db.execute(copy_query) sends = await self.db.execute(send_query) return { "total_events": totals.scalar() or 0, "today": todays.scalar() or 0, "this_week": weeks.scalar() or 0, "copy_count": copies.scalar() or 0, "send_count": sends.scalar() or 0, }