"""
Viral Discovery Engine v2 - Intelligent Content Discovery.

Instead of pulling from famous creators, this engine:
1. Uses hashtag-based discovery to find content from ANY creator
2. Leverages TikTok Creative Center for trending elements
3. Searches for rising stars (small creators with exploding content)
4. Cross-platform trend bridging (TikTok trend → find on Instagram)
"""

import logging
from datetime import datetime, timedelta

from backend.core.config import settings
from backend.scrapers.youtube import YouTubeScraper
from backend.scrapers.tiktok import TikTokScraper
from backend.scrapers.instagram import InstagramScraper
from backend.scrapers.tiktok_creative import TikTokCreativeCenter

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


def _get_scrapecreators():
    if settings.SCRAPECREATORS_API_KEY:
        from backend.scrapers.scrapecreators import ScrapeCreatorsAPI
        return ScrapeCreatorsAPI(settings.SCRAPECREATORS_API_KEY)
    return None


def _get_apify():
    if settings.APIFY_API_TOKEN:
        from backend.scrapers.apify_scraper import ApifyScraper
        return ApifyScraper(settings.APIFY_API_TOKEN)
    return None


class ViralDiscovery:
    def __init__(self):
        self.youtube = YouTubeScraper()
        self.tiktok = TikTokScraper(
            cookies_file=settings.TIKTOK_COOKIE_FILE or None
        )
        self.instagram = InstagramScraper()
        self.creative_center = TikTokCreativeCenter()

    def discover_all(
        self,
        region: str = "BR",
        max_per_platform: int = 50,
    ) -> dict:
        results = {
            "youtube": [],
            "tiktok": [],
            "instagram": [],
            "sources_used": [],
            "total": 0,
            "timestamp": datetime.utcnow().isoformat(),
        }

        yt_videos, yt_sources = self.discover_youtube(region, max_per_platform)
        results["youtube"] = yt_videos
        results["sources_used"].extend(yt_sources)

        tt_videos, tt_sources = self.discover_tiktok(region, max_per_platform)
        results["tiktok"] = tt_videos
        results["sources_used"].extend(tt_sources)

        ig_videos, ig_sources = self.discover_instagram(region, max_per_platform)
        results["instagram"] = ig_videos
        results["sources_used"].extend(ig_sources)

        results["total"] = len(yt_videos) + len(tt_videos) + len(ig_videos)
        return results

    # ─── YouTube Discovery ──────────────────────────────────────

    def discover_youtube(
        self, region: str = "BR", max_results: int = 50
    ) -> tuple[list[dict], list[str]]:
        all_videos = []
        sources = []

        # Strategy A: Rising Stars - Recent videos with high views from any channel
        rising_queries = [
            "shorts viral hoje",
            "video viral hoje",
            "viralizou agora",
        ]
        for query in rising_queries:
            if len(all_videos) >= max_results:
                break
            try:
                published_after = (
                    datetime.utcnow() - timedelta(days=2)
                ).strftime("%Y-%m-%dT%H:%M:%SZ")
                videos = self.youtube.search_trending(
                    query=query, region=region,
                    max_results=15, order="viewCount",
                    published_after=published_after,
                )
                if videos:
                    all_videos.extend(videos)
                    sources.append(f"youtube_rising:{query}")
            except Exception as e:
                logger.warning(f"[YouTube rising] '{query}' failed: {e}")

        # Strategy B: Trending page (still useful as secondary)
        try:
            videos = self.youtube.get_trending_videos(
                region=region, max_results=min(max_results, 50)
            )
            if videos:
                all_videos.extend(videos)
                sources.append("youtube_trending")
                logger.info(f"[YouTube] {len(videos)} trending videos")
        except Exception as e:
            logger.warning(f"[YouTube trending] failed: {e}")

        # Strategy C: Category-specific search for niches
        niche_queries = [
            "tutorial viral",
            "react video viral",
            "storytime viral",
            "receita viral",
            "dica viral",
        ]
        for query in niche_queries[:3]:
            if len(all_videos) >= max_results:
                break
            try:
                videos = self.youtube.search_trending(
                    query=query, region=region,
                    max_results=10, order="viewCount",
                )
                if videos:
                    all_videos.extend(videos)
                    sources.append(f"youtube_niche:{query}")
            except Exception as e:
                logger.warning(f"[YouTube niche] '{query}' failed: {e}")

        # Strategy D: ScrapeCreators (if available)
        sc = _get_scrapecreators()
        if sc and len(all_videos) < max_results:
            try:
                videos = sc.youtube_trending(region=region, count=30)
                if videos:
                    all_videos.extend(videos)
                    sources.append("scrapecreators_youtube_trending")
            except Exception as e:
                logger.warning(f"[ScrapeCreators YouTube trending] failed: {e}")

            # D2: Trending Shorts
            try:
                videos = sc.youtube_shorts_trending(region=region, count=30)
                if videos:
                    all_videos.extend(videos)
                    sources.append("scrapecreators_youtube_shorts")
            except Exception as e:
                logger.warning(f"[ScrapeCreators YouTube shorts] failed: {e}")

            # D3: YouTube search for viral content
            if len(all_videos) < max_results:
                try:
                    result = sc.youtube_search("viral", count=20)
                    videos = result.get("videos", []) + result.get("shorts", [])
                    if videos:
                        all_videos.extend(videos)
                        sources.append("scrapecreators_youtube_search")
                except Exception:
                    pass

        return self._deduplicate(all_videos)[:max_results], sources

    # ─── TikTok Discovery ──────────────────────────────────────

    def discover_tiktok(
        self, region: str = "BR", max_results: int = 50
    ) -> tuple[list[dict], list[str]]:
        all_videos = []
        sources = []

        # Strategy A: TikTok Creative Center top videos (FREE - PRIORITY)
        try:
            videos = self.creative_center.get_top_videos(
                region=region, period=7, limit=50
            )
            if videos:
                all_videos.extend(videos)
                sources.append("tiktok_creative_center_videos")
                logger.info(f"[Creative Center] {len(videos)} top videos")
        except Exception as e:
            logger.warning(f"[Creative Center] videos failed: {e}")

        # Strategy B: Hashtag-based discovery via Apify (finds ANY creator)
        apify = _get_apify()
        if apify and len(all_videos) < max_results:
            trending_tags = self._get_hot_hashtags(region)
            for tag in trending_tags[:3]:
                if len(all_videos) >= max_results:
                    break
                try:
                    videos = apify.tiktok_hashtag_videos(tag, max_results=20)
                    if videos:
                        all_videos.extend(videos)
                        sources.append(f"apify_tiktok_hashtag:{tag}")
                        logger.info(f"[Apify] {len(videos)} videos for #{tag}")
                except Exception as e:
                    logger.warning(f"[Apify hashtag #{tag}] failed: {e}")

        # Strategy C: Sound-based discovery
        # Get trending sounds, then find videos using them
        try:
            trending_songs = self.creative_center.get_trending_songs(
                region=region, limit=10
            )
            if trending_songs:
                sources.append("tiktok_creative_center_songs_meta")
                # Songs data enriches our trend detection
        except Exception:
            pass

        # Strategy D: Trending creators from Creative Center (dynamic, not hardcoded)
        try:
            trending_creators = self.creative_center.get_trending_creators(
                region=region, limit=10
            )
            if trending_creators:
                # Only scrape a few trending creators (not hardcoded mega accounts)
                for creator_info in trending_creators[:5]:
                    if len(all_videos) >= max_results:
                        break
                    username = creator_info.get("unique_id", "")
                    if not username:
                        continue
                    try:
                        videos = self.tiktok.get_user_videos(username, 5)
                        if videos:
                            all_videos.extend(videos)
                            sources.append(f"tiktok_trending_creator:{username}")
                    except Exception:
                        pass
        except Exception as e:
            logger.warning(f"[Creative Center creators] failed: {e}")

        # Strategy E: ScrapeCreators (PAID - full coverage)
        sc = _get_scrapecreators()
        if sc and len(all_videos) < max_results:
            # E1: Trending feed
            try:
                videos = sc.tiktok_trending(region=region, count=30)
                if videos:
                    all_videos.extend(videos)
                    sources.append("scrapecreators_tiktok_trending")
            except Exception as e:
                logger.warning(f"[ScrapeCreators TikTok trending] failed: {e}")

            # E2: Search top (videos + carousels with shop product detection)
            try:
                videos = sc.tiktok_search_top("trending viral", count=30)
                if videos:
                    all_videos.extend(videos)
                    sources.append("scrapecreators_search_top")
            except Exception as e:
                logger.warning(f"[ScrapeCreators search top] failed: {e}")

            # E3: Hashtag-based discovery
            trending_tags = self._get_hot_hashtags(region)
            for tag in trending_tags[:2]:
                try:
                    videos = sc.tiktok_hashtag_videos(tag, count=20)
                    if videos:
                        all_videos.extend(videos)
                        sources.append(f"scrapecreators_hashtag:{tag}")
                except Exception:
                    pass

            # E4: Search-based discovery
            if len(all_videos) < max_results:
                try:
                    videos = sc.tiktok_search("viral", count=20)
                    if videos:
                        all_videos.extend(videos)
                        sources.append("scrapecreators_tiktok_search")
                except Exception:
                    pass

        return self._deduplicate(all_videos)[:max_results], sources

    # ─── Instagram Discovery ───────────────────────────────────

    def discover_instagram(
        self, region: str = "BR", max_results: int = 50
    ) -> tuple[list[dict], list[str]]:
        all_videos = []
        sources = []

        # Strategy A: Cross-platform bridge - use TikTok trending hashtags on Instagram
        apify = _get_apify()
        if apify:
            cross_tags = self._get_hot_hashtags(region)[:3]
            for tag in cross_tags:
                if len(all_videos) >= max_results:
                    break
                try:
                    videos = apify.instagram_hashtag_posts(tag, max_results=15)
                    if videos:
                        all_videos.extend(videos)
                        sources.append(f"apify_ig_cross_hashtag:{tag}")
                except Exception:
                    pass

        # Strategy B: ScrapeCreators Instagram (PAID - full coverage)
        sc = _get_scrapecreators()
        if sc and len(all_videos) < max_results:
            # B1: Explore page
            try:
                videos = sc.instagram_explore(count=30)
                if videos:
                    all_videos.extend(videos)
                    sources.append("scrapecreators_ig_explore")
            except Exception as e:
                logger.warning(f"[ScrapeCreators IG explore] failed: {e}")

            # B2: Reels search (direct search for viral reels)
            try:
                videos = sc.instagram_reels_search("viral", count=30)
                if videos:
                    all_videos.extend(videos)
                    sources.append("scrapecreators_ig_reels_search")
            except Exception as e:
                logger.warning(f"[ScrapeCreators IG reels search] failed: {e}")

            # B3: Hashtag-based discovery
            ig_hashtags = ["viral", "reels", "trending", "fyp", "explore"]
            for tag in ig_hashtags[:2]:
                try:
                    videos = sc.instagram_hashtag(tag, count=20)
                    if videos:
                        all_videos.extend(videos)
                        sources.append(f"scrapecreators_ig_hashtag:{tag}")
                except Exception:
                    pass

        # Strategy C: yt-dlp for specific creators (only if nothing else worked)
        if len(all_videos) < 10:
            ig_creators = [
                "tiktok", "relogioglobo", "natgeo", "nike",
                "neymarjr", "leomessi",
            ]
            for creator in ig_creators[:4]:
                try:
                    videos = self.instagram.get_user_reels(creator, max_results=5)
                    if videos:
                        all_videos.extend(videos)
                        sources.append(f"ig_ytdlp:{creator}")
                except Exception:
                    pass
                if len(all_videos) >= max_results:
                    break

        return self._deduplicate(all_videos)[:max_results], sources

    # ─── Trending Hashtags ──────────────────────────────────────

    def discover_trending_hashtags(self, region: str = "BR") -> dict:
        result = {"tiktok": [], "instagram": [], "youtube": [], "sources_used": []}

        try:
            hashtags = self.creative_center.get_trending_hashtags(region=region, limit=50)
            if hashtags:
                result["tiktok"] = hashtags
                result["sources_used"].append("tiktok_creative_center")
        except Exception as e:
            logger.warning(f"[Creative Center hashtags] failed: {e}")

        apify = _get_apify()
        if apify and not result["tiktok"]:
            try:
                hashtags = apify.tiktok_trending_hashtags(region=region)
                if hashtags:
                    result["tiktok"] = hashtags
                    result["sources_used"].append("apify_tiktok_hashtags")
            except Exception as e:
                logger.warning(f"[Apify hashtags] failed: {e}")

        try:
            songs = self.creative_center.get_trending_songs(region=region, limit=30)
            if songs:
                result["tiktok_songs"] = songs
                result["sources_used"].append("tiktok_creative_center_songs")
        except Exception:
            pass

        return result

    # ─── Helpers ────────────────────────────────────────────────

    def _get_hot_hashtags(self, region: str) -> list[str]:
        try:
            hashtags = self.creative_center.get_trending_hashtags(
                region=region, period=7, limit=10
            )
            return [h["name"] for h in hashtags if h.get("name")]
        except Exception:
            return ["viral", "fyp", "trending", "foryou"]

    @staticmethod
    def _deduplicate(videos: list[dict]) -> list[dict]:
        seen = set()
        unique = []
        for v in videos:
            key = f"{v.get('platform', '')}:{v.get('external_id', '')}"
            if key not in seen and v.get("external_id"):
                seen.add(key)
                unique.append(v)
        return unique

    def get_source_status(self) -> dict:
        sc = _get_scrapecreators()
        apify = _get_apify()
        return {
            "free_sources": {
                "youtube_api": {
                    "configured": bool(settings.YOUTUBE_API_KEY),
                    "fallback": "yt-dlp (always works)",
                    "cost": "FREE (10K req/day)",
                },
                "tiktok_creative_center": {
                    "configured": True,
                    "cost": "FREE",
                    "note": "Trending hashtags, songs, creators, top videos",
                },
                "ytdlp_tiktok": {
                    "configured": True,
                    "cost": "FREE",
                    "note": "Works for user profiles",
                },
                "ytdlp_instagram": {
                    "configured": bool(
                        settings.INSTAGRAM_COOKIE_FILE or settings.COOKIES_FROM_BROWSER
                    ),
                    "cost": "FREE (needs cookies)",
                },
            },
            "paid_sources": {
                "scrapecreators": {
                    "configured": sc is not None,
                    "cost": "$10/5K credits (pay-as-you-go)",
                    "covers": "TikTok, Instagram, YouTube, TikTok Shop",
                    "features": [
                        "Popular videos/creators/hashtags/songs",
                        "TikTok Shop (products, stores, reviews)",
                        "Video transcripts (TikTok, Instagram, YouTube)",
                        "Comments, followers, following",
                        "Reels search, highlights",
                        "YouTube Shorts trending, channel videos",
                    ],
                },
                "apify": {
                    "configured": apify is not None,
                    "cost": "$0-39/month ($5 free credits)",
                    "covers": "TikTok hashtags, Instagram hashtags",
                },
            },
            "recommendation": self._get_recommendation(sc, apify),
        }

    @staticmethod
    def _get_recommendation(sc, apify) -> str:
        suggestions = []
        if not settings.YOUTUBE_API_KEY:
            suggestions.append(
                "Configure YOUTUBE_API_KEY (gratis, 10K req/dia)"
            )
        if sc is None:
            suggestions.append(
                "Configure SCRAPECREATORS_API_KEY ($10 por 5K creditos)"
            )
        if apify is None:
            suggestions.append(
                "Configure APIFY_API_TOKEN ($5 creditos gratis)"
            )
        if not suggestions:
            return "Todas as fontes configuradas! Coleta no maximo."
        return " | ".join(suggestions)
