"""
kis_trader/engine/ema_trend_filter.py — EMA 추세 필터 (모멘텀/돌파 TRIGGER 공통)
==============================================================================
SCAN 단계가 아닌 **매수 직전(TRIGGER)** 에만 적용.

조건 (필터 ON 시):
  1) 종가 > EMA(fast)
  2) EMA(fast) > EMA(slow)

기본 OFF → 기존 백테·실매 동작 100% 유지.
"""
from __future__ import annotations

from typing import List, Optional, Tuple


def compute_ema_series(values: List[float], period: int) -> List[Optional[float]]:
    """지수이동평균(EMA) 시리즈. 초기값은 SMA (scalping_engine._ema_series 와 동일 철학)."""
    n = len(values)
    out: List[Optional[float]] = [None] * n
    if period <= 0 or n < period:
        return out
    mult = 2.0 / (period + 1)
    ema = sum(values[:period]) / period
    out[period - 1] = ema
    for i in range(period, n):
        ema = (values[i] - ema) * mult + ema
        out[i] = ema
    return out


def _to_bool(v: object, default: bool = False) -> bool:
    if v is None:
        return default
    if isinstance(v, bool):
        return v
    s = str(v).strip().lower()
    if s in ("1", "true", "t", "y", "yes", "on"):
        return True
    if s in ("0", "false", "f", "n", "no", "off", ""):
        return False
    return default


def eval_ema_uptrend_reject(
    closes: List[float],
    i: int,
    close_price: float,
    *,
    use_filter: bool,
    fast_period: int,
    slow_period: int,
    ema_fast_val: Optional[float] = None,
    ema_slow_val: Optional[float] = None,
) -> Tuple[Optional[str], Optional[str]]:
    """TRIGGER EMA 추세 필터. 통과 (None, None), 탈락 (reason, msg)."""
    if not _to_bool(use_filter, False):
        return (None, None)

    fast_p = max(1, int(fast_period))
    slow_p = max(1, int(slow_period))
    if slow_p <= fast_p:
        slow_p = fast_p + 1

    need = max(fast_p, slow_p)
    if i < 0 or i >= len(closes) or len(closes) < need:
        return ("탈락-EMA데이터", "봉 부족 (need=%d i=%d)" % (need, i))

    ema_fast = ema_fast_val if ema_fast_val is not None else compute_ema_series(closes, fast_p)[i]
    ema_slow = ema_slow_val if ema_slow_val is not None else compute_ema_series(closes, slow_p)[i]
    if ema_fast is None or ema_slow is None:
        return ("탈락-EMA데이터", "EMA 미계산 (fast=%d slow=%d)" % (fast_p, slow_p))

    if close_price <= ema_fast:
        return (
            "탈락-EMA약세",
            "close=%.0f ≤ EMA(%d)=%.0f" % (close_price, fast_p, ema_fast),
        )
    if ema_fast <= ema_slow:
        return (
            "탈락-EMA미정렬",
            "EMA(%d)=%.0f ≤ EMA(%d)=%.0f" % (fast_p, ema_fast, slow_p, ema_slow),
        )
    return (None, None)
