"""
Free Threat Intelligence Feeds — CryptoScamDB, GoPlus, Januus.
Paper ref: Article 3, Section 2 & Section 6 — Free Datasets and APIs.
"""

import logging

import httpx

logger = logging.getLogger(__name__)


class ThreatIntelFeeds:
    """Aggregates free threat intelligence from multiple open sources."""

    def __init__(self):
        self._scamdb_cache: dict[str, dict] = {}
        self._goplus_cache: dict[str, dict] = {}

    # ── CryptoScamDB integration ──────────────────────────

    async def check_cryptoscamdb(self, address: str) -> dict | None:
        """Check if address is in CryptoScamDB (MIT-licensed, free)."""
        if address in self._scamdb_cache:
            return self._scamdb_cache[address]

        try:
            # CryptoScamDB API — free, no auth required
            url = f"https://api.cryptoscamdb.org/v1/check/{address}"
            async with httpx.AsyncClient(timeout=8.0) as client:
                r = await client.get(url)
                if r.status_code == 200:
                    data = r.json()
                    result = {
                        "address": address,
                        "is_scam": data.get("success", False),
                        "entries": data.get("result", {}).get("entries", [])[:5],
                        "source": "cryptoscamdb",
                    }
                    self._scamdb_cache[address] = result
                    return result
        except Exception as e:
            logger.debug(f"CryptoScamDB check failed: {e}")

        self._scamdb_cache[address] = None
        return None

    # ── GoPlus Security API ───────────────────────────────

    async def check_goplus(self, chain_id: str, address: str) -> dict | None:
        """GoPlus token security check (free, multi-chain)."""
        cache_key = f"{chain_id}:{address}"
        if cache_key in self._goplus_cache:
            return self._goplus_cache[cache_key]

        try:
            url = f"https://api.gopluslabs.io/api/v1/token_security/{chain_id}"
            async with httpx.AsyncClient(timeout=10.0) as client:
                r = await client.get(url, params={"contract_addresses": address})
                if r.status_code == 200:
                    result = r.json().get("result", {}).get(address.lower(), {})
                    if result:
                        data = {
                            "address": address,
                            "chain": chain_id,
                            "is_honeypot": result.get("is_honeypot") == "1",
                            "can_take_back_ownership": result.get("can_take_back_ownership") == "1",
                            "is_open_source": result.get("is_open_source") != "0",
                            "is_blacklisted": result.get("is_blacklisted") == "1",
                            "buy_tax": float(result.get("buy_tax", "0")),
                            "sell_tax": float(result.get("sell_tax", "0")),
                            "is_mintable": result.get("is_mintable") == "1",
                            "is_proxy": result.get("is_proxy") == "1",
                            "source": "goplus",
                        }
                        # Calculate risk
                        score = 0
                        if data["is_honeypot"]:
                            score += 50
                        if data["can_take_back_ownership"]:
                            score += 20
                        if not data["is_open_source"]:
                            score += 15
                        if data["is_blacklisted"]:
                            score += 40
                        if data["buy_tax"] > 10:
                            score += 15
                        if data["sell_tax"] > 10:
                            score += 15
                        data["risk_score"] = min(100, score)
                        self._goplus_cache[cache_key] = data
                        return data
        except Exception as e:
            logger.debug(f"GoPlus check failed: {e}")

        self._goplus_cache[cache_key] = None
        return None

    # ── Januus Free Risk Scores ───────────────────────────

    async def check_januus(self, address: str) -> dict | None:
        """Januus free risk score (open-source, no license fee)."""
        try:
            url = f"https://api.januus.io/v1/risk/{address}"
            async with httpx.AsyncClient(timeout=8.0) as client:
                r = await client.get(url)
                if r.status_code == 200:
                    data = r.json()
                    return {
                        "address": address,
                        "risk_score": data.get("risk_score", 0),
                        "risk_level": data.get("risk_level", "unknown"),
                        "source": "januus",
                    }
        except Exception as e:
            logger.debug(f"Januus check failed: {e}")
        return None

    # ── Combined multi-source check ───────────────────────

    async def full_check(self, address: str, chain_id: str = "1") -> dict:
        """Run all free threat intel checks against an address."""
        results = {
            "address": address,
            "sources_checked": 0,
            "any_scam_flag": False,
            "findings": [],
        }

        # CryptoScamDB
        csdb = await self.check_cryptoscamdb(address)
        if csdb and csdb.get("is_scam"):
            results["any_scam_flag"] = True
            results["findings"].append(
                {
                    "source": "cryptoscamdb",
                    "severity": "high",
                    "detail": f"Found in CryptoScamDB with {len(csdb.get('entries', []))} entries",
                }
            )
        results["sources_checked"] += 1

        # GoPlus (for contract addresses)
        if len(address) > 30:  # Looks like a contract/token address
            goplus = await self.check_goplus(chain_id, address)
            if goplus:
                results["sources_checked"] += 1
                if goplus.get("is_honeypot"):
                    results["any_scam_flag"] = True
                    results["findings"].append(
                        {"source": "goplus", "severity": "critical", "detail": "Honeypot detected"}
                    )
                if goplus.get("risk_score", 0) > 50:
                    results["findings"].append(
                        {
                            "source": "goplus",
                            "severity": "high",
                            "detail": f"GoPlus risk score: {goplus['risk_score']}/100",
                        }
                    )

        # Januus
        januus = await self.check_januus(address)
        if januus and januus.get("risk_score", 0) > 50:
            results["sources_checked"] += 1
            results["any_scam_flag"] = True
            results["findings"].append(
                {
                    "source": "januus",
                    "severity": "medium",
                    "detail": f"Januus risk: {januus['risk_score']}/{januus.get('risk_level', '?')}",
                }
            )

        return results


# Singleton
_feeds: ThreatIntelFeeds | None = None


def get_threat_feeds() -> ThreatIntelFeeds:
    global _feeds
    if _feeds is None:
        _feeds = ThreatIntelFeeds()
    return _feeds
