"""
Growth Tracker.

Takes periodic snapshots of video metrics to detect
acceleration/deceleration of viral growth.
"""

import json
import logging
import time
from datetime import datetime, timedelta

from sqlalchemy.orm import Session

from backend.models.video import Video

logger = logging.getLogger("viral_social.growth")


class GrowthTracker:
    MAX_SNAPSHOTS = 20  # Keep last 20 snapshots per video

    def take_snapshot(self, db: Session, video: Video) -> dict | None:
        """Record current metrics as a snapshot."""
        snapshot = {
            "timestamp": int(time.time()),
            "views": video.views,
            "likes": video.likes,
            "comments": video.comments,
            "shares": video.shares,
        }

        existing = []
        if video.growth_snapshots:
            try:
                existing = json.loads(video.growth_snapshots)
            except (json.JSONDecodeError, TypeError):
                existing = []

        # Don't add if views haven't changed
        if existing and existing[-1].get("views") == video.views:
            return None

        existing.append(snapshot)
        # Keep only last N snapshots
        if len(existing) > self.MAX_SNAPSHOTS:
            existing = existing[-self.MAX_SNAPSHOTS:]

        video.growth_snapshots = json.dumps(existing)
        db.commit()
        return snapshot

    def take_snapshots_for_recent(self, db: Session, hours: int = 72) -> int:
        """Take snapshots for all videos published within the last N hours."""
        cutoff = datetime.utcnow() - timedelta(hours=hours)
        videos = (
            db.query(Video)
            .filter(
                (Video.published_at.isnot(None)) &
                (Video.published_at >= cutoff)
            )
            .all()
        )

        count = 0
        for video in videos:
            result = self.take_snapshot(db, video)
            if result:
                count += 1

        logger.info(f"Took {count} snapshots for {len(videos)} recent videos")
        return count

    @staticmethod
    def get_growth_data(video: Video) -> dict:
        """Get growth analysis for a video."""
        if not video.growth_snapshots:
            return {"snapshots": [], "growth_rate": 0, "acceleration": 0, "status": "no_data"}

        try:
            snapshots = json.loads(video.growth_snapshots)
        except (json.JSONDecodeError, TypeError):
            return {"snapshots": [], "growth_rate": 0, "acceleration": 0, "status": "error"}

        if len(snapshots) < 2:
            return {"snapshots": snapshots, "growth_rate": 0, "acceleration": 0, "status": "insufficient"}

        # Current growth rate (views/hour in last interval)
        latest = snapshots[-1]
        previous = snapshots[-2]
        hours = max((latest["timestamp"] - previous["timestamp"]) / 3600, 0.5)
        growth_rate = (latest["views"] - previous["views"]) / hours

        # Acceleration
        acceleration = 0
        status = "stable"
        if len(snapshots) >= 3:
            even_earlier = snapshots[-3]
            earlier_hours = max((previous["timestamp"] - even_earlier["timestamp"]) / 3600, 0.5)
            earlier_rate = (previous["views"] - even_earlier["views"]) / earlier_hours

            if earlier_rate > 0:
                acceleration = growth_rate / earlier_rate
                if acceleration > 1.5:
                    status = "exploding"
                elif acceleration > 1.0:
                    status = "accelerating"
                elif acceleration > 0.5:
                    status = "decelerating"
                else:
                    status = "dying"
        elif growth_rate > 0:
            status = "growing"

        return {
            "snapshots": snapshots,
            "growth_rate": round(growth_rate, 0),
            "acceleration": round(acceleration, 2),
            "status": status,
        }
