import numpy as np
import pandas as pd


def ema(series: pd.Series, period: int) -> pd.Series:
    """Exponential Moving Average."""
    return series.ewm(span=period, adjust=False).mean()


def atr(df: pd.DataFrame, period: int = 14) -> pd.Series:
    """
    Average True Range (klassisch, nicht Wilder-Glättung).
    Erwartet Spalten: 'high', 'low', 'close'.
    """
    high_low = df["high"] - df["low"]
    high_close = (df["high"] - df["close"].shift()).abs()
    low_close = (df["low"] - df["close"].shift()).abs()
    tr = pd.concat([high_low, high_close, low_close], axis=1).max(axis=1)
    return tr.rolling(window=period).mean()


def atr_percent(df: pd.DataFrame, period: int = 14) -> pd.Series:
    """
    ATR in Prozent des Schlusskurses.
    """
    atr_vals = atr(df, period)
    return (atr_vals / df["close"]) * 100.0


def rvol(df: pd.DataFrame, lookback: int = 20) -> float:
    """
    Relative Volume: aktuelles Volumen vs. Durchschnitt der letzten N Tage.
    Erwartet Spalte 'volume'.
    """
    if "volume" not in df.columns or len(df) < lookback:
        return float("nan")
    avg_vol = df["volume"].rolling(window=lookback).mean()
    if np.isnan(avg_vol.iloc[-1]) or avg_vol.iloc[-1] == 0:
        return float("nan")
    return float(df["volume"].iloc[-1] / avg_vol.iloc[-1])


def detect_trend_close_vs_ema(close: pd.Series, ema_series: pd.Series) -> str:
    """
    D1-Bias: Kurs vs. EMA (z.B. EMA200).
    """
    if close.iloc[-1] > ema_series.iloc[-1]:
        return "LONG"
    elif close.iloc[-1] < ema_series.iloc[-1]:
        return "SHORT"
    else:
        return "NEUTRAL"


def detect_trend_ema_cross(short_ema: pd.Series, long_ema: pd.Series) -> str:
    """
    Einfache Trendlogik über EMA-Kreuz (z.B. EMA20 vs. EMA50 auf H1).
    """
    if len(short_ema) == 0 or len(long_ema) == 0:
        return "NEUTRAL"
    if short_ema.iloc[-1] > long_ema.iloc[-1]:
        return "UP"
    elif short_ema.iloc[-1] < long_ema.iloc[-1]:
        return "DOWN"
    else:
        return "NEUTRAL"


def detect_intraday_momentum(close: pd.Series, lookback: int = 5) -> str:
    """
    Sehr einfache Intraday-Struktur: vergleicht letzten Close mit dem vor X Kerzen.
    """
    if len(close) <= lookback:
        return "FLAT"
    last = close.iloc[-1]
    ref = close.iloc[-lookback]
    if last > ref * 1.002:      # +0.2% und mehr → UP
        return "UP"
    elif last < ref * 0.998:   # -0.2% und mehr → DOWN
        return "DOWN"
    return "FLAT"
