"""
Trends Scanner Service - Discover trending content from TikTok and YouTube Shorts.

Strategy:
1. ScrapeCreators /v1/tiktok/trending (1 credit) -> trending TikTok videos
2. ScrapeCreators /v1/youtube/shorts (1 credit) -> trending YouTube Shorts
3. Local analysis (FREE) -> viral score, engagement, filters
4. Auto-runs every 15 minutes, max 200 credits/day

Each cycle uses 2 credits (1 TikTok + 1 YouTube Shorts).
At 15-min intervals = 96 cycles/day = 192 credits/day (under 200 limit).
"""

import time
import logging
from datetime import datetime

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

from backend.database.connection import SessionLocal
from backend.models.video import Video
from backend.services.viral_detector import ViralDetector
from backend.services import video_service
from backend.services.api_usage_tracker import log_usage, can_use_credits, get_usage_today

logger = logging.getLogger("viral_social.trends_scanner")
detector = ViralDetector()

# In-memory state
_trends_status = {
    "running": False,
    "last_run": None,
    "last_tiktok_found": 0,
    "last_youtube_found": 0,
    "last_videos_saved": 0,
    "last_credits_used": 0,
    "total_runs": 0,
    "error": None,
}


def get_trends_status() -> dict:
    return {**_trends_status}


def scan_trends(settings: dict) -> dict:
    """Fetch trending content from TikTok and YouTube Shorts.

    Args:
        settings: Dict with trends scanner settings from AppSettings.

    Returns:
        Dict with scan results.
    """
    global _trends_status

    if _trends_status["running"]:
        return {"error": "Trends scanner ja esta rodando", "status": "busy"}

    _trends_status["running"] = True
    _trends_status["error"] = None

    db = SessionLocal()
    results = {
        "tiktok_found": 0,
        "youtube_found": 0,
        "total_videos_found": 0,
        "total_videos_saved": 0,
        "total_credits_used": 0,
        "videos_with_products": 0,
        "scan_time": 0,
        "errors": [],
    }

    try:
        from backend.scrapers.scrapecreators import ScrapeCreatorsAPI
        from backend.models.settings import AppSettings

        # Get API key
        api_key_row = db.query(AppSettings).filter_by(key="scrapecreators_api_key").first()
        if not api_key_row or not api_key_row.value:
            _trends_status["running"] = False
            return {"error": "ScrapeCreators API key nao configurada.", "status": "error"}

        sc = ScrapeCreatorsAPI(api_key_row.value)

        daily_limit = int(settings.get("trends_daily_credit_limit", 200))
        delay = int(settings.get("trends_api_delay_seconds", 2))
        min_views = int(settings.get("trends_min_views_to_save", 10000))
        region = settings.get("trends_region", "BR")
        max_results = int(settings.get("trends_max_results", 30))

        # Platforms to scan
        scan_tiktok = settings.get("trends_scan_tiktok", "true").lower() == "true"
        scan_youtube = settings.get("trends_scan_youtube", "true").lower() == "true"

        start_time = time.time()

        # Check daily limit
        if not can_use_credits(db, daily_limit):
            results["errors"].append(f"Limite diario de {daily_limit} creditos atingido")
            logger.warning(f"[Trends] Daily limit {daily_limit} reached")
            _trends_status["running"] = False
            db.close()
            return results

        # ── TikTok Trending ──
        if scan_tiktok:
            try:
                videos_data = sc.tiktok_trending_feed(region=region, count=max_results)
                log_usage(db, "trends_scanner", "/v1/tiktok/trending",
                         credits=1, keyword="trending", videos_found=len(videos_data))
                results["total_credits_used"] += 1

                if videos_data:
                    # Track sounds
                    try:
                        from backend.services.sound_predictor import track_sounds_from_videos
                        track_sounds_from_videos(db, videos_data)
                    except Exception:
                        pass

                    if min_views > 0:
                        videos_data = [v for v in videos_data if v.get("views", 0) >= min_views]

                    product_count = sum(1 for v in videos_data if v.get("shop_product_url"))
                    results["videos_with_products"] += product_count
                    results["tiktok_found"] = len(videos_data)
                    results["total_videos_found"] += len(videos_data)

                    if videos_data:
                        saved = video_service.save_videos(db, videos_data)
                        results["total_videos_saved"] += len(saved)

                    logger.info(f"[Trends] TikTok trending: {len(videos_data)} found")
            except Exception as e:
                results["errors"].append(f"TikTok trending: {str(e)}")
                log_usage(db, "trends_scanner", "/v1/tiktok/trending",
                         credits=0, keyword="trending", status="error")
                logger.error(f"[Trends] TikTok error: {e}")

            if delay > 0 and scan_youtube:
                time.sleep(delay)

        # ── YouTube Shorts Trending ──
        if scan_youtube:
            try:
                videos_data = sc.youtube_shorts_feed(region=region, count=max_results)
                log_usage(db, "trends_scanner", "/v1/youtube/shorts",
                         credits=1, keyword="trending", videos_found=len(videos_data))
                results["total_credits_used"] += 1

                if videos_data:
                    if min_views > 0:
                        videos_data = [v for v in videos_data if v.get("views", 0) >= min_views]

                    results["youtube_found"] = len(videos_data)
                    results["total_videos_found"] += len(videos_data)

                    if videos_data:
                        saved = video_service.save_videos(db, videos_data)
                        results["total_videos_saved"] += len(saved)

                    logger.info(f"[Trends] YouTube Shorts trending: {len(videos_data)} found")
            except Exception as e:
                results["errors"].append(f"YouTube Shorts trending: {str(e)}")
                log_usage(db, "trends_scanner", "/v1/youtube/shorts",
                         credits=0, keyword="trending", status="error")
                logger.error(f"[Trends] YouTube error: {e}")

        results["scan_time"] = round(time.time() - start_time, 1)

        # Pre-cache thumbnails
        try:
            from backend.services.viral_scanner import _cache_new_thumbnails
            _cache_new_thumbnails(db)
        except Exception:
            pass

        # Update status
        _trends_status.update({
            "last_run": datetime.utcnow().isoformat(),
            "last_tiktok_found": results["tiktok_found"],
            "last_youtube_found": results["youtube_found"],
            "last_videos_saved": results["total_videos_saved"],
            "last_credits_used": results["total_credits_used"],
            "total_runs": _trends_status["total_runs"] + 1,
        })

    except Exception as e:
        _trends_status["error"] = str(e)
        results["errors"].append(str(e))
        logger.error(f"[Trends] Fatal error: {e}")
    finally:
        _trends_status["running"] = False
        db.close()

    return results


