#!/usr/bin/env python3
"""#15 — Chain Comparability Index. Compare tokens across chains: price, liquidity,
volume, tx count. Detect arbitrage and inflated-volume scams."""

import os

import httpx
from fastapi import APIRouter, Query
from pydantic import BaseModel

router = APIRouter(prefix="/api/v1/chain-compare", tags=["chain-comparability"])

BACKEND = os.environ.get("BACKEND_URL", "http://localhost:8000")
DEXSCREENER = "https://api.dexscreener.com/latest/dex/search"

CHAINS = ["ethereum", "bsc", "base", "arbitrum", "polygon", "avalanche", "optimism", "solana"]


class CrossChainListing(BaseModel):
    chain: str
    price_usd: float
    liquidity_usd: float
    volume_24h: float
    volume_liq_ratio: float = 0
    tx_count_24h: int = 0
    dex: str
    age_days: int = 0
    suspicious: bool = False
    suspicion_reason: str = ""


async def _get_token_chain_listings(symbol: str) -> list[dict]:
    """Find the same token across multiple chains via DexScreener."""
    listings: list[dict] = []
    try:
        async with httpx.AsyncClient(timeout=10) as client:
            resp = await client.get(f"{DEXSCREENER}?q={symbol}")
            if resp.status_code != 200:
                return listings
            pairs = resp.json().get("pairs", [])
            for p in pairs[:50]:
                chain_id = p.get("chainId", "unknown")
                if chain_id in CHAINS or chain_id == "solana":
                    listings.append(
                        {
                            "chain": chain_id,
                            "price_usd": float(p.get("priceUsd", 0) or 0),
                            "liquidity_usd": p.get("liquidity", {}).get("usd", 0) or 0,
                            "volume_24h": float(p.get("volume", {}).get("h24", 0) or 0),
                            "tx_count_24h": p.get("txns", {}).get("h24", {}).get("buys", 0)
                            + p.get("txns", {}).get("h24", {}).get("sells", 0),
                            "dex": p.get("dexId", "?"),
                            "pair_created": p.get("pairCreatedAt", 0),
                        }
                    )
    except Exception:
        pass
    return listings


def _detect_suspicious(listings: list[dict]) -> list[dict]:
    """Flag suspicious listings: inflated volume, price disconnects."""
    if len(listings) < 2:
        return listings

    avg_vol_liq = sum(line.get("volume_24h", 0) / max(line.get("liquidity_usd", 1), 1) for line in listings) / len(listings)
    avg_price = sum(line["price_usd"] for line in listings if line["price_usd"] > 0) / max(
        len([line for line in listings if line["price_usd"] > 0]), 1
    )

    for line in listings:
        v_ratio = line.get("volume_24h", 0) / max(line.get("liquidity_usd", 1), 1)
        line["volume_liq_ratio"] = round(v_ratio, 2)

        if v_ratio > avg_vol_liq * 3:
            line["suspicious"] = True
            line["suspicion_reason"] = "Inflated volume vs liquidity"

        if line["price_usd"] > 0 and avg_price > 0:
            price_dev = abs(line["price_usd"] - avg_price) / avg_price
            if price_dev > 0.5:
                line["suspicious"] = True
                existing = line.get("suspicion_reason", "")
                line["suspicion_reason"] = (
                    existing + "; " if existing else ""
                ) + f"Price disconnect ({price_dev:.0%} off average)"

    return listings


@router.get("/token/{symbol}")
async def compare_token_chains(symbol: str):
    """Compare a token's listings across all chains. Flags suspicious activity."""
    listings = await _get_token_chain_listings(symbol)
    listings = _detect_suspicious(listings)

    suspicious = [line for line in listings if line.get("suspicious")]
    chains_active = len({line["chain"] for line in listings})

    return {
        "symbol": symbol,
        "chains_active": chains_active,
        "total_listings": len(listings),
        "suspicious_listings": len(suspicious),
        "listings": listings,
        "summary": (
            f"{symbol} trades on {chains_active} chains with {len(listings)} DEX listings. "
            f"{len(suspicious)} listings show suspicious patterns."
        ),
    }


@router.get("/arbitrage")
async def find_arbitrage_opportunities(
    min_discrepancy: float = Query(2.0, ge=0.5, description="Minimum % price difference"),
    limit: int = Query(10, le=25),
):
    """Find tokens with large price discrepancies across chains (arbitrage signals)."""
    # Scan top tokens for price discrepancies
    opportunities: list[dict] = []
    popular = ["ETH", "USDC", "USDT", "MATIC", "ARB", "OP", "LINK", "UNI", "AAVE", "SNX"]

    for symbol in popular[:8]:
        listings = await _get_token_chain_listings(symbol)
        prices = [(line["chain"], line["price_usd"]) for line in listings if line["price_usd"] > 0]
        if len(prices) >= 2:
            prices.sort(key=lambda x: x[1])
            low_chain, low_price = prices[0]
            high_chain, high_price = prices[-1]
            if low_price > 0:
                discrepancy = ((high_price - low_price) / low_price) * 100
                if discrepancy > min_discrepancy:
                    opportunities.append(
                        {
                            "symbol": symbol,
                            "lowest": {"chain": low_chain, "price": low_price},
                            "highest": {"chain": high_chain, "price": high_price},
                            "discrepancy_pct": round(discrepancy, 2),
                        }
                    )

    opportunities.sort(key=lambda o: o["discrepancy_pct"], reverse=True)
    return {"opportunities": opportunities[:limit], "scan_time": "realtime"}
