import logging from datetime import datetime, time from app import config from app.models import Review logger = logging.getLogger(__name__) class StatsService: async def get_daily_stats(self, platform: str) -> dict: target_date = datetime.now(config.TIMEZONE).date() day_start = datetime.combine(target_date, time.min, tzinfo=config.TIMEZONE) day_end = datetime.combine(target_date, time.max, tzinfo=config.TIMEZONE) reviews = await Review.filter( platform=platform, published_at__gte=day_start, published_at__lte=day_end ) return self._calculate_stats(platform, reviews) async def get_all_time_stats(self, platform: str) -> dict: reviews = await Review.filter(platform=platform) return self._calculate_stats(platform, reviews) def _calculate_stats(self, platform: str, reviews: list) -> dict: good_reviews = 0 bad_reviews = 0 critical_reviews = 0 rating_counts = {1: 0, 2: 0, 3: 0, 4: 0, 5: 0} tone_counts = {"positive": 0, "neutral": 0, "negative": 0} for review in reviews: rating = min(max(review.rating, 1), 5) rating_counts[rating] += 1 if rating <= 3: bad_reviews += 1 if review.is_critical: critical_reviews += 1 else: good_reviews += 1 if review.tone in tone_counts: tone_counts[review.tone] += 1 total_reviews = good_reviews + bad_reviews bad_ratio = bad_reviews / total_reviews if total_reviews > 0 else 0 critical_ratio = critical_reviews / total_reviews if total_reviews > 0 else 0 critical_to_bad_ratio = critical_reviews / bad_reviews if bad_reviews > 0 else 0 total_ratings = sum(rating_counts.values()) weighted_sum = sum(count * rating for rating, count in rating_counts.items()) average_rating = weighted_sum / total_ratings if total_ratings > 0 else 0 return { "platform": platform, "good_reviews": good_reviews, "bad_reviews": bad_reviews, "total_reviews": total_reviews, "bad_ratio": bad_ratio, "critical_reviews": critical_reviews, "critical_ratio": critical_ratio, "critical_to_bad_ratio": critical_to_bad_ratio, "ratings": { "1": rating_counts[1], "2": rating_counts[2], "3": rating_counts[3], "4": rating_counts[4], "5": rating_counts[5], }, "tone": { "positive": tone_counts["positive"], "neutral": tone_counts["neutral"], "negative": tone_counts["negative"], }, "average_rating": average_rating, }