from pathlib import Path

from alerting import AlertPlan


def test_telegram_config_defaults_disabled(monkeypatch, tmp_path):
    from telegram_alerts import TelegramAlertConfig

    monkeypatch.setenv("CTB_TELEGRAM_ENV_FILE", str(tmp_path / "missing.env"))
    monkeypatch.delenv("CTB_TELEGRAM_ALERTS", raising=False)
    cfg = TelegramAlertConfig.from_env()

    assert cfg.enabled is False
    assert cfg.chat_id is None
    assert cfg.thread_id is None


def test_telegram_config_reads_topic_env(monkeypatch):
    from telegram_alerts import TelegramAlertConfig

    monkeypatch.setenv("CTB_TELEGRAM_ALERTS", "true")
    monkeypatch.setenv("CTB_TELEGRAM_BOT_TOKEN", "token")
    monkeypatch.setenv("CTB_TELEGRAM_CHAT_ID", "-100123")
    monkeypatch.setenv("CTB_TELEGRAM_THREAD_ID", "6579")

    cfg = TelegramAlertConfig.from_env()

    assert cfg.enabled is True
    assert cfg.bot_token == "token"
    assert cfg.chat_id == "-100123"
    assert cfg.thread_id == 6579


def test_telegram_config_can_load_secret_env_file(monkeypatch, tmp_path):
    from telegram_alerts import TelegramAlertConfig

    env_file = tmp_path / "crypto_agent_telegram.env"
    env_file.write_text("CTB_TELEGRAM_ALERTS=true\nCTB_TELEGRAM_BOT_TOKEN=file-token\nCTB_TELEGRAM_CHAT_ID=-100456\nCTB_TELEGRAM_THREAD_ID=6579\n", encoding="utf-8")
    monkeypatch.setenv("CTB_TELEGRAM_ENV_FILE", str(env_file))
    monkeypatch.delenv("CTB_TELEGRAM_BOT_TOKEN", raising=False)
    monkeypatch.delenv("CTB_TELEGRAM_CHAT_ID", raising=False)
    monkeypatch.delenv("CTB_TELEGRAM_THREAD_ID", raising=False)
    monkeypatch.delenv("CTB_TELEGRAM_ALERTS", raising=False)

    cfg = TelegramAlertConfig.from_env()

    assert cfg.enabled is True
    assert cfg.bot_token == "file-token"
    assert cfg.chat_id == "-100456"
    assert cfg.thread_id == 6579


def test_telegram_disabled_returns_skipped_without_sender():
    from telegram_alerts import TelegramAlertConfig, send_telegram_alert

    result = send_telegram_alert(AlertPlan(text="hello"), TelegramAlertConfig(enabled=False))

    assert result.sent is False
    assert result.reason == "disabled"


def test_telegram_send_requires_crypto_topic_thread():
    from telegram_alerts import TelegramAlertConfig, send_telegram_alert

    cfg = TelegramAlertConfig(enabled=True, bot_token="token", chat_id="-100123", thread_id=None)

    result = send_telegram_alert(AlertPlan(text="hello"), cfg, sender=lambda *_args, **_kwargs: {"ok": True})

    assert result.sent is False
    assert result.reason == "missing_thread_id"


def test_telegram_sender_payload_uses_thread_and_no_secrets():
    from telegram_alerts import TelegramAlertConfig, send_telegram_alert

    calls = []

    def fake_sender(url, payload, timeout):
        calls.append((url, payload, timeout))
        return {"ok": True, "result": {"message_id": 123}}

    cfg = TelegramAlertConfig(enabled=True, bot_token="secret-token", chat_id="-100123", thread_id=6579)
    result = send_telegram_alert(AlertPlan(text="Crypto Bot ENTRY BTC"), cfg, sender=fake_sender)

    assert result.sent is True
    assert result.reason == "ok"
    assert calls[0][1]["chat_id"] == "-100123"
    assert calls[0][1]["message_thread_id"] == 6579
    assert "secret-token" not in str(calls[0][1])
    assert "secret-token" in calls[0][0]


def test_paper_exchange_records_orders_and_positions(tmp_path):
    from paper_trading import PaperExchange

    path = tmp_path / "paper_state.json"
    exchange = PaperExchange(path)

    exchange.set_leverage(5, "BTC/USDC:USDC")
    result = exchange.create_order("BTC/USDC:USDC", "market", "buy", 0.5, 100.0)
    exchange.create_order("BTC/USDC:USDC", "market", "sell", 0.5, 110.0, params={"reduceOnly": True})

    assert result["status"] == "ok"
    assert exchange.positions["BTC"]["contracts"] == 0
    assert len(exchange.orders) == 2
    assert path.exists()


def test_paper_exchange_fetch_positions_matches_ccxt_shape(tmp_path):
    from paper_trading import PaperExchange

    exchange = PaperExchange(tmp_path / "paper_state.json")
    exchange.create_order("ETH/USDC:USDC", "market", "buy", 2.0, 50.0)

    positions = exchange.fetch_positions()

    assert positions == [{
        "symbol": "ETH/USDC:USDC",
        "contracts": 2.0,
        "entryPrice": 50.0,
        "leverage": 1,
        "side": "long",
    }]
