from __future__ import annotations

import json
from pathlib import Path

from src.tools.hyperliquid_daily_report import summarize_tradingview_signals, build_tradingview_report_lines
from src.tools.tradingview_paper_bridge import process_pending_tradingview_signals


def _append(path: Path, row: dict) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    with path.open("a", encoding="utf-8") as fh:
        fh.write(json.dumps(row) + "\n")


def test_summarize_tradingview_signals_counts_paper_only_runtime(tmp_path):
    journal = tmp_path / "signals" / "signal_journal.jsonl"
    _append(journal, {
        "source": "tradingview",
        "strategy_id": "gaussian_channel_v1",
        "coin": "BTC",
        "action": "entry",
        "side": "long",
        "execution_mode": "paper_signal",
        "live_order_allowed": False,
    })
    _append(journal, {
        "source": "tradingview",
        "strategy_id": "squeeze_breakout_1h",
        "coin": "ETH",
        "action": "exit",
        "side": "short",
        "execution_mode": "paper_signal",
        "live_order_allowed": False,
    })

    summary = summarize_tradingview_signals(tmp_path)

    assert summary["received"] == 2
    assert summary["rejected"] == 0
    assert summary["paper_signal"] == 2
    assert summary["live_order_allowed_count"] == 0
    assert summary["by_strategy"] == {"gaussian_channel_v1": 1, "squeeze_breakout_1h": 1}
    assert summary["by_coin"] == {"BTC": 1, "ETH": 1}


def test_tradingview_report_lines_state_no_live_when_no_signals(tmp_path):
    lines = build_tradingview_report_lines(tmp_path)

    assert "TradingView Signals: empfangen=0" in "\n".join(lines)
    assert "Live-Freigabe aus TradingView: nein" in "\n".join(lines)


def test_tradingview_report_lines_warn_if_any_live_flag_appears(tmp_path):
    journal = tmp_path / "signals" / "signal_journal.jsonl"
    _append(journal, {
        "source": "tradingview",
        "strategy_id": "bad_live_flag",
        "coin": "BTC",
        "action": "entry",
        "side": "long",
        "execution_mode": "paper_signal",
        "live_order_allowed": True,
    })

    lines = build_tradingview_report_lines(tmp_path)

    joined = "\n".join(lines)
    assert "empfangen=1" in joined
    assert "Live-Freigabe aus TradingView: BLOCKIERT" in joined


def test_summarize_tradingview_rejected_reasons(tmp_path):
    reject_journal = tmp_path / "signals" / "rejected_signal_journal.jsonl"
    _append(reject_journal, {"source": "tradingview", "reason": "strategy_not_allowed", "live_order_allowed": False})
    _append(reject_journal, {"source": "tradingview", "reason": "duplicate_signal", "live_order_allowed": False})
    _append(reject_journal, {"source": "tradingview", "reason": "duplicate_signal", "live_order_allowed": False})

    summary = summarize_tradingview_signals(tmp_path)
    lines = build_tradingview_report_lines(tmp_path)

    assert summary["rejected"] == 3
    assert summary["reject_reasons"] == {"duplicate_signal": 2, "strategy_not_allowed": 1}
    assert "abgelehnt=3" in "\n".join(lines)
    assert "Rejects: {'duplicate_signal': 2, 'strategy_not_allowed': 1}" in "\n".join(lines)


def test_tradingview_report_lines_include_paper_bridge_summary(tmp_path):
    journal = tmp_path / "signals" / "signal_journal.jsonl"
    _append(journal, {
        "source": "tradingview",
        "signal_id": "tv-report-1",
        "strategy_id": "gaussian_channel_v1",
        "coin": "BTC",
        "side": "long",
        "action": "entry",
        "timeframe": "1h",
        "price": "60000",
        "timestamp": "2026-06-28T18:00:00Z",
        "execution_mode": "paper_signal",
        "live_order_allowed": False,
        "mainnet_signed_action": False,
    })
    process_pending_tradingview_signals(runtime_dir=tmp_path)

    joined = "\n".join(build_tradingview_report_lines(tmp_path))

    assert "TradingView Paper Bridge: entries=1" in joined
    assert "Bridge Strategien: {'gaussian_channel_v1': 1}" in joined
    assert "Promotion Gates:" in joined
    assert "Operational Gates:" in joined
    assert "live=nein" in joined
