"""
X/Twitter Social Intelligence via Web Scraping
================================================
Uses web_search + web_extract for tweet discovery and content.
No API credits needed. Runs as a cron job every 6 hours.

Cache strategy:
  - Tweet text: cached 24h (doesn't change)
  - Engagement metrics: cached 1h (changes frequently)
  - Profile data: cached 24h
  - Sentiment/analysis: cached 6h

Cron: Every 6 hours, discover new tweets, extract content, update metrics.
"""

import logging
from datetime import UTC, datetime

from app.databus.cache import CacheLayer, get_cache

logger = logging.getLogger("databus.social_scraper")

# Twitter handle for our account
OUR_HANDLE = "CryptoRugMunch"
OUR_USER_ID = "1771377421117169668"  # @CryptoRugMunch

# Cache TTLs
CACHE_TTL_TWEET = 86400  # 24h - tweet text doesn't change
CACHE_TTL_METRICS = 3600  # 1h - engagement changes
CACHE_TTL_PROFILE = 86400  # 24h
CACHE_TTL_DISCOVERY = 21600  # 6h - new tweet discovery


class XWebScraper:
    """
    X/Twitter data via web search + extract. No API needed.

    Uses:
      - web_search: discover tweets by keyword/from:handle
      - web_extract: pull full tweet content from URLs
      - DataBus cache: dedup and TTL management

    Designed to run as a cron job every 6 hours.
    """

    def __init__(self, cache: CacheLayer = None):
        self.cache = cache or get_cache()

    async def discover_tweets(
        self, handle: str = OUR_HANDLE, since_date: str | None = None, limit: int = 50
    ) -> list[dict]:
        """
        Discover tweets from @handle using web_search.
        Returns list of {id, url, text_snippet, date, source}.
        """
        cache_key = f"social:x:discovery:{handle}:{since_date or 'latest'}"

        # Check cache first
        cached = await self.cache.get(cache_key)
        if cached:
            return cached

        # Import here to avoid circular imports in module scope
        from hermes_tools import web_extract, web_search

        all_tweets = {}
        queries = [
            f"from:{handle}",
            f"site:x.com/{handle} 2026",
            f"site:x.com/{handle} status",
        ]

        if since_date:
            queries.append(f"from:{handle} since:{since_date}")

        for q in queries:
            try:
                result = web_search(q, limit=10)
                for item in result.get("data", {}).get("web", []):
                    url = item.get("url", "")
                    desc = item.get("description", "")
                    title = item.get("title", "")

                    # Extract tweet ID from URL
                    tweet_id = url.split("/")[-1] if "/" in url else ""
                    if not tweet_id.isdigit():
                        continue

                    if tweet_id not in all_tweets:
                        all_tweets[tweet_id] = {
                            "id": tweet_id,
                            "url": url,
                            "title": title,
                            "description": desc,
                            "discovered_at": datetime.now(UTC).isoformat(),
                        }
            except Exception as e:
                logger.warning(f"Search error for '{q}': {e}")
                continue

        # Extract full content from discovered tweets
        tweet_urls = [
            t["url"]
            for t in all_tweets.values()
            if "CryptoRugMunch/status/" in t["url"] or "twitter.com/CryptoRugMunch/status/" in t["url"]
        ]

        if tweet_urls:
            for i in range(0, len(tweet_urls), 5):
                batch = tweet_urls[i : i + 5]
                try:
                    results = web_extract(batch)
                    for r in results.get("results", []):
                        if r.get("content"):
                            url = r.get("url", "")
                            tweet_id = url.split("/")[-1] if "/" in url else ""
                            if tweet_id in all_tweets:
                                all_tweets[tweet_id]["full_text"] = r["content"][:2000]
                                all_tweets[tweet_id]["extracted_at"] = datetime.now(UTC).isoformat()
                except Exception as e:
                    logger.warning(f"Extract error: {e}")
                    continue

        tweets = list(all_tweets.values())

        # Cache the discovery results
        await self.cache.set(cache_key, tweets, ttl=CACHE_TTL_DISCOVERY)

        # Cache individual tweets
        for tweet in tweets:
            await self.cache.set(f"social:x:tweet:{tweet['id']}", tweet, ttl=CACHE_TTL_TWEET)

        logger.info(f"Discovered {len(tweets)} tweets for @{handle}")
        return tweets

    async def get_profile(self, handle: str = OUR_HANDLE) -> dict | None:
        """
        Get profile data via web search. Returns cached if available.
        """
        cache_key = f"social:x:profile:{handle}"
        cached = await self.cache.get(cache_key)
        if cached:
            return cached

        from hermes_tools import web_search

        try:
            result = web_search(f"@{handle} twitter profile followers", limit=5)
            for item in result.get("data", {}).get("web", []):
                desc = item.get("description", "")
                if handle.lower() in desc.lower() and "follower" in desc.lower():
                    # Extract follower count from description
                    import re

                    match = re.search(r"(\d[\d,]+)\s+follower", desc)
                    followers = int(match.group(1).replace(",", "")) if match else None

                    profile = {
                        "handle": handle,
                        "followers": followers,
                        "source_url": item.get("url", ""),
                        "description": desc,
                        "updated_at": datetime.now(UTC).isoformat(),
                    }
                    await self.cache.set(cache_key, profile, ttl=CACHE_TTL_PROFILE)
                    return profile
        except Exception as e:
            logger.warning(f"Profile search error: {e}")

        return None

    async def get_mentions(self, handle: str = OUR_HANDLE, limit: int = 20) -> list[dict]:
        """
        Find tweets mentioning @handle.
        """
        cache_key = f"social:x:mentions:{handle}"
        cached = await self.cache.get(cache_key)
        if cached:
            return cached

        from hermes_tools import web_search

        mentions = []
        try:
            result = web_search(f"@{handle} -from:{handle}", limit=limit)
            for item in result.get("data", {}).get("web", []):
                url = item.get("url", "")
                if "/status/" in url and handle.lower() not in url.lower().split("/status/")[0]:
                    mentions.append(
                        {
                            "url": url,
                            "title": item.get("title", ""),
                            "description": item.get("description", ""),
                            "discovered_at": datetime.now(UTC).isoformat(),
                        }
                    )
        except Exception as e:
            logger.warning(f"Mentions search error: {e}")

        await self.cache.set(cache_key, mentions, ttl=CACHE_TTL_METRICS)
        return mentions

    async def get_trending_topics(self) -> list[dict]:
        """Get current crypto trending topics via web search."""
        cache_key = "social:x:trending:crypto"
        cached = await self.cache.get(cache_key)
        if cached:
            return cached

        from hermes_tools import web_search

        topics = []
        searches = [
            "crypto rug pull trending today",
            "crypto scam alert today 2026",
            "cryptocurrency security news",
        ]

        for q in searches:
            try:
                result = web_search(q, limit=5)
                for item in result.get("data", {}).get("web", []):
                    topics.append(
                        {
                            "query": q,
                            "title": item.get("title", ""),
                            "url": item.get("url", ""),
                            "description": item.get("description", "")[:200],
                            "discovered_at": datetime.now(UTC).isoformat(),
                        }
                    )
            except Exception:
                continue

        await self.cache.set(cache_key, topics, ttl=CACHE_TTL_METRICS)
        return topics

    async def get_engagement_report(self, handle: str = OUR_HANDLE) -> dict:
        """
        Generate an engagement report based on discovered tweets.
        Computes avg likes, best performing tweets, posting frequency.
        """
        tweets = await self.discover_tweets(handle)
        if not tweets:
            return {"error": "No tweets discovered"}

        # Extract engagement metrics from descriptions
        import re

        total_likes = 0
        total_replies = 0
        tweets_with_metrics = 0

        for t in tweets:
            desc = (t or {}).get("description", "")
            likes_match = re.search(r"(\d+)\s+likes?", desc)
            replies_match = re.search(r"(\d+)\s+repl(?:ies|y)", desc)

            if likes_match:
                total_likes += int(likes_match.group(1))
                tweets_with_metrics += 1
            if replies_match:
                total_replies += int(replies_match.group(1))

        avg_likes = total_likes / max(1, tweets_with_metrics)

        report = {
            "handle": handle,
            "total_tweets_discovered": len(tweets),
            "tweets_with_metrics": tweets_with_metrics,
            "total_likes": total_likes,
            "total_replies": total_replies,
            "avg_likes_per_tweet": round(avg_likes, 1),
            "best_tweets": sorted(
                [t for t in tweets if t and t.get("description")],
                key=lambda t: int(re.search(r"(\d+)\s+likes?", t.get("description", "")).group(1))
                if re.search(r"(\d+)\s+likes?", t.get("description", ""))
                else 0,
                reverse=True,
            )[:5],
            "generated_at": datetime.now(UTC).isoformat(),
        }

        return report


# Convenience function for cron jobs
async def run_social_scan():
    """Run a full social scan — called by cron every 6 hours."""
    cache = get_cache()
    scraper = XWebScraper(cache)

    # Discover new tweets
    tweets = await scraper.discover_tweets()
    logger.info(f"Social scan: discovered {len(tweets)} tweets")

    # Update profile
    profile = await scraper.get_profile()
    logger.info(f"Social scan: profile updated - {profile}")

    # Check mentions
    mentions = await scraper.get_mentions()
    logger.info(f"Social scan: found {len(mentions)} mentions")

    # Get trending topics
    trends = await scraper.get_trending_topics()
    logger.info(f"Social scan: found {len(trends)} trending items")

    # Generate engagement report
    report = await scraper.get_engagement_report()
    logger.info(f"Social scan: engagement report - avg {report.get('avg_likes_per_tweet', 0)} likes/tweet")

    return {
        "tweets_found": len(tweets),
        "mentions_found": len(mentions),
        "trends_found": len(trends),
        "report": report,
    }