def get_trends_videos(
    db: Session,
    min_views: int = 0,
    max_views: int = 0,
    min_viral_score: float = 0,
    min_engagement: float = 0,
    min_duration: int = 0,
    max_duration: int = 0,
    has_product: str = "",
    description_contains: str = "",
    creator_tier: str = "",
    published_within_hours: int = 0,
    sort_by: str = "collected",
    limit: int = 48,
    offset: int = 0,
    platform: str = "",
    language: str = "",
) -> tuple[list[dict], int]:
    """Get trending videos with filters. Returns most recently collected first by default."""
    from datetime import timedelta

    query = db.query(Video)

    if platform:
        query = query.filter(Video.platform == platform)

    if language:
        query = query.filter(Video.language == language)

    if min_views > 0:
        query = query.filter(Video.views >= min_views)
    if max_views > 0:
        query = query.filter(Video.views <= max_views)

    if min_viral_score > 0:
        query = query.filter(Video.viral_score >= min_viral_score)

    if min_engagement > 0:
        query = query.filter(Video.engagement_rate >= min_engagement)

    if min_duration > 0:
        query = query.filter(Video.duration >= min_duration)
    if max_duration > 0:
        query = query.filter(Video.duration <= max_duration)

    if has_product == "yes":
        query = query.filter(
            or_(
                Video.shop_product_url != "",
                Video.shop_product_url != None,
            )
        )

    if description_contains:
        query = query.filter(
            or_(
                Video.title.ilike(f"%{description_contains}%"),
                Video.description.ilike(f"%{description_contains}%"),
            )
        )

    if creator_tier:
        tiers = {
            "nano": (1, 10_000),
            "micro": (10_000, 100_000),
            "mid": (100_000, 1_000_000),
            "macro": (1_000_000, 10_000_000),
            "mega": (10_000_000, 999_999_999),
        }
        if creator_tier in tiers:
            low, high = tiers[creator_tier]
            query = query.filter(Video.creator_followers >= low, Video.creator_followers < high)

    if published_within_hours > 0:
        since = datetime.utcnow() - timedelta(hours=published_within_hours)
        query = query.filter(Video.published_at >= since)

    total = query.count()

    sort_map = {
        "collected": desc(Video.collected_at),
        "viral_score": desc(Video.viral_score),
        "views": desc(Video.views),
        "likes": desc(Video.likes),
        "engagement": desc(Video.engagement_rate),
        "recent": desc(Video.published_at),
    }
    order = sort_map.get(sort_by, desc(Video.collected_at))
    videos = query.order_by(order).offset(offset).limit(limit).all()

    result = []
    for v in videos:
        d = {
            "id": v.id,
            "platform": v.platform,
            "external_id": v.external_id,
            "url": v.url,
            "embed_id": v.external_id,
            "title": v.title,
            "description": v.description,
            "hashtags": v.hashtags or [],
            "views": v.views,
            "views_formatted": v.views_formatted,
            "likes": v.likes,
            "comments": v.comments,
            "shares": v.shares,
            "duration": v.duration,
            "duration_formatted": v.duration_formatted,
            "thumbnail_url": f"/api/thumbnail/{v.id}",
            "viral_score": v.viral_score,
            "engagement_rate": v.engagement_rate,
            "outlier_ratio": v.outlier_ratio,
            "creator_followers": v.creator_followers,
            "shop_product_url": v.shop_product_url or "",
            "region": v.region or "",
            "created_by_ai": v.created_by_ai,
            "published_at": v.published_at.isoformat() if v.published_at else None,
            "collected_at": v.collected_at.isoformat() if v.collected_at else None,
            "viral_label": detector.get_viral_label(v.viral_score),
            "viral_color": detector.get_viral_color(v.viral_score),
            "creator": {"username": v.creator.username if v.creator else None} if v.creator else None,
        }
        result.append(d)

    return result, total
