"""
Sound/Audio Trend Predictor - Detect emerging sounds before they peak.
"""

from datetime import datetime
from sqlalchemy.orm import Session

from backend.models.competitor import SoundTracker


def track_sounds_from_videos(db: Session, videos: list[dict]) -> int:
    """Extract and track sounds from a list of videos."""
    tracked = 0
    for v in videos:
        music = v.get("music", {}) or {}
        if not isinstance(music, dict):
            continue
        sound_id = str(music.get("id", "") or music.get("musicId", "") or "")
        if not sound_id:
            continue

        # Extract URL safely (can be string or dict)
        play_url = music.get("playUrl", "") or music.get("play_url", "") or music.get("url", "")
        if isinstance(play_url, dict):
            play_url = play_url.get("uri", "") or ""

        existing = db.query(SoundTracker).filter(SoundTracker.sound_id == sound_id).first()
        if existing:
            existing.prev_video_count = existing.video_count
            existing.video_count = int(music.get("videoCount", existing.video_count) or existing.video_count)
            if existing.prev_video_count > 0:
                existing.growth_rate = (existing.video_count - existing.prev_video_count) / max(1, existing.prev_video_count) * 100
            existing.phase = _classify_phase(existing.video_count, existing.growth_rate, existing.first_seen)
            existing.last_checked = datetime.utcnow()
        else:
            count = int(music.get("videoCount", 0) or 0)
            title = str(music.get("title", "") or music.get("musicName", "") or "")[:500]
            author = str(music.get("authorName", "") or music.get("author", "") or "")[:200]
            db.add(SoundTracker(
                sound_id=sound_id,
                title=title,
                author=author,
                url=str(play_url)[:1000] if play_url else "",
                video_count=count,
                phase="emerging" if count < 500 else "growing",
            ))
        tracked += 1

    try:
        db.commit()
    except Exception:
        db.rollback()
    return tracked


def search_emerging_sounds(db: Session, sc, keywords: list[str] = None) -> list[dict]:
    """Search for sounds and track their growth."""
    if not keywords:
        keywords = ["viral sound", "trending audio", "novo som"]

    all_videos = []
    for kw in keywords[:3]:
        try:
            videos = sc.tiktok_search(kw, 20)
            all_videos.extend(videos)
        except Exception:
            pass

    if all_videos:
        track_sounds_from_videos(db, all_videos)

    return get_trending_sounds(db)


def get_trending_sounds(db: Session, limit: int = 30) -> list[dict]:
    """Get sounds sorted by growth rate."""
    sounds = (
        db.query(SoundTracker)
        .order_by(SoundTracker.growth_rate.desc())
        .limit(limit)
        .all()
    )
    return [s.to_dict() for s in sounds]


def get_emerging_sounds(db: Session, limit: int = 20) -> list[dict]:
    """Get sounds in emerging phase (< 500 videos, high growth)."""
    sounds = (
        db.query(SoundTracker)
        .filter(SoundTracker.phase == "emerging")
        .order_by(SoundTracker.growth_rate.desc())
        .limit(limit)
        .all()
    )
    return [s.to_dict() for s in sounds]


def _classify_phase(video_count: int, growth_rate: float, first_seen: datetime) -> str:
    hours_alive = max(1, (datetime.utcnow() - first_seen).total_seconds() / 3600)

    if video_count < 500 and hours_alive < 72:
        return "emerging"
    elif growth_rate > 20 and video_count < 10000:
        return "growing"
    elif growth_rate < 5 and video_count > 5000:
        return "peak"
    elif growth_rate < 0:
        return "declining"
    elif video_count < 5000:
        return "growing"
    return "peak"
