import os
import requests
import pandas as pd
from datetime import datetime, timedelta
from dotenv import load_dotenv

from indicator_lib import (
    ema,
    atr_percent,
    rvol,
    detect_trend_close_vs_ema,
    detect_trend_ema_cross,
    detect_intraday_momentum,
)

load_dotenv()
POLYGON_KEY = os.getenv("POLYGON_API_KEY")

BASE_URL = "https://api.polygon.io/v2/aggs/ticker"


def fetch_polygon_ohlc(symbol: str, multiplier: int, timespan: str, days_back: int) -> pd.DataFrame | None:
    """
    Holt OHLCV-Daten von Polygon über die Aggregates-API.
    timespan: 'day', 'hour', 'minute'
    days_back: wie viele Kalendertage rückwärts wir abdecken wollen.
    """
    if not POLYGON_KEY:
        raise RuntimeError("POLYGON_API_KEY nicht in .env gesetzt")

    end_date = datetime.utcnow().date()
    start_date = end_date - timedelta(days=days_back)

    url = (
        f"{BASE_URL}/{symbol}/range/{multiplier}/{timespan}/"
        f"{start_date.isoformat()}/{end_date.isoformat()}"
        f"?adjusted=true&sort=asc&limit=5000&apiKey={POLYGON_KEY}"
    )

    try:
        resp = requests.get(url, timeout=10)
        data = resp.json()
        if resp.status_code != 200 or data.get("resultsCount", 0) == 0:
            print(f"⚠️ Polygon keine Daten für {symbol} ({timespan}): {data.get('error', resp.status_code)}")
            return None

        rows = data.get("results", [])
        if not rows:
            print(f"⚠️ Polygon leere Ergebnismenge für {symbol} ({timespan})")
            return None

        df = pd.DataFrame(rows)
        df.rename(
            columns={"o": "open", "h": "high", "l": "low", "c": "close", "v": "volume", "t": "timestamp"},
            inplace=True,
        )
        df["timestamp"] = pd.to_datetime(df["timestamp"], unit="ms")
        return df

    except Exception as e:
        print(f"⚠️ Fehler beim Polygon-Call {symbol} ({timespan}): {e}")
        return None


def build_dummy_trend_features(symbol: str) -> dict:
    """
    Fallback, falls Polygon nicht erreichbar ist.
    """
    return {
        "symbol": symbol,
        "trend_D1": "NEUTRAL",
        "trend_H1": "NEUTRAL",
        "trend_M15": "FLAT",
        "ema200_D1": None,
        "atr_percent": None,
        "rvol": None,
    }


def build_trend_features_from_polygon(symbol: str) -> dict:
    """
    Baut echte Trend-Features aus Polygon-Daten:
    - D1: EMA200, ATR%, RVOL, Bias LONG/SHORT/NEUTRAL
    - H1: Trend über EMA20 vs. EMA50 (UP/DOWN/NEUTRAL)
    - M15: Intraday-Momentum (UP/DOWN/FLAT)
    """
    try:
        # --- D1: Tagesdaten für Bias, ATR%, RVOL ---
        df_d1 = fetch_polygon_ohlc(symbol, multiplier=1, timespan="day", days_back=260)
        if df_d1 is None or df_d1.empty:
            raise ValueError("Keine D1-Daten")

        df_d1["ema200"] = ema(df_d1["close"], 200)
        df_d1["atr_pct"] = atr_percent(df_d1, period=14)

        trend_d1 = detect_trend_close_vs_ema(df_d1["close"], df_d1["ema200"])
        atr_p = float(round(df_d1["atr_pct"].iloc[-1], 2))
        rv = float(round(rvol(df_d1, lookback=20), 2)) if len(df_d1) >= 20 else float("nan")

        ema200_last = float(round(df_d1["ema200"].iloc[-1], 2))

        # --- H1: Stunden-Trend über EMA20 vs. EMA50 ---
        df_h1 = fetch_polygon_ohlc(symbol, multiplier=1, timespan="hour", days_back=5)
        if df_h1 is not None and not df_h1.empty:
            df_h1["ema20"] = ema(df_h1["close"], 20)
            df_h1["ema50"] = ema(df_h1["close"], 50)
            trend_h1 = detect_trend_ema_cross(df_h1["ema20"], df_h1["ema50"])
        else:
            trend_h1 = "NEUTRAL"

        # --- M15: Intraday-Momentum ---
        df_m15 = fetch_polygon_ohlc(symbol, multiplier=15, timespan="minute", days_back=2)
        if df_m15 is not None and not df_m15.empty:
            trend_m15 = detect_intraday_momentum(df_m15["close"], lookback=5)
        else:
            trend_m15 = "FLAT"

        return {
            "symbol": symbol,
            "trend_D1": trend_d1,
            "trend_H1": trend_h1,
            "trend_M15": trend_m15,
            "ema200_D1": ema200_last,
            "atr_percent": atr_p,
            "rvol": rv,
        }

    except Exception as e:
        # WICHTIG: Fallback, damit der Fullscan nicht abstürzt
        print(f"❌ Trend-Fallback für {symbol}: {e}")
        return build_dummy_trend_features(symbol)
