#!/usr/bin/env python3
from __future__ import annotations

import json
from pathlib import Path
from typing import Any, Dict, List, Tuple
from datetime import datetime, timezone

# WICHTIG: liegt im selben Ordner (/home/suprafl1/kleiner/backend/)
from trend_features import build_trend_features_from_polygon


# ---------------------------------------------------------
# Hilfsfunktionen für Dateien
# ---------------------------------------------------------

def load_json(path: Path, default):
    if not path.exists():
        return default
    try:
        with path.open("r", encoding="utf-8") as f:
            return json.load(f)
    except Exception:
        return default


def save_json(path: Path, data: Any):
    path.parent.mkdir(parents=True, exist_ok=True)
    with path.open("w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)


# ---------------------------------------------------------
# Phase 4: Writer fürs Dashboard (signals_live.json / signals_history.json)
# ---------------------------------------------------------

def write_signals_live(
    signals: List[Dict[str, Any]],
    market_mode: str | None = None,
    out_path: Path | str | None = None,
):
    """
    Schreibt data/live_scan/signals_live.json
    Format:
    {
      "last_update_utc": "...",
      "market_mode": "...",
      "signals": [...]
    }
    """
    if out_path is None:
        raise ValueError("out_path is required")

    out_path = Path(out_path)
    out_path.parent.mkdir(parents=True, exist_ok=True)

    payload = {
        "last_update_utc": datetime.now(timezone.utc).isoformat(),
        "market_mode": market_mode,
        "signals": signals,
    }
    save_json(out_path, payload)


def write_signals_history(
    items: List[Dict[str, Any]],
    out_path: Path | str | None = None,
):
    """
    Schreibt data/live_scan/signals_history.json
    Minimalformat:
    {
      "day": "YYYY-MM-DD" | null,
      "items": [...]
    }
    """
    if out_path is None:
        raise ValueError("out_path is required")

    out_path = Path(out_path)
    out_path.parent.mkdir(parents=True, exist_ok=True)

    payload = {
        "day": datetime.now(timezone.utc).date().isoformat(),
        "items": items,
    }
    save_json(out_path, payload)


# ---------------------------------------------------------
# Historische Daten: AvgVol20 & Gap%
# ---------------------------------------------------------

def compute_avgvol20_and_gap(history: List[Dict[str, Any]]) -> Tuple[float, float]:
    """
    Erwartetes Format history:
    [
        {"t": "2024-10-07", "o": ..., "h": ..., "l": ..., "c": ..., "v": ...},
        ...
    ]
    """
    if not history:
        return 0.0, 0.0

    # Nach Datum sortieren, nur zur Sicherheit
    try:
        history_sorted = sorted(history, key=lambda x: x.get("t", ""))
    except Exception:
        history_sorted = history

    # Volumen der letzten 20 Tage
    last_20 = history_sorted[-20:]
    vols = [float(d.get("v", 0.0)) for d in last_20 if d.get("v") is not None]
    avg_vol20 = float(sum(vols) / len(vols)) if vols else 0.0

    # Gap % zwischen letztem und vorletztem Tag
    if len(history_sorted) >= 2:
        prev = history_sorted[-2]
        last = history_sorted[-1]
        try:
            prev_close = float(prev.get("c", 0.0))
            today_open = float(last.get("o", 0.0))
            gap_pct = ((today_open - prev_close) / prev_close * 100.0) if prev_close > 0 else 0.0
        except Exception:
            gap_pct = 0.0
    else:
        gap_pct = 0.0

    return avg_vol20, gap_pct


# ---------------------------------------------------------
# Snapshot je Ticker
# ---------------------------------------------------------

def build_snapshot_for_symbol(symbol: str, data_dir: Path) -> Dict[str, Any]:
    """
    Baut den Live-Scan-Snapshot für genau EIN Symbol.
    Nutzt:
    - build_trend_features_from_polygon(symbol)
    - data/history/{SYMBOL}.json
    """

    history_dir = data_dir / "history"
    history_path = history_dir / f"{symbol}.json"
    history = load_json(history_path, [])

    avg_vol20, gap_pct = compute_avgvol20_and_gap(history)

    # Trend-Features aus Polygon
    features = build_trend_features_from_polygon(symbol=symbol)

    # Preis
    try:
        price = float(features.get("last_price") or 0.0)
    except Exception:
        price = 0.0

    # ATR% (je nach Version)
    try:
        atr_pct = float(features.get("atr_percent") or features.get("atrp") or 0.0)
    except Exception:
        atr_pct = 0.0

    # RVOL
    try:
        rvol = float(features.get("rvol") or 0.0)
    except Exception:
        rvol = 0.0

    # EMA200 (D1)
    try:
        ema200 = float(features.get("ema200_D1") or 0.0)
    except Exception:
        ema200 = 0.0

    # Trend-Felder
    trend_d1 = (
        features.get("d1_trend")
        or features.get("trend_D1")
        or features.get("bias_d1")
        or ""
    )
    trend_h1 = features.get("h1_trend") or features.get("trend_H1") or ""
    trend_m15 = (
        features.get("m15_trend")
        or features.get("trend_M15")
        or features.get("intraday_trend_m15")
        or ""
    )
    trend_simple = (features.get("trend") or "").lower()

    # Lage vs. EMA200
    if ema200 > 0 and price > ema200 * 1.002:
        vs_ema200 = "oberhalb"
    elif ema200 > 0 and price < ema200 * 0.998:
        vs_ema200 = "unterhalb"
    elif ema200 > 0:
        vs_ema200 = "nahe"
    else:
        vs_ema200 = "unbekannt"

    # Datenqualität (Heuristik)
    data_quality = "ok"
    if price <= 0 or avg_vol20 <= 0 or atr_pct <= 0 or rvol <= 0:
        data_quality = "warnung"

    snapshot = {
        "ticker": symbol,
        "price": round(price, 4),
        "avg_vol20": round(avg_vol20, 2),
        "rvol": round(rvol, 2),
        "atr_pct": round(atr_pct, 2),
        "trend_d1": trend_d1,
        "trend_h1": trend_h1,
        "trend_m15": trend_m15,
        "trend_simple": trend_simple,
        "vs_ema200": vs_ema200,
        "gap_pct": round(gap_pct, 2),
        "data_quality": data_quality,
    }

    return snapshot


# ---------------------------------------------------------
# Hauptlauf
# ---------------------------------------------------------

def run_build_daytrader_snapshots() -> Dict[str, Any]:
    """
    Lädt die 20 Daytrader-Ticker aus data/tickers.json,
    baut für jeden einen Snapshot und schreibt:
    - data/live_scan/daytrader_20.json

    UND (Phase 4):
    - data/live_scan/signals_live.json
    - data/live_scan/signals_history.json
    """

    # /home/suprafl1/kleiner/backend/build_daytrader_20.py
    # parents[1] => /home/suprafl1/kleiner
    base_dir = Path(__file__).resolve().parents[1]
    data_dir = base_dir / "data"
    live_scan_dir = data_dir / "live_scan"

    tickers_path = data_dir / "tickers.json"
    tickers_data = load_json(tickers_path, [])

    # Liste der Symbols extrahieren
    symbols: List[str] = []
    for item in tickers_data:
        if isinstance(item, dict):
            sym = item.get("symbol")
            if isinstance(sym, str) and sym.strip():
                symbols.append(sym.strip().upper())

    symbols = sorted(set(symbols))

    snapshots: List[Dict[str, Any]] = []
    for symbol in symbols:
        snap = build_snapshot_for_symbol(symbol, data_dir=data_dir)
        snapshots.append(snap)

    # 1) daytrader_20.json (Snapshots)
    out_snapshots = live_scan_dir / "daytrader_20.json"
    save_json(out_snapshots, snapshots)

    # 2) Phase 4: leere Live-Signale (werden später vom echten Live-Scan gefüllt)
    out_live = live_scan_dir / "signals_live.json"
    write_signals_live(signals=[], market_mode=None, out_path=out_live)

    # 3) Phase 4: leere History
    out_hist = live_scan_dir / "signals_history.json"
    write_signals_history(items=[], out_path=out_hist)

    return {
        "symbols": symbols,
        "snapshots_output": str(out_snapshots),
        "count": len(snapshots),
        "signals_live_written": str(out_live),
        "signals_history_written": str(out_hist),
    }


if __name__ == "__main__":
    status = run_build_daytrader_snapshots()
    print("build_daytrader_20 OK:")
    print(json.dumps(status, indent=2, ensure_ascii=False))
