"""On-chain signal analysis."""

from typing import Any

from .base import Signal, SignalCategory, SignalIndicator, SignalResult


class OnChainSignal(Signal):
    """Analyze on-chain signals for FOMO detection."""

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

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

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

        # Glassnode analysis
        glassnode_data = data.get("glassnode", {})
        if glassnode_data:
            gn_indicators = self._analyze_glassnode(glassnode_data)
            indicators.extend(gn_indicators)

        # Etherscan analysis (for ETH)
        etherscan_data = data.get("etherscan", {})
        if etherscan_data:
            eth_indicators = self._analyze_etherscan(etherscan_data)
            indicators.extend(eth_indicators)

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

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

        return self._create_result(indicators, summary)

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

        # Exchange netflow (positive = inflow = selling pressure)
        netflow = data.get("exchange_netflow")
        if netflow is not None:
            score = self._netflow_to_score(netflow)
            indicators.append(
                SignalIndicator(
                    name="Exchange Netflow",
                    value=netflow,
                    score=score,
                    description=self._describe_netflow(netflow),
                    raw_value=netflow,
                )
            )

        # Whale transactions
        whale_count = data.get("whale_transactions_count")
        if whale_count is not None:
            score = self._whale_activity_to_score(whale_count)
            indicators.append(
                SignalIndicator(
                    name="Whale Activity",
                    value=whale_count,
                    score=score,
                    description=f"{whale_count} large transactions (>$100k) in 24h",
                    raw_value=whale_count,
                )
            )

        # Supply in profit (high = potential selling)
        supply_profit = data.get("supply_in_profit_percent")
        if supply_profit is not None:
            score = self._supply_profit_to_score(supply_profit)
            indicators.append(
                SignalIndicator(
                    name="Supply in Profit",
                    value=supply_profit * 100,
                    score=score,
                    description=self._describe_supply_profit(supply_profit),
                    raw_value=supply_profit,
                )
            )

        # Active addresses (network activity)
        active = data.get("active_addresses_24h")
        if active is not None:
            score = self._address_activity_to_score(active)
            indicators.append(
                SignalIndicator(
                    name="Active Addresses",
                    value=active,
                    score=score,
                    description=f"{active:,} active addresses in 24h",
                    raw_value=active,
                )
            )

        # New addresses (new buyers)
        new_addrs = data.get("new_addresses_24h")
        if new_addrs is not None:
            score = self._new_addresses_to_score(new_addrs)
            indicators.append(
                SignalIndicator(
                    name="New Addresses",
                    value=new_addrs,
                    score=score,
                    description=self._describe_new_addresses(new_addrs),
                    raw_value=new_addrs,
                )
            )

        return indicators

    def _analyze_etherscan(self, data: dict[str, Any]) -> list[SignalIndicator]:
        """Analyze Etherscan metrics."""
        indicators = []

        # Gas prices (high gas = high network activity/FOMO)
        gas_price = data.get("gas_price_gwei")
        if gas_price is not None:
            score = self._gas_price_to_score(gas_price)
            indicators.append(
                SignalIndicator(
                    name="Gas Price",
                    value=gas_price,
                    score=score,
                    description=self._describe_gas_price(gas_price),
                    raw_value=gas_price,
                )
            )

        return indicators

    def _netflow_to_score(self, netflow: float) -> float:
        """Convert exchange netflow to FOMO score."""
        # Positive netflow = coins moving to exchanges = potential selling
        # This is actually a warning sign, not FOMO per se
        # High inflow during price pump = distribution phase
        if netflow > 10000:  # Significant inflow
            return 85  # High risk - whales moving to exchanges
        elif netflow > 1000:
            return 65
        elif netflow > 0:
            return 45
        elif netflow > -1000:
            return 30  # Slight outflow - accumulation
        else:
            return 15  # Strong outflow - heavy accumulation

    def _describe_netflow(self, netflow: float) -> str:
        """Describe exchange netflow."""
        if netflow > 10000:
            return f"High exchange inflow ({netflow:,.0f}) - potential distribution"
        elif netflow > 1000:
            return f"Moderate exchange inflow ({netflow:,.0f})"
        elif netflow > 0:
            return f"Slight exchange inflow ({netflow:,.0f})"
        elif netflow > -1000:
            return f"Slight exchange outflow ({abs(netflow):,.0f}) - accumulation"
        else:
            return f"Strong exchange outflow ({abs(netflow):,.0f}) - heavy accumulation"

    def _whale_activity_to_score(self, count: int) -> float:
        """Convert whale transaction count to FOMO score."""
        # High whale activity during pump = smart money may be distributing
        if count >= 500:
            return 85
        elif count >= 200:
            return 65
        elif count >= 100:
            return 50
        elif count >= 50:
            return 35
        else:
            return 20

    def _supply_profit_to_score(self, profit_pct: float) -> float:
        """Convert supply in profit percentage to FOMO score."""
        # When most supply is in profit, there's sell pressure
        # This is a classic top indicator
        if profit_pct >= 0.95:
            return 95  # 95%+ in profit = extreme risk
        elif profit_pct >= 0.90:
            return 80
        elif profit_pct >= 0.80:
            return 60
        elif profit_pct >= 0.60:
            return 40
        else:
            return 20  # Lower profit = better entry

    def _describe_supply_profit(self, profit_pct: float) -> str:
        """Describe supply in profit."""
        pct = profit_pct * 100
        if profit_pct >= 0.95:
            return f"{pct:.0f}% of supply in profit - extreme sell pressure risk"
        elif profit_pct >= 0.90:
            return f"{pct:.0f}% of supply in profit - high sell pressure risk"
        elif profit_pct >= 0.80:
            return f"{pct:.0f}% of supply in profit - moderate risk"
        elif profit_pct >= 0.60:
            return f"{pct:.0f}% of supply in profit - balanced"
        else:
            return f"{pct:.0f}% of supply in profit - potential accumulation zone"

    def _address_activity_to_score(self, count: int) -> float:
        """Convert active address count to FOMO score."""
        # This is highly asset-dependent, using BTC-like thresholds
        if count >= 1000000:
            return 75  # Very high activity
        elif count >= 500000:
            return 55
        elif count >= 200000:
            return 40
        else:
            return 25

    def _new_addresses_to_score(self, count: int) -> float:
        """Convert new address count to FOMO score."""
        # New addresses = new buyers entering
        # Spike in new addresses during pump = retail FOMO
        if count >= 100000:
            return 90  # Massive new buyer influx
        elif count >= 50000:
            return 70
        elif count >= 20000:
            return 50
        elif count >= 10000:
            return 35
        else:
            return 20

    def _describe_new_addresses(self, count: int) -> str:
        """Describe new address activity."""
        if count >= 100000:
            return f"{count:,} new addresses - massive retail influx (FOMO indicator)"
        elif count >= 50000:
            return f"{count:,} new addresses - significant new buyer activity"
        elif count >= 20000:
            return f"{count:,} new addresses - elevated new interest"
        else:
            return f"{count:,} new addresses - normal activity"

    def _gas_price_to_score(self, gwei: float) -> float:
        """Convert gas price to FOMO score."""
        # High gas = high network demand = potential FOMO
        if gwei >= 200:
            return 90  # Extreme congestion
        elif gwei >= 100:
            return 70
        elif gwei >= 50:
            return 50
        elif gwei >= 20:
            return 30
        else:
            return 15  # Low activity

    def _describe_gas_price(self, gwei: float) -> str:
        """Describe gas price."""
        if gwei >= 200:
            return f"Gas {gwei:.0f} gwei - extreme network congestion"
        elif gwei >= 100:
            return f"Gas {gwei:.0f} gwei - high network activity"
        elif gwei >= 50:
            return f"Gas {gwei:.0f} gwei - elevated activity"
        elif gwei >= 20:
            return f"Gas {gwei:.0f} gwei - normal activity"
        else:
            return f"Gas {gwei:.0f} gwei - low activity"

    def _generate_summary(
        self, score: float, indicators: list[SignalIndicator]
    ) -> str:
        """Generate summary of on-chain signals."""
        if not indicators:
            return "No on-chain 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"On-chain warning signals: {names}"
        elif score >= 50:
            return "On-chain metrics show elevated activity"
        else:
            return "On-chain metrics appear healthy"
