# source: https://raw.githubusercontent.com/BruceMong/crypto-ai/3fac80b74f0495fa6b55c04846850ebd999675ff/freqtrade/user_data/strategies/helpers/symbol_config.py
# directory_url: https://github.com/BruceMong/crypto-ai/blob/main/freqtrade/user_data/strategies/helpers/
# User: BruceMong
# Repository: crypto-ai
# --------------------"""
Symbol Configuration Manager
============================

Manages per-symbol configuration overrides for Freqtrade strategies.

MIGRATION NOTE: This module maps to per_symbol section in config/config.yaml

Usage in strategy:
    from helpers.symbol_config import SymbolConfigManager

    class Github_BruceMong_crypto_ai__symbol_config__20260730_182353(IStrategy):
        def __init__(self, config):
            super().__init__(config)
            self.symbol_mgr = SymbolConfigManager.from_freqtrade_config(config)

        def populate_entry_trend(self, dataframe, metadata):
            symbol_cfg = self.symbol_mgr.get_config(metadata['pair'])
            # Use symbol_cfg['rsi_long_max'], etc.
"""

from typing import Dict, Any, Optional, List
import logging

logger = logging.getLogger(__name__)


class SymbolConfigManager:
    """
    Manager for per-symbol configuration overrides.

    MIGRATION FROM config/config.yaml > per_symbol section:
    Each symbol can have custom settings for:
    - Entry method selection (use_trend_entry, use_breakout_entry)
    - Indicator parameters (breakout_n, etc.)
    - Filter thresholds (min_ma_distance_pct, rsi_long_max)
    - Debug mode (debug_always_entry)
    """

    # Default configuration applied to all symbols
    DEFAULT_CONFIG: Dict[str, Any] = {
        # Entry methods
        "use_trend_entry": True,
        "use_breakout_entry": True,
        "entry_method": "TREND",  # Legacy single method

        # Indicator parameters
        "breakout_n": 20,
        "breakout_buffer_pct": 0.0,

        # Filter thresholds (None = use global setting)
        "min_ma_distance_pct": None,
        "rsi_long_max": None,

        # Debug
        "debug_always_entry": False,
    }

    def __init__(self, per_symbol_config: Optional[Dict[str, Dict[str, Any]]] = None):
        """
        Initialize with per-symbol configurations.

        Args:
            per_symbol_config: Dict mapping pair names to config overrides
                Example: {"SOL/USDT": {"use_trend_entry": False}}
        """
        self._per_symbol = per_symbol_config or {}

        # Normalize pair names (convert SOLUSDT to SOL/USDT format if needed)
        self._normalized = {}
        for pair, cfg in self._per_symbol.items():
            normalized = self._normalize_pair_name(pair)
            self._normalized[normalized] = cfg

        logger.info(f"[SYMBOL_CONFIG] Loaded {len(self._normalized)} per-symbol configs")

    @classmethod
    def from_freqtrade_config(cls, config: Dict[str, Any]) -> 'SymbolConfigManager':
        """
        Create manager from Freqtrade config.

        Looks for 'per_symbol' key in config, falling back to empty dict.

        Args:
            config: Freqtrade configuration dict

        Returns:
            SymbolConfigManager instance
        """
        per_symbol = config.get('per_symbol', {})
        return cls(per_symbol)

    @classmethod
    def from_yaml_config(cls, yaml_config: Dict[str, Any]) -> 'SymbolConfigManager':
        """
        Create manager from original YAML config format.

        MIGRATION: Reads from config/config.yaml format

        Args:
            yaml_config: Loaded YAML configuration dict

        Returns:
            SymbolConfigManager instance
        """
        per_symbol = yaml_config.get('per_symbol', {})

        # Convert from YAML format (nested indicators) to flat format
        converted = {}
        for symbol, symbol_cfg in per_symbol.items():
            flat_cfg = {}

            # Extract indicator settings
            indicators = symbol_cfg.get('indicators', {})
            flat_cfg.update(indicators)

            # Extract trade settings
            trade = symbol_cfg.get('trade', {})
            flat_cfg.update(trade)

            converted[symbol] = flat_cfg

        return cls(converted)

    def _normalize_pair_name(self, pair: str) -> str:
        """
        Normalize pair name to Freqtrade format (BASE/QUOTE).

        Converts: SOLUSDT -> SOL/USDT
        Keeps: SOL/USDT -> SOL/USDT

        Args:
            pair: Pair name in any format

        Returns:
            Normalized pair name
        """
        # Already in correct format
        if '/' in pair:
            return pair.upper()

        # Common quote currencies
        quotes = ['USDT', 'USDC', 'USD', 'BTC', 'ETH', 'BNB', 'EUR']

        for quote in quotes:
            if pair.upper().endswith(quote):
                base = pair.upper()[:-len(quote)]
                return f"{base}/{quote}"

        # Couldn't normalize, return as-is
        logger.warning(f"[SYMBOL_CONFIG] Could not normalize pair name: {pair}")
        return pair.upper()

    def get_config(self, pair: str) -> Dict[str, Any]:
        """
        Get configuration for a specific pair.

        Merges default config with per-symbol overrides.

        Args:
            pair: Trading pair (e.g., "SOL/USDT")

        Returns:
            Complete configuration dict for the pair
        """
        normalized = self._normalize_pair_name(pair)

        # Start with defaults
        config = dict(self.DEFAULT_CONFIG)

        # Apply per-symbol overrides
        if normalized in self._normalized:
            symbol_overrides = self._normalized[normalized]
            for key, value in symbol_overrides.items():
                if value is not None:  # Only override if explicitly set
                    config[key] = value

        return config

    def get_entry_methods(self, pair: str) -> List[str]:
        """
        Get enabled entry methods for a pair.

        MIGRATION: Maps to entry_methods/entry_method in config.yaml

        Args:
            pair: Trading pair

        Returns:
            List of enabled entry methods (e.g., ["TREND", "BREAKOUT_N"])
        """
        cfg = self.get_config(pair)

        methods = []
        if cfg.get('use_trend_entry', True):
            methods.append('TREND')
        if cfg.get('use_breakout_entry', True):
            methods.append('BREAKOUT_N')

        # Fallback to legacy single method
        if not methods:
            legacy = cfg.get('entry_method', 'TREND')
            methods.append(legacy.upper())

        return methods

    def is_debug_mode(self, pair: str) -> bool:
        """
        Check if debug mode is enabled for a pair.

        MIGRATION: Maps to debug_always_entry in config.yaml

        Args:
            pair: Trading pair

        Returns:
            True if debug mode is enabled
        """
        cfg = self.get_config(pair)
        return cfg.get('debug_always_entry', False)

    def get_filter_thresholds(self, pair: str) -> Dict[str, Optional[float]]:
        """
        Get filter thresholds for a pair.

        MIGRATION: Maps to min_ma_distance_pct, rsi_long_max in config.yaml

        Args:
            pair: Trading pair

        Returns:
            Dict with filter thresholds (None means use global default)
        """
        cfg = self.get_config(pair)
        return {
            'min_ma_distance_pct': cfg.get('min_ma_distance_pct'),
            'rsi_long_max': cfg.get('rsi_long_max'),
        }

    def list_configured_pairs(self) -> List[str]:
        """
        List all pairs with custom configurations.

        Returns:
            List of pair names with overrides
        """
        return list(self._normalized.keys())

    def __repr__(self) -> str:
        return f"SymbolConfigManager({len(self._normalized)} pairs configured)"


# ==========================================================================
# PRE-CONFIGURED SYMBOL CONFIGS (from your config.yaml)
# ==========================================================================

# These match your per_symbol section in config/config.yaml
# You can import and use these directly or modify as needed

PRECONFIGURED_SYMBOLS: Dict[str, Dict[str, Any]] = {
    # SOL/USDT: Use only BREAKOUT_N method
    "SOL/USDT": {
        "use_trend_entry": False,
        "use_breakout_entry": True,
        "entry_method": "BREAKOUT_N",
        "breakout_n": 20,
        "breakout_buffer_pct": 0.0,
        "debug_always_entry": False,
    },

    # DOGE/USDT: Debug mode enabled (for testing)
    "DOGE/USDT": {
        "use_trend_entry": True,
        "use_breakout_entry": True,
        "debug_always_entry": True,  # Set to False for production
    },

    # PEPE/USDT: Stricter filters for meme coin
    "PEPE/USDT": {
        "use_trend_entry": True,
        "use_breakout_entry": True,
        "debug_always_entry": True,  # Set to False for production
        "min_ma_distance_pct": 0.01,  # 1% minimum MA distance
        "rsi_long_max": 50,           # Block entry if RSI > 50
    },

    # SHIB/USDT: Even stricter filters for meme coin
    "SHIB/USDT": {
        "use_trend_entry": True,
        "use_breakout_entry": True,
        "debug_always_entry": True,  # Set to False for production
        "min_ma_distance_pct": 0.01,  # 1% minimum MA distance
        "rsi_long_max": 45,           # Block entry if RSI > 45
    },
}


def get_default_symbol_manager() -> SymbolConfigManager:
    """
    Get a SymbolConfigManager with pre-configured symbols.

    Returns:
        SymbolConfigManager with your original per_symbol settings
    """
    return SymbolConfigManager(PRECONFIGURED_SYMBOLS)
