"""Social sentiment signal analysis."""

from typing import Any

from .base import Signal, SignalCategory, SignalIndicator, SignalResult


class SocialSignal(Signal):
    """Analyze social sentiment signals for FOMO detection."""

    category = SignalCategory.SOCIAL
    weight = 0.30  # 30% weight in final score

    async def analyze(self, symbol: str, data: dict[str, Any]) -> SignalResult:
        """Analyze social signals."""
        indicators = []

        # Check if we have any social data
        if not data:
            return self._create_result(
                indicators=[],
                summary="Social data unavailable - configure API keys for social analysis",
                available=False,
            )

        # Twitter analysis
        twitter_data = data.get("twitter", {})
        if twitter_data:
            twitter_indicators = self._analyze_twitter(twitter_data)
            indicators.extend(twitter_indicators)

        # Reddit analysis
        reddit_data = data.get("reddit", {})
        if reddit_data:
            reddit_indicators = self._analyze_reddit(reddit_data)
            indicators.extend(reddit_indicators)

        # LunarCrush analysis (comprehensive social metrics)
        lunarcrush_data = data.get("lunarcrush", {})
        if lunarcrush_data:
            lc_indicators = self._analyze_lunarcrush(lunarcrush_data)
            indicators.extend(lc_indicators)

        if not indicators:
            return self._create_result(
                indicators=[],
                summary="No social data available",
                available=False,
            )

        score = self._calculate_score(indicators)
        summary = self._generate_summary(score, indicators)

        return self._create_result(indicators, summary)

    def _analyze_twitter(self, data: dict[str, Any]) -> list[SignalIndicator]:
        """Analyze Twitter data for FOMO signals."""
        indicators = []

        # Mention velocity (surge detection)
        velocity = data.get("mention_velocity")
        if velocity is not None:
            score = self._velocity_to_score(velocity, "twitter")
            indicators.append(
                SignalIndicator(
                    name="Twitter Velocity",
                    value=velocity,
                    score=score,
                    description=self._describe_velocity(velocity, "Twitter mentions"),
                    raw_value=velocity,
                )
            )

        # Sentiment score
        sentiment = data.get("sentiment_score")
        if sentiment is not None:
            # High bullish sentiment can indicate FOMO
            score = self._sentiment_to_score(sentiment)
            indicators.append(
                SignalIndicator(
                    name="Twitter Sentiment",
                    value=sentiment,
                    score=score,
                    description=self._describe_sentiment(sentiment),
                    raw_value=sentiment,
                )
            )

        # Bullish ratio
        bullish_ratio = data.get("bullish_ratio")
        if bullish_ratio is not None:
            # Extreme bullishness is a FOMO indicator
            score = self._bullish_ratio_to_score(bullish_ratio)
            indicators.append(
                SignalIndicator(
                    name="Bullish Ratio",
                    value=bullish_ratio * 100,
                    score=score,
                    description=f"{bullish_ratio * 100:.0f}% of tweets are bullish",
                    raw_value=bullish_ratio,
                )
            )

        return indicators

    def _analyze_reddit(self, data: dict[str, Any]) -> list[SignalIndicator]:
        """Analyze Reddit data for FOMO signals."""
        indicators = []

        # Post count surge
        post_count = data.get("post_count_24h")
        if post_count is not None:
            score = self._post_count_to_score(post_count)
            indicators.append(
                SignalIndicator(
                    name="Reddit Activity",
                    value=post_count,
                    score=score,
                    description=f"{post_count} posts in last 24h",
                    raw_value=post_count,
                )
            )

        # Average post score (engagement)
        avg_score = data.get("avg_score")
        if avg_score is not None:
            score = self._engagement_to_score(avg_score)
            indicators.append(
                SignalIndicator(
                    name="Reddit Engagement",
                    value=avg_score,
                    score=score,
                    description=f"Average post score: {avg_score:.0f}",
                    raw_value=avg_score,
                )
            )

        return indicators

    def _analyze_lunarcrush(self, data: dict[str, Any]) -> list[SignalIndicator]:
        """Analyze LunarCrush data for FOMO signals."""
        indicators = []

        # Galaxy Score (LunarCrush's overall social metric)
        galaxy_score = data.get("galaxy_score")
        if galaxy_score is not None:
            # High galaxy score can indicate hype/FOMO
            fomo_score = self._galaxy_score_to_fomo(galaxy_score)
            indicators.append(
                SignalIndicator(
                    name="Galaxy Score",
                    value=galaxy_score,
                    score=fomo_score,
                    description=self._describe_galaxy_score(galaxy_score),
                    raw_value=galaxy_score,
                )
            )

        # Social volume change
        volume_change = data.get("social_volume_change_24h")
        if volume_change is not None:
            score = self._volume_change_to_score(volume_change)
            indicators.append(
                SignalIndicator(
                    name="Social Volume Change",
                    value=volume_change,
                    score=score,
                    description=f"Social volume {'+' if volume_change >= 0 else ''}{volume_change:.0f}% in 24h",
                    raw_value=volume_change,
                )
            )

        # Sentiment (0-100 scale)
        sentiment = data.get("sentiment")
        if sentiment is not None:
            # LunarCrush sentiment is 0-100, high is bullish
            score = self._lc_sentiment_to_score(sentiment)
            indicators.append(
                SignalIndicator(
                    name="LunarCrush Sentiment",
                    value=sentiment,
                    score=score,
                    description=self._describe_lc_sentiment(sentiment),
                    raw_value=sentiment,
                )
            )

        return indicators

    def _velocity_to_score(self, velocity: float, platform: str) -> float:
        """Convert mention velocity to FOMO score."""
        # Thresholds vary by platform
        if velocity >= 500:
            return 95  # Viral
        elif velocity >= 200:
            return 80
        elif velocity >= 100:
            return 60
        elif velocity >= 50:
            return 40
        else:
            return 20

    def _describe_velocity(self, velocity: float, metric: str) -> str:
        """Describe mention velocity."""
        if velocity >= 500:
            return f"Extreme {metric} surge - viral activity detected"
        elif velocity >= 200:
            return f"High {metric} volume - significant attention"
        elif velocity >= 100:
            return f"Elevated {metric} - above average interest"
        elif velocity >= 50:
            return f"Moderate {metric} - normal activity"
        else:
            return f"Low {metric} - minimal attention"

    def _sentiment_to_score(self, sentiment: float) -> float:
        """Convert sentiment (-1 to 1) to FOMO score."""
        # High bullish sentiment = high FOMO risk
        if sentiment >= 0.8:
            return 90  # Extreme bullishness
        elif sentiment >= 0.5:
            return 70
        elif sentiment >= 0.2:
            return 50
        elif sentiment >= -0.2:
            return 30  # Neutral
        else:
            return 15  # Bearish (contrarian opportunity)

    def _describe_sentiment(self, sentiment: float) -> str:
        """Describe sentiment score."""
        if sentiment >= 0.8:
            return "Extremely bullish - potential euphoria"
        elif sentiment >= 0.5:
            return "Very bullish sentiment"
        elif sentiment >= 0.2:
            return "Moderately bullish"
        elif sentiment >= -0.2:
            return "Neutral sentiment"
        else:
            return "Bearish sentiment"

    def _bullish_ratio_to_score(self, ratio: float) -> float:
        """Convert bullish ratio (0-1) to FOMO score."""
        if ratio >= 0.9:
            return 95  # Echo chamber
        elif ratio >= 0.8:
            return 80
        elif ratio >= 0.7:
            return 60
        elif ratio >= 0.5:
            return 35
        else:
            return 15

    def _post_count_to_score(self, count: int) -> float:
        """Convert post count to FOMO score."""
        if count >= 500:
            return 90
        elif count >= 200:
            return 70
        elif count >= 100:
            return 50
        elif count >= 50:
            return 35
        else:
            return 20

    def _engagement_to_score(self, avg_score: float) -> float:
        """Convert engagement score to FOMO score."""
        if avg_score >= 1000:
            return 85  # Viral posts
        elif avg_score >= 500:
            return 70
        elif avg_score >= 200:
            return 50
        elif avg_score >= 50:
            return 30
        else:
            return 15

    def _galaxy_score_to_fomo(self, score: float) -> float:
        """Convert LunarCrush galaxy score to FOMO score."""
        # Galaxy score is 0-100, higher = more social activity
        if score >= 80:
            return 90  # Maximum hype
        elif score >= 60:
            return 70
        elif score >= 40:
            return 45
        else:
            return 20

    def _describe_galaxy_score(self, score: float) -> str:
        """Describe galaxy score."""
        if score >= 80:
            return f"Galaxy Score {score:.0f} - extreme social hype"
        elif score >= 60:
            return f"Galaxy Score {score:.0f} - high social activity"
        elif score >= 40:
            return f"Galaxy Score {score:.0f} - moderate activity"
        else:
            return f"Galaxy Score {score:.0f} - low social activity"

    def _volume_change_to_score(self, change: float) -> float:
        """Convert social volume change to FOMO score."""
        if change >= 100:
            return 95  # Doubling = extreme hype
        elif change >= 50:
            return 80
        elif change >= 25:
            return 60
        elif change >= 0:
            return 35
        else:
            return 15  # Declining interest

    def _lc_sentiment_to_score(self, sentiment: float) -> float:
        """Convert LunarCrush sentiment (0-100) to FOMO score."""
        if sentiment >= 80:
            return 90
        elif sentiment >= 65:
            return 70
        elif sentiment >= 50:
            return 45
        elif sentiment >= 35:
            return 25
        else:
            return 10

    def _describe_lc_sentiment(self, sentiment: float) -> str:
        """Describe LunarCrush sentiment."""
        if sentiment >= 80:
            return f"Sentiment {sentiment:.0f}/100 - extremely bullish"
        elif sentiment >= 65:
            return f"Sentiment {sentiment:.0f}/100 - bullish"
        elif sentiment >= 50:
            return f"Sentiment {sentiment:.0f}/100 - neutral-bullish"
        elif sentiment >= 35:
            return f"Sentiment {sentiment:.0f}/100 - neutral-bearish"
        else:
            return f"Sentiment {sentiment:.0f}/100 - bearish"

    def _generate_summary(
        self, score: float, indicators: list[SignalIndicator]
    ) -> str:
        """Generate summary of social signals."""
        if not indicators:
            return "No social signals available"

        high_risk = [i for i in indicators if i.score >= 70]
        if high_risk:
            names = ", ".join(i.name for i in high_risk[:2])
            return f"High social FOMO signals: {names}"
        elif score >= 50:
            return "Elevated social activity - increased attention on this coin"
        else:
            return "Social signals appear normal"
