"""
config_schema.py — env 설정 키 → 테이블 분류 (전략별 config_* + 공통 env_config)

테이블 명명: config_{전략}  (config_scalp, config_short, …)
공통(API·MM·인프라): env_config

기존 ENV_CONFIG_KEYS 전체는 get_merged_env_snapshot() 으로 flat dict 유지 (하위 호환).
"""
from __future__ import annotations

from typing import Dict, Iterable, List, Tuple

# (테이블명, 전략 ID — 로그/문서용)
CONFIG_TABLE_NAMES: Tuple[str, ...] = (
    "env_config",
    "config_scalp",
    "config_short",
    "config_momentum",
    "config_breakout",
    "config_range_break",
    "config_updow",
    "config_dbband",
)

STRATEGY_ID_TO_TABLE: Dict[str, str] = {
    "SCALP": "config_scalp",
    "SHORT": "config_short",
    "MOMENTUM": "config_momentum",
    "BREAKOUT": "config_breakout",
    "RANGE_BREAK": "config_range_break",
    "UPDOW": "config_updow",
    "DBBAND": "config_dbband",
}

# 전략 ON/OFF · MM alias — 접두어 규칙 예외 없이 전략 테이블에만 저장
_EXPLICIT_KEY_TABLE: Dict[str, str] = {
    "STRATEGY_SCALP_ENABLED": "config_scalp",
    "STRATEGY_SHORT_ENABLED": "config_short",
    "STRATEGY_MOMENTUM_ENABLED": "config_momentum",
    "STRATEGY_BREAKOUT_ENABLED": "config_breakout",
    "STRATEGY_RANGE_BREAK_ENABLED": "config_range_break",
    "STRATEGY_UPDOW_ENABLED": "config_updow",
    "STRATEGY_DBBAND_ENABLED": "config_dbband",
    "KIS_SCALP_MM_CHANNEL": "config_scalp",
    "KIS_SHORT_MM_CHANNEL": "config_short",
    "KIS_MOMENTUM_MM_CHANNEL": "config_momentum",
    "KIS_BREAKOUT_MM_CHANNEL": "config_breakout",
    "KIS_RANGE_BREAK_MM_CHANNEL": "config_range_break",
    "KIS_UPDOW_MM_CHANNEL": "config_updow",
    "KIS_DBBAND_MM_CHANNEL": "config_dbband",
}

# 꼬리 오케스트레이터(SHORT strategy_id) — TAIL_* 와 분리
_SHORT_ORCHESTRATOR_KEYS = frozenset({
    "SHORT_GAP_FILL_LIMIT",
    "SHORT_LIVE_BACKTEST_ALIGN",
    "SHORT_LIVE_SIGNAL_LOOKBACK_BARS",
    "SHORT_UNIVERSE_SOURCE",
    "RANK_SHORT_SORT",
    "RANK_SHORT_LIMIT",
    "CONDITION_SHORT_NAME",
    "CONDITION_SHORT_SEQ",
    "SHORT_CAND_LIMIT",
    "KIS_SHORT_MM_CHANNEL",
})

# 익절 호가 — 실행 공통이지만 SHORT 튜닝과 함께 둠
_SHORT_EXEC_KEYS = frozenset({
    "SELL_USE_ORDERBOOK_ON_PROFIT",
    "SELL_ORDERBOOK_BID_LEVELS",
    "SELL_ORDERBOOK_DEPTH_MULT",
})


def classify_config_key(key: str) -> str:
    """설정 키가 들어갈 테이블명 반환."""
    k = (key or "").strip()
    if not k:
        return "env_config"

    explicit = _EXPLICIT_KEY_TABLE.get(k)
    if explicit:
        return explicit

    if k in _SHORT_ORCHESTRATOR_KEYS or k in _SHORT_EXEC_KEYS:
        return "config_short"
    if k.startswith("UPDOW_") or k == "MIN_CANDLE_LEN_UPDOW":
        return "config_updow"
    if k.startswith("DBBAND_"):
        return "config_dbband"
    if k.startswith("BREAKOUT_"):
        return "config_breakout"
    if k.startswith("RANGE_BREAK_"):
        return "config_range_break"
    if k.startswith("MOMENTUM_"):
        return "config_momentum"
    if k.startswith("SCALP_"):
        return "config_scalp"
    if k.startswith("SHORT_") or k.startswith("TAIL_") or k.startswith("SHOULDER"):
        return "config_short"
    if k.startswith("STOP_ATR") or k.startswith("TARGET_ATR"):
        return "config_short"

    if k.startswith("RANK_UPDOW_") or k.startswith("CONDITION_UPDOW"):
        return "config_updow"
    if k.startswith("RANK_DBBAND_") or k.startswith("CONDITION_DBBAND"):
        return "config_dbband"
    if k.startswith("RANK_BREAKOUT_") or k.startswith("CONDITION_BREAKOUT"):
        return "config_breakout"
    if k.startswith("RANK_RANGE_BREAK_") or k.startswith("CONDITION_RANGE_BREAK"):
        return "config_range_break"
    if k.startswith("RANK_MOMENTUM_") or k.startswith("CONDITION_MOMENTUM"):
        return "config_momentum"
    if k.startswith("RANK_SCALP_") or k.startswith("CONDITION_SCALP"):
        return "config_scalp"
    if k.startswith("RANK_SHORT_") or k.startswith("CONDITION_SHORT"):
        return "config_short"

    return "env_config"


def split_env_keys(all_keys: Iterable[str]) -> Dict[str, Tuple[str, ...]]:
    """키 목록을 테이블별 튜플로 분류."""
    buckets: Dict[str, List[str]] = {t: [] for t in CONFIG_TABLE_NAMES}
    for key in all_keys:
        tbl = classify_config_key(key)
        if tbl not in buckets:
            tbl = "env_config"
        buckets[tbl].append(key)
    return {t: tuple(buckets[t]) for t in CONFIG_TABLE_NAMES}


def build_config_schema(all_keys: Tuple[str, ...]) -> Dict[str, Tuple[str, ...]]:
    """ENV_CONFIG_KEYS 로부터 테이블별 키 튜플 생성."""
    return split_env_keys(all_keys)
