from __future__ import annotations

from dataclasses import dataclass
from typing import Mapping

from config import BotConfig

STABLE_OR_INDEX_NAMES = {
    "USDC", "USDT", "DAI", "TUSD", "USDP", "FRAX", "USDE", "FDUSD", "PYUSD", "USD", "STABLE"
}


@dataclass(frozen=True)
class MarketUniverseFilter:
    cfg: BotConfig

    def allowed(self, coin: str, volume_24h: float) -> bool:
        symbol = str(coin).upper().strip()
        if not symbol or symbol.startswith("@"):
            return False
        if not symbol.replace("-", "").replace("_", "").isalnum():
            return False
        if symbol in STABLE_OR_INDEX_NAMES:
            return False
        if symbol in self.cfg.blacklist:
            return False
        if self.cfg.allowed_coins and symbol not in self.cfg.allowed_coins:
            return False
        return float(volume_24h or 0.0) >= float(self.cfg.min_volume_24h)


def select_scan_coins(volumes: Mapping[str, float], cfg: BotConfig) -> list[str]:
    filt = MarketUniverseFilter(cfg)
    allowed = [
        (str(coin).upper(), float(volume or 0.0))
        for coin, volume in volumes.items()
        if filt.allowed(str(coin), float(volume or 0.0))
    ]
    allowed.sort(key=lambda item: (-item[1], item[0]))
    return [coin for coin, _ in allowed[: int(cfg.max_scan_coins)]]
