from datetime import datetime

from sqlalchemy.orm import Session
from sqlalchemy import desc, func

from backend.models.creator import Creator
from backend.models.video import Video


class CreatorService:
    """Manage and monitor creators/competitors."""

    def get_creators(
        self,
        db: Session,
        platform: str = "",
        tracked_only: bool = False,
        search: str = "",
        sort_by: str = "followers",
        limit: int = 50,
        offset: int = 0,
    ) -> tuple[list[dict], int]:
        """Get creators with stats."""
        query = db.query(Creator)

        if platform:
            query = query.filter(Creator.platform == platform)
        if tracked_only:
            query = query.filter(Creator.tracked == True)  # noqa: E712
        if search:
            query = query.filter(Creator.username.ilike(f"%{search}%"))

        total = query.count()

        sort_map = {
            "followers": desc(Creator.followers),
            "avg_views": desc(Creator.avg_views),
            "avg_engagement": desc(Creator.avg_engagement),
            "recent": desc(Creator.updated_at),
            "name": Creator.username,
        }
        query = query.order_by(sort_map.get(sort_by, desc(Creator.followers)))
        creators = query.offset(offset).limit(limit).all()

        results = []
        for c in creators:
            video_count = db.query(Video).filter(Video.creator_id == c.id).count()
            avg_score = (
                db.query(func.avg(Video.viral_score))
                .filter(Video.creator_id == c.id)
                .scalar()
            ) or 0
            best_video = (
                db.query(Video)
                .filter(Video.creator_id == c.id)
                .order_by(desc(Video.viral_score))
                .first()
            )

            results.append({
                "id": c.id,
                "platform": c.platform,
                "username": c.username,
                "display_name": c.display_name,
                "profile_url": c.profile_url,
                "avatar_url": c.avatar_url,
                "followers": c.followers,
                "following": c.following,
                "tracked": c.tracked,
                "avg_views": c.avg_views,
                "avg_engagement": c.avg_engagement,
                "video_count": video_count,
                "avg_viral_score": round(float(avg_score), 1),
                "best_video": {
                    "id": best_video.id,
                    "title": best_video.title[:80],
                    "viral_score": best_video.viral_score,
                    "views": best_video.views,
                    "url": best_video.url,
                } if best_video else None,
            })

        return results, total

    def toggle_tracking(self, db: Session, creator_id: int) -> dict:
        """Toggle creator tracking on/off."""
        creator = db.query(Creator).filter(Creator.id == creator_id).first()
        if not creator:
            return {"error": "Criador não encontrado"}
        creator.tracked = not creator.tracked
        db.commit()
        return {
            "id": creator.id,
            "username": creator.username,
            "tracked": creator.tracked,
        }

    def update_creator_stats(self, db: Session, creator_id: int) -> dict:
        """Recalculate creator stats from their videos."""
        creator = db.query(Creator).filter(Creator.id == creator_id).first()
        if not creator:
            return {"error": "Criador não encontrado"}

        videos = db.query(Video).filter(Video.creator_id == creator_id).all()
        if videos:
            creator.total_videos = len(videos)
            creator.avg_views = sum(v.views for v in videos) / len(videos)
            creator.avg_engagement = sum(v.engagement_rate for v in videos) / len(videos)
            creator.updated_at = datetime.utcnow()
            db.commit()

        return {"id": creator.id, "updated": True}

    def get_creator_videos(
        self, db: Session, creator_id: int, limit: int = 50
    ) -> list[dict]:
        """Get all videos from a specific creator."""
        videos = (
            db.query(Video)
            .filter(Video.creator_id == creator_id)
            .order_by(desc(Video.viral_score))
            .limit(limit)
            .all()
        )
        return [
            {
                "id": v.id,
                "title": v.title[:100],
                "url": v.url,
                "views": v.views,
                "likes": v.likes,
                "viral_score": v.viral_score,
                "engagement_rate": v.engagement_rate,
                "platform": v.platform,
                "thumbnail_url": v.thumbnail_url,
                "published_at": v.published_at.isoformat() if v.published_at else None,
            }
            for v in videos
        ]

    def get_tracked_summary(self, db: Session) -> dict:
        """Get summary of all tracked creators."""
        tracked = db.query(Creator).filter(Creator.tracked == True).all()  # noqa: E712
        return {
            "total_tracked": len(tracked),
            "by_platform": {
                p: len([c for c in tracked if c.platform == p])
                for p in ["youtube", "tiktok", "instagram"]
            },
            "creators": [
                {
                    "id": c.id,
                    "username": c.username,
                    "platform": c.platform,
                    "followers": c.followers,
                    "avg_views": c.avg_views,
                }
                for c in tracked
            ],
        }

    @staticmethod
    def format_followers(n: int) -> str:
        if n >= 1_000_000:
            return f"{n / 1_000_000:.1f}M"
        if n >= 1_000:
            return f"{n / 1_000:.1f}K"
        return str(n)
