import pytest
from unittest.mock import patch, MagicMock
from mars_bot.telegram import send_message, TelegramError


def _ok_response(result=None):
    resp = MagicMock()
    resp.status_code = 200
    resp.json.return_value = {"ok": True, "result": result or {"message_id": 1}}
    return resp


def test_send_message_success(mocker):
    mock_post = mocker.patch("mars_bot.telegram.requests.post", return_value=_ok_response())
    result = send_message("test-token", -100123, "hello")
    assert result["message_id"] == 1
    args, kwargs = mock_post.call_args
    assert args[0] == "https://api.telegram.org/bottest-token/sendMessage"
    assert kwargs["json"]["chat_id"] == -100123
    assert kwargs["json"]["text"] == "hello"
    assert kwargs["json"]["parse_mode"] == "HTML"
    assert kwargs["json"]["disable_web_page_preview"] is True


def _err_response(status: int, description: str):
    resp = MagicMock()
    resp.status_code = status
    resp.json.return_value = {"ok": False, "description": description}
    return resp


def test_send_message_403_forbidden(mocker):
    mocker.patch("mars_bot.telegram.requests.post", return_value=_err_response(403, "Forbidden: bot was kicked"))
    with pytest.raises(TelegramError, match="403.*Forbidden"):
        send_message("t", 1, "x")


def test_send_message_400_bad_html(mocker):
    mocker.patch("mars_bot.telegram.requests.post", return_value=_err_response(400, "Bad Request: can't parse entities"))
    with pytest.raises(TelegramError, match="400.*can't parse"):
        send_message("t", 1, "x")


def test_send_message_http_failure(mocker):
    import requests as _requests
    mocker.patch("mars_bot.telegram.requests.post", side_effect=_requests.ConnectionError("network down"))
    with pytest.raises(TelegramError, match="HTTP request failed"):
        send_message("t", 1, "x")


def test_send_message_http_failure_masks_token(mocker):
    """Токен в URL из RequestException не должен утечь в текст TelegramError."""
    import requests as _requests
    mocker.patch(
        "mars_bot.telegram.requests.post",
        side_effect=_requests.ConnectionError(
            "url https://api.telegram.org/bot99999:AAsecretTOKENvalue-_/sendMessage"
        ),
    )
    with pytest.raises(TelegramError) as ei:
        send_message("99999:AAsecretTOKENvalue-_", 1, "x")
    assert "AAsecretTOKENvalue" not in str(ei.value)
    assert "/bot***/sendMessage" in str(ei.value)
