from __future__ import annotations

import json

from fastapi.testclient import TestClient

import eightmem.ui.app as ui_app
from eightmem.ui.app import create_app


def test_telegram_webhook_requires_config(fake_home, monkeypatch):
    monkeypatch.delenv("TELEGRAM_BOT_TOKEN", raising=False)
    client = TestClient(create_app())

    response = client.post("/channels/telegram/webhook", json={})

    assert response.status_code == 503
    assert response.json()["ok"] is False


def test_telegram_webhook_rejects_bad_secret(fake_home, monkeypatch):
    monkeypatch.setenv("TELEGRAM_BOT_TOKEN", "123:abc")
    monkeypatch.setenv("TELEGRAM_WEBHOOK_SECRET", "good-secret")
    client = TestClient(create_app())

    response = client.post(
        "/channels/telegram/webhook",
        json={},
        headers={"X-Telegram-Bot-Api-Secret-Token": "bad-secret"},
    )

    assert response.status_code == 403
    assert response.json()["ok"] is False


def test_telegram_webhook_ignores_non_message_updates(fake_home, monkeypatch):
    monkeypatch.setenv("TELEGRAM_BOT_TOKEN", "123:abc")
    client = TestClient(create_app())

    response = client.post("/channels/telegram/webhook", json={"update_id": 1, "edited_message": {}})

    assert response.status_code == 200
    assert response.json() == {"ok": True, "ignored": True}


def test_telegram_webhook_processes_and_sends(fake_home, monkeypatch):
    monkeypatch.setenv("TELEGRAM_BOT_TOKEN", "123:abc")
    monkeypatch.setattr(
        ui_app,
        "send_telegram_message",
        lambda config, outgoing: {"ok": True, "result": {"chat_id": outgoing.chat_id, "text": outgoing.text}},
    )
    monkeypatch.setattr(
        ui_app,
        "process_telegram_update",
        lambda payload: type(
            "_Msg",
            (),
            {
                "chat_id": "777",
                "text": "Saved. I'll use that.",
                "user_id": "123",
                "update_id": 2,
                "action": "save_preference",
                "memory_updated": True,
            },
        )(),
    )
    client = TestClient(create_app())

    response = client.post(
        "/channels/telegram/webhook",
        json={
            "update_id": 2,
            "message": {
                "message_id": 20,
                "text": "Remember: keep answers concise",
                "chat": {"id": 777},
                "from": {"id": 123},
            },
        },
    )

    assert response.status_code == 200
    body = response.json()
    assert body["ok"] is True
    assert body["chat_id"] == "777"
    assert body["telegram"]["ok"] is True


def test_telegram_webhook_logs_structured_success(fake_home, monkeypatch, caplog):
    monkeypatch.setenv("TELEGRAM_BOT_TOKEN", "123:abc")
    monkeypatch.setattr(
        ui_app,
        "send_telegram_message",
        lambda config, outgoing: {"ok": True},
    )
    monkeypatch.setattr(
        ui_app,
        "process_telegram_update",
        lambda payload: type(
            "_Msg",
            (),
            {
                "chat_id": "777",
                "text": "Saved. I'll use that.",
                "user_id": "123",
                "update_id": 2,
                "action": "save_preference",
                "memory_updated": True,
            },
        )(),
    )
    client = TestClient(create_app())

    with caplog.at_level("INFO", logger="eightmem.telegram"):
        response = client.post(
            "/channels/telegram/webhook",
            json={
                "update_id": 2,
                "message": {
                    "message_id": 20,
                    "text": "Remember: keep answers concise",
                    "chat": {"id": 777},
                    "from": {"id": 123},
                },
            },
        )

    assert response.status_code == 200
    payload = json.loads(caplog.records[-1].message)
    assert payload["event"] == "telegram_message_processed"
    assert payload["action"] == "save_preference"
    assert payload["user_id"] == "123"


def test_telegram_webhook_handles_backend_unavailable_without_500(fake_home, monkeypatch):
    monkeypatch.setenv("TELEGRAM_BOT_TOKEN", "123:abc")
    monkeypatch.setattr(
        ui_app,
        "send_telegram_message",
        lambda config, outgoing: {"ok": True, "result": {"chat_id": outgoing.chat_id, "text": outgoing.text}},
    )
    monkeypatch.setattr(
        ui_app,
        "process_telegram_update",
        lambda payload: type(
            "_Msg",
            (),
            {
                "chat_id": "777",
                "text": "I couldn't generate that draft right now because the model backend is unavailable. Please try again in a moment.",
                "user_id": "123",
                "update_id": 3,
                "action": "draft_backend_unavailable",
                "memory_updated": False,
            },
        )(),
    )
    client = TestClient(create_app())

    response = client.post(
        "/channels/telegram/webhook",
        json={
            "update_id": 3,
            "message": {
                "message_id": 30,
                "text": "Draft: write a founder update in my style",
                "chat": {"id": 777},
                "from": {"id": 123},
            },
        },
    )

    assert response.status_code == 200
    body = response.json()
    assert body["ok"] is True
    assert "model backend is unavailable" in body["telegram"]["result"]["text"].lower()
